橡皮筋类的使用

来源:互联网 发布:水准仪高程测量数据 编辑:程序博客网 时间:2024/04/28 10:32

 一:

使用橡皮筋类CRectTracker,可以使的被选择的区域,通过鼠标来移动或缩放,并且不会发生闪烁现象。

如果想实现图片的移动和缩放的话, 使用响应down、up、move是一种方法,不过这种方法通常闪烁的很厉害,而更好的方法的就是用橡皮筋类来实现,直接将图画到橡皮筋内部去

 

 

第一步:定义类变量

CRectTracker  m_RectTracker;


 

第二步:在构造函数中初始化类变量

 

m_RectTracker.m_nStyle=CRectTracker::dottedLine|CRectTracker::resizeInside;  // 样式  m_RectTracker.m_nHandleSize=10;  //手柄大小m_RectTracker.m_rect.SetRectEmpty(); // 最初的矩形                            

 

 

第三步:在适当位置确定橡皮筋所属的控件对象及确定橡皮筋初始大小

 

 

m_RectTracker.Draw(m_image.GetDC()); //表示要画橡皮筋区域的手柄   同时表示橡皮筋是在控件m_image上面的,所以橡皮筋用的坐标是控件m_image的坐标系  Graphics graphics(m_image.GetDC()->m_hDC);  // 在m_image上面画图,所以使用的是m_image控件坐标系WCHAR * path;USES_CONVERSION;path=A2W((LPCTSTR)imagePath);if(m_pImageObj!=NULL)delete [] m_pImageObj;m_pImageObj=Bitmap::FromFile(path);     //加载图片CRect rectTracker;m_image.GetClientRect(&rectTracker);m_RectTracker.m_rect.SetRect(rectTracker.TopLeft(),rectTracker.BottomRight());  //设置橡皮筋大小为m_image控件的大小CRect rect;// 得到橡皮筋大区域大小m_RectTracker.GetTrueRect(&rect); //使用得到的橡皮筋区域信息rect作为参数,用此参数控制画图位置//这样橡皮筋大小改变时,图片才能相应改变,这一点非常重要graphics.DrawImage(m_pImageObj,rect.TopLeft().x,rect.TopLeft().y,rect.Width(),rect.Height());  Invalidate();


 

第四步:响应WM_SETCURSOR消息

 

BOOL CShowImageDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message){// TODO: 在此添加消息处理程序代码和/或调用默认值if(pWnd==this && m_RectTracker.SetCursor((CWnd*)GetDlgItem(IDC_IMAGE),nHitTest))  //SetCursor第一个参数为拥有它的窗口指针return TRUE;return CDialog::OnSetCursor(pWnd, nHitTest, message);}


 

第五步: 响应WM_LBUTTONDOWN消息

 

void CShowImageDlg::OnLButtonDown(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值CPoint  tp=point;this->ClientToScreen(&point);m_image.ScreenToClient(&point);  //坐标由对话框客户坐标 转变到m_image控件坐标上                                          //因为 下面用到的Tracker是在IDC_IMAGE上面执行的,所以要将坐标转换到IMAGE上面if(m_RectTracker.HitTest(point)<0)  //{CRectTracker tempRectTracker;tempRectTracker.TrackRubberBand((CWnd*)GetDlgItem(IDC_IMAGE),point);  //画虚线框tempRectTracker.m_rect.NormalizeRect();}else{m_RectTracker.Draw(m_image.GetDC()); //在m_image控件上面画m_RectTracker.Track((CWnd*)GetDlgItem(IDC_IMAGE),point);    //  跟踪这个点   它屏蔽了UP 和MOUSEMOVE消息  当左键UP时 跟踪完毕Invalidate(FALSE);// UP以后执行的代码}CDialog::OnLButtonDown(nFlags, tp);}

 

实际响应此消息时, 移动时,要不断的是前面的区域无效,否则会出现很多重合的画面

下面是一个实际的例子:

void CShowImageDlg::OnLButtonDown(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值CPoint  tp=point;this->ClientToScreen(&point);m_image.ScreenToClient(&point);      if(m_RectTracker.HitTest(point)<0)  // { CRectTracker tempRectTracker; CRect rect; tempRectTracker.TrackRubberBand((CWnd*)GetDlgItem(IDC_IMAGE),point); tempRectTracker.m_rect.NormalizeRect(); if(rect.IntersectRect(tempRectTracker.m_rect,m_RectTracker.m_rect)) m_bcapture=TRUE; else m_bcapture=FALSE; CRect oldRc(m_btDownPoint,m_btDownSize); m_image.ClientToScreen(&oldRc); this->ScreenToClient(&oldRc); InvalidateRect(oldRc,TRUE); }else { m_RectTracker.Draw(m_image.GetDC()); m_RectTracker.Track((CWnd*)GetDlgItem(IDC_IMAGE),point);    //  跟踪这个点   当左键UP时 跟踪完毕 m_bcapture=TRUE; //以下为左键UP时代码 CRect oldRc(m_btDownPoint,m_btDownSize); //记录的是 鼠标刚按下时的区域的大小   鼠标左键UP后,要先将前面层呆过的地方重绘下 m_image.ClientToScreen(&oldRc); this->ScreenToClient(&oldRc); InvalidateRect(oldRc,TRUE);                            // 鼠标左键UP后,不需要在手动的写代码使的新的区域重画了,因为橡皮筋类替我们完成了这个步骤                                 }CDialog::OnLButtonDown(nFlags, tp);}




二:静态库下CRectTracker无法显示鼠标光标解决方案


         1   解决非控件(对话框,单文档等)静态库中鼠标不见的问题(转自微软)


         1) 原因:当应用程序通过使用静态库链接到 MFC 时, MFC 资源被编译到应用程序的可执行文件。 应用程序的可执行文件将包括在 Afxres.rc 文件。 若要检查这,单击 资源包含 在 视图 菜单上。 在 Afxres.rc 文件拥有 CRectTracker 使用 MFC 源代码中的资源。 这些资源不是是 _AFX_NO_TRACKER_RESOURCES 时,包括只定义的。 BLOCKS32 项目具有 _AFX_NO_TRACKER_RESOURCES 定义的。 因此,它确实不置于应用程序的可执行映像 CRectTracker 需要的资源。 因此,没有任何所使用的 CRectTracker 游标会在生成该示例通过使用 MFC 静态时显示。


       2) 解决方案

           在资源视图中,在rc中点击 Resource Includes,然后 删除以下行: #define _AFX_NO_TRACKER_RESOURCES。


      2  解决控件中静态库鼠标不见的问题


         由于在控件的资源里没有_AFX_NO_TRACKER_RESOURCES,所以需要添加#undef _AFX_NO_TRACKER_RESOURCES\r\n。

         在资源视图中,在rc中点击 Resource Includes,在3 TEXTINCLUDE 下面添加如下语句,注意斜体部分,一定要有。


    3 TEXTINCLUDE    BEGIN    "1 TYPELIB ""test.tlb""\r\n"    "\r\n"    "#define _AFX_NO_SPLITTER_RESOURCES\r\n"    "#define _AFX_NO_OLE_RESOURCES\r\n"    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"    "#undef _AFX_NO_TRACKER_RESOURCES\r\n"    "\r\n"    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"    "LANGUAGE 9, 1\r\n"    "#pragma code_page(1252)\r\n"    "#include ""afxres.rc"" // Standard components\r\n"    "#endi\0"    END


 

 

参考资料:


http://www.zxbc.cn/html/20081023/67064.html

http://bbs.astiny.com/viewtopic.php?f=2&t=10


 

原创粉丝点击