MFC 鼠标移动画矩形
转自:问题日记:MFC 鼠标移动画矩形
昨天的时候,模仿人家的软件已经七七八八啦,开始不断完善的工作。首先是完善用鼠标拖动矩形选择东西,开始当然进入死胡同,在OnMouseMove里单纯画矩形,结果测试移动一下鼠标杯了,n个矩形刺瞎了我的眼:
我相信人家做得到的,我也做得到,只是我还不知道而已。于是上网找资料,虽说网上有很多资料,可也有点费时,有时看了资料测试还不一定行,汗,不行你放上网干嘛啦。最后结果OK啦:
现写下来:
(1 )在类里定义变量和消息:
bool m_bClickEmpty; //判断是否点击了空白的地方,以实现拖动框选择
CPoint OldEmptyBegin;//点击空白开始的座标
CPoint NowEmptyEnd;//移动时保存座标
afx_msg void OnMouseMove(UINT nFlags, CPoint point);afx_msg void OnLButtonDown(UINT nFlags, CPoint point);afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
( 2 )在鼠标相关的消息里面写代码:
void XX::OnLButtonDown(UINT nFlags, CPoint point){
m_bClickEmpty = true;
OldEmptyBegin = point;
NowEmptyEnd = point;
}
void XX::OnMouseMove(UINT nFlags, CPoint point)
{
if ( m_bClickEmpty ) { CClientDC dc(this);
CBrush *pBrush = CBrush::FromHandle( (HBRUSH)GetStockObject( NULL_BRUSH) );
CBrush *POldBrush = dc.SelectObject( pBrush );
int nOldMode = dc.SetROP2(R2_NOTXORPEN);
dc.Rectangle( &CRect( OldEmptyBegin, NowEmptyEnd ) );
dc.Rectangle( &CRect( OldEmptyBegin, point ) );
NowEmptyEnd = point;
dc.SelectObject( POldBrush );
dc.SetROP2( nOldMode );
}
}
void XX::OnLButtonUp(UINT nFlags, CPoint point){
if ( m_bClickEmpty ) { m_bClickEmpty = false;
CClientDC dc(this);
CBrush *pBrush = CBrush::FromHandle( (HBRUSH)GetStockObject( NULL_BRUSH) );
CBrush *POldBrush = dc.SelectObject( pBrush );
int nOldMode = dc.SetROP2(R2_NOTXORPEN);
dc.Rectangle( &CRect( OldEmptyBegin, NowEmptyEnd ) );
dc.SelectObject( POldBrush );
dc.SetROP2( nOldMode );
}}
有时候最好还是让鼠标限制在一个的主框里面这样会比较好办(座标,鼠标不用走到外面,在外面也没用),用ClipCursor.
-----------------------------+_+------------------2013-05-28
上面都是老方法了,叫橡皮筋技术,但是在不停拖动过程中还是会出现一些难看的重绘,应该用双缓冲,保存鼠标点击下去时候的点StartPoint,和鼠标移动时候的点EndPoint,直接刷新界面。这样更好.
- CPoint m_StartPoint;//开始点
- CPoint m_EndPoint;//结束点
- BOOL m_bLBDown;//鼠标是否按下
CPoint m_StartPoint;//开始点
CPoint m_EndPoint;//结束点
BOOL m_bLBDown;//鼠标是否按下
- afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
- afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
- afx_msg void OnMouseMove(UINT nFlags, CPoint point);
- afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
- m_bLBDown = FALSE;//在构造函数初始化为FALSE
m_bLBDown = FALSE;//在构造函数初始化为FALSE
- void CMy22Dlg::OnPaint()
- {
- CPaintDC dc(this);
- //绘制背景
- CRect rect;
- GetClientRect(&rect);
- CBrush bruDB(RGB(255, 255, 255));//背景颜色
- dc.FillRect(&rect, &bruDB);
- //绘制拖动矩形
- if (m_bLBDown)
- {
- CRect rect(m_StartPoint, m_EndPoint);
- rect.NormalizeRect();//规范化矩形
- CBrush bruPen(RGB(255, 0, 0));//矩形边框颜色
- dc.FrameRect(&rect, &bruPen);
- }
- }
- void CMy22Dlg::OnLButtonDown(UINT nFlags, CPoint point)
- {
- m_StartPoint = point;
- m_EndPoint = point;
- m_bLBDown = TRUE;
- SetCapture();//设置鼠标捕获
- CDialogEx::OnLButtonDown(nFlags, point);
- }
- void CMy22Dlg::OnLButtonUp(UINT nFlags, CPoint point)
- {
- if(this == GetCapture())
- {
- ReleaseCapture();
- }
- m_bLBDown = FALSE;
- Invalidate(FALSE);//更新界面
- CDialogEx::OnLButtonUp(nFlags, point);
- }
- void CMy22Dlg::OnMouseMove(UINT nFlags, CPoint point)
- {
- if (m_bLBDown)
- {
- m_EndPoint = point;
- Invalidate(FALSE);//更新界面
- }
- CDialogEx::OnMouseMove(nFlags, point);
- }
- BOOL CMy22Dlg::OnEraseBkgnd(CDC* pDC)
- {
- //return CDialogEx::OnEraseBkgnd(pDC);不需要重绘背景
- return TRUE;
- }
void CMy22Dlg::OnPaint()
{
CPaintDC dc(this);
//绘制背景
CRect rect;
GetClientRect(&rect);
CBrush bruDB(RGB(255, 255, 255));//背景颜色
dc.FillRect(&rect, &bruDB);
//绘制拖动矩形
if (m_bLBDown)
{
CRect rect(m_StartPoint, m_EndPoint);
rect.NormalizeRect();//规范化矩形
CBrush bruPen(RGB(255, 0, 0));//矩形边框颜色
dc.FrameRect(&rect, &bruPen);
}
}
void CMy22Dlg::OnLButtonDown(UINT nFlags, CPoint point)
{
m_StartPoint = point;
m_EndPoint = point;
m_bLBDown = TRUE;
SetCapture();//设置鼠标捕获
CDialogEx::OnLButtonDown(nFlags, point);
}
void CMy22Dlg::OnLButtonUp(UINT nFlags, CPoint point)
{
if(this == GetCapture())
{
ReleaseCapture();
}
m_bLBDown = FALSE;
Invalidate(FALSE);//更新界面
CDialogEx::OnLButtonUp(nFlags, point);
}
void CMy22Dlg::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_bLBDown)
{
m_EndPoint = point;
Invalidate(FALSE);//更新界面
}
CDialogEx::OnMouseMove(nFlags, point);
}
BOOL CMy22Dlg::OnEraseBkgnd(CDC* pDC)
{
//return CDialogEx::OnEraseBkgnd(pDC);不需要重绘背景
return TRUE;
}