Programming Technology

VC下使用橡皮筋类(Use CRectTracker)

使用CRectTracker,可以简单的实现操作系统下的选择框
声明与设置

  1. //成员变量
  2. CRectTracker m_RectTracker;
  3.  
  4. //设置RectTracker样式
  5. m_RectTracker.m_nStyle = CRectTracker::resizeOutside|CRectTracker::solidLine;
  6. m_RectTracker.m_nHandleSize = 6;
  7. m_RectTracker.m_rect.SetRect(0,0,0,0);

实现点击代码如下:

  1. CPoint m_ptStart;       //成员变量
  2.  
  3. //有关正规化矩形的解释:
  4. //因为有可能出现矩形的起始点的X坐标大于终止点的X坐标
  5. //这样在以后的操作中会引起不必要的麻烦,所以需要转换过来
  6. //MFC已经定义好了这个函数m_rect.NormalizeRect()
  7.  
  8. void CMyDlg::OnLButtonDown(UINT nFlags, CPoint point)
  9. {
  10.         // TODO: Add your message handler code here and/or call default 
  11.         if(m_RectTracker.HitTest(point)<0)      //如果未击中矩形选择框,重新画选择框
  12.         {
  13.                 m_ptStart = point;      //保存起始点
  14.  
  15.                 m_RectTracker.TrackRubberBand(this,point,TRUE);
  16.                 m_RectTracker.m_rect.NormalizeRect();   //正规化矩形
  17.  
  18.                 //这时系统就屏蔽了WM_LBUTTONUP事件,所以需要自己发送消息(已删除,原因见下)
  19.                 /*SendMessage(WM_LBUTTONUP,NULL,NULL);*/
  20.         }
  21.         else    //如果击中矩形选择框
  22.         {
  23.                 m_RectTracker.Track(this,point,TRUE);
  24.                 m_RectTracker.m_rect.NormalizeRect();   //正规化矩形
  25.         }
  26.  
  27.         Invalidate();   //刷新窗口区域
  28.  
  29.         CDialog::OnLButtonDown(nFlags, point);
  30. }
  31.  
  32. //Update: 2007/10/18
  33. //经验证,删除此函数,CRectTracker仍可正常工作,此函数在没有特殊操作的情况下显得多余了
  34. /*
  35. void CMyDlg::OnLButtonUp(UINT nFlags, CPoint point)
  36. {
  37.         // TODO: Add your message handler code here and/or call default
  38.  
  39.         //左键弹起,设置矩形
  40.         CPoint ptEnd;
  41.         GetCursorPos(&ptEnd);
  42.         ScreenToClient(&ptEnd);
  43.  
  44.         m_RectTracker.m_rect.SetRect(m_ptStart,ptEnd);
  45.         m_RectTracker.m_rect.NormalizeRect();   //正规化矩形
  46.  
  47.         Invalidate(); //刷新窗口区域
  48.        
  49.         CDialog::OnLButtonUp(nFlags, point);
  50. }
  51. */

改变光标: (Update: 2008/01/30)
ps: 由于MFC的BUG问题,使用静态库时,会发生光标丢失的情况
具体解决方法: 1. Microsoft官方 2. VC静态库下CRectTracker鼠标光标(指针)不显示问题
谢谢haoder的提醒,更新了本文 :)

  1. //注意:在使用静态MFC链接库时,会不起作用,请看相关解释
  2. BOOL CMyDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  3. {
  4.         // TODO: Add your message handler code here and/or call default
  5.  
  6.         if (pWnd == this && m_RectTracker.SetCursor(this, nHitTest))
  7.         {
  8.                 return TRUE;
  9.         }
  10.        
  11.         return CDialog::OnSetCursor(pWnd, nHitTest, message);
  12. }

画矩形(自己实现):

  1. void CMyDlg::OnPaint()
  2. {
  3.         if (IsIconic())
  4.         {
  5.                 CPaintDC dc(this); // device context for painting
  6.  
  7.                 SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  8.  
  9.                 // Center icon in client rectangle
  10.                 int cxIcon = GetSystemMetrics(SM_CXICON);
  11.                 int cyIcon = GetSystemMetrics(SM_CYICON);
  12.                 CRect rect;
  13.                 GetClientRect(&rect);
  14.                 int x = (rect.Width() - cxIcon + 1) / 2;
  15.                 int y = (rect.Height() - cyIcon + 1) / 2;
  16.  
  17.                 // Draw the icon
  18.                 dc.DrawIcon(x, y, m_hIcon);
  19.         }
  20.         else
  21.         {
  22.                 CPaintDC dc(this);
  23.                 dc.Draw3dRect(m_RectTracker.m_rect,0x000000,0x000000)//画矩形边界
  24.                
  25.                 CDialog::OnPaint();
  26.         }
  27. }

其他可重载函数:
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

Comment by wupei (2008/11/24 10:06)

解决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

Comment by haoder (2008/01/31 07:12)

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);

Comment by wupei (2007/10/19 15:39)

乱码?没见过,sweete的留言

你好:
看了你写的关于CRectTracker类的一个帖子,想请教你一个问题:当视图出现滚动条了 ,我想当拖动矩形边框时,一旦光标移出了客户区的时候,这时滚动条能跟随光标移动而移动。实现滚动条能跟随光标移动而移动的函数我是可以实现,但现在问题是我将这个函数写在OnMouseMove函数里,但执行完OnLButtonDown里的Track函数完,不会进入OnMouseMove函数。
放在Track函数前,也不行。不知道你知道这个问题该如何解决么?谢谢了。

Comment by wupei (2007/10/19 15:36)

发表评论 ( 如果您刚刚提交过评论,但是还没有被显示出来,请点击这里刷新一下: 刷新评论 )

标题

内容*

昵称*

电子邮件

个人网页


 authimage