VC下使用橡皮筋类(Use CRectTracker)
使用CRectTracker,可以简单的实现操作系统下的选择框
声明与设置
- //成员变量
- CRectTracker m_RectTracker;
- //设置RectTracker样式
- m_RectTracker.m_nStyle = CRectTracker::resizeOutside|CRectTracker::solidLine;
- m_RectTracker.m_nHandleSize = 6;
- m_RectTracker.m_rect.SetRect(0,0,0,0);
实现点击代码如下:
- CPoint m_ptStart; //成员变量
- //有关正规化矩形的解释:
- //因为有可能出现矩形的起始点的X坐标大于终止点的X坐标
- //这样在以后的操作中会引起不必要的麻烦,所以需要转换过来
- //MFC已经定义好了这个函数m_rect.NormalizeRect()
- void CMyDlg::OnLButtonDown(UINT nFlags, CPoint point)
- {
- // TODO: Add your message handler code here and/or call default
- if(m_RectTracker.HitTest(point)<0) //如果未击中矩形选择框,重新画选择框
- {
- m_ptStart = point; //保存起始点
- m_RectTracker.TrackRubberBand(this,point,TRUE);
- m_RectTracker.m_rect.NormalizeRect(); //正规化矩形
- //这时系统就屏蔽了WM_LBUTTONUP事件,所以需要自己发送消息(已删除,原因见下)
- /*SendMessage(WM_LBUTTONUP,NULL,NULL);*/
- }
- else //如果击中矩形选择框
- {
- m_RectTracker.Track(this,point,TRUE);
- m_RectTracker.m_rect.NormalizeRect(); //正规化矩形
- }
- Invalidate(); //刷新窗口区域
- CDialog::OnLButtonDown(nFlags, point);
- }
- //Update: 2007/10/18
- //经验证,删除此函数,CRectTracker仍可正常工作,此函数在没有特殊操作的情况下显得多余了
- /*
- void CMyDlg::OnLButtonUp(UINT nFlags, CPoint point)
- {
- // TODO: Add your message handler code here and/or call default
- //左键弹起,设置矩形
- CPoint ptEnd;
- GetCursorPos(&ptEnd);
- ScreenToClient(&ptEnd);
- m_RectTracker.m_rect.SetRect(m_ptStart,ptEnd);
- m_RectTracker.m_rect.NormalizeRect(); //正规化矩形
- Invalidate(); //刷新窗口区域
- CDialog::OnLButtonUp(nFlags, point);
- }
- */
改变光标: (Update: 2008/01/30)
ps: 由于MFC的BUG问题,使用静态库时,会发生光标丢失的情况
具体解决方法: 1. Microsoft官方 2. VC静态库下CRectTracker鼠标光标(指针)不显示问题
谢谢haoder的提醒,更新了本文 :)
- //注意:在使用静态MFC链接库时,会不起作用,请看相关解释
- BOOL CMyDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
- {
- // TODO: Add your message handler code here and/or call default
- if (pWnd == this && m_RectTracker.SetCursor(this, nHitTest))
- {
- return TRUE;
- }
- return CDialog::OnSetCursor(pWnd, nHitTest, message);
- }
画矩形(自己实现):
- void CMyDlg::OnPaint()
- {
- if (IsIconic())
- {
- CPaintDC dc(this); // device context for painting
- SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
- // Center icon in client rectangle
- int cxIcon = GetSystemMetrics(SM_CXICON);
- int cyIcon = GetSystemMetrics(SM_CYICON);
- CRect rect;
- GetClientRect(&rect);
- int x = (rect.Width() - cxIcon + 1) / 2;
- int y = (rect.Height() - cyIcon + 1) / 2;
- // Draw the icon
- dc.DrawIcon(x, y, m_hIcon);
- }
- else
- {
- CPaintDC dc(this);
- dc.Draw3dRect(m_RectTracker.m_rect,0x000000,0x000000); //画矩形边界
- CDialog::OnPaint();
- }
- }
其他可重载函数:
AdjustRect 当矩形被改变大小时此函数被调用
DrawTrackerRect 当画一个CRectTracker对象的边框时此函数被调用
OnChangedRect 当矩形被改变大小或被移动时,此函数被调用
GetHandleMask 调用此函数来获得一个CRectTracker项的调整大小把手的掩码
Re: haoder
Thank you! It is official description on Microsoft.
You can also see the article on this website
http://wupei.j2megame.org/blog.php/myblog/vc/2007/10/27/vc-crecttracker-cur
解决VC++橡皮区矩形CRectTracker无法显示光标(cursor)的问题
1) In the ResourceView pane, of the Workspace, right-click the projrct name.
2) select Resource Incoudes.
3) See if this line is there:
#define _AFX_NO_TRACKER_RESOURCES
If it is, delete it.
This is a bug in MFC v 5 and 6, described here:
BUG: BLOCKS32 Sample Fails to Show Cursors when Linked to MFC
ID: Q208856
http://support.microsoft.com/support/kb/articles/Q208/8/56.ASP
Re: sweete
你好
对的,你说的情况是正确的
void CMyDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(m_RectTracker.HitTest(point)<0) //如果未击中矩形选择框,重新画选择框
{
m_ptStart = point; //保存起始点
m_RectTracker.TrackRubberBand(this,point,TRUE);
m_RectTracker.m_rect.NormalizeRect(); //正规化矩形
//这时系统就屏蔽了WM_LBUTTONUP事件,所以需要自己发送消息
SendMessage(WM_LBUTTONUP,NULL,NULL);
}
else //如果击中矩形选择框
{
m_RectTracker.Track(this,point,TRUE);
m_RectTracker.m_rect.NormalizeRect(); //正规化矩形
}
Invalidate(); //刷新窗口区域
CDialog::OnLButtonDown(nFlags, point);
}
看这段代码当出发左键单击的情况后,会屏蔽WM_LBUTTONUP消息,同理,应为也屏蔽OnMouseMove的消息
因为自己来发送相关的消息才行,比如,让他发出左键弹起消息
SendMessage(WM_LBUTTONUP,NULL,NULL);
乱码?没见过,sweete的留言
你好:
看了你写的关于CRectTracker类的一个帖子,想请教你一个问题:当视图出现滚动条了 ,我想当拖动矩形边框时,一旦光标移出了客户区的时候,这时滚动条能跟随光标移动而移动。实现滚动条能跟随光标移动而移动的函数我是可以实现,但现在问题是我将这个函数写在OnMouseMove函数里,但执行完OnLButtonDown里的Track函数完,不会进入OnMouseMove函数。
放在Track函数前,也不行。不知道你知道这个问题该如何解决么?谢谢了。





