昨天的时候,模仿人家的软件已经七七八八啦,开始不断完善的工作。首先是完善用鼠标拖动矩形选择东西,开始当然进入死胡同,在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;//鼠标是否按下
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
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; }
问题日记:VC MFC 鼠标移动画矩形
最新推荐文章于 2025-05-06 11:06:44 发布
本文介绍了一种改进的鼠标拖动选区方法,通过使用双缓冲技术和规范化矩形来提高用户体验并减少重绘问题。文章详细展示了如何通过记录鼠标按下和移动的位置,并在释放鼠标时刷新界面来实现这一功能。


4万+

被折叠的 条评论
为什么被折叠?



