CScrollView坐标转换
转载自:http://blog.beaplat.com/257310/item/2459.html
2007-11-19 晴 |
出处或者来源:MFC Windows CView派生类的说明 CEdit View 实现像便签多行正文编辑器的视图 CFormView 使用对话框控件模板资源来定义用户应用程序接口的滚动视图 CListView 支持重点在列表控件的文档/视图结构的视图 CRecordView 显示对话框控件中的数据库记录的视图 CRichEditView 支持重点在金莲能编辑控件的文档/视图结构的视图 CScrollView 提供支持自动化滚动的视图 CTreeView 支持重点在树控件的文档/视力结构的视图 这些增强的视力类,都可以作为应用程序视图类的基类.方法是在MFC AppWizard的第6个对话框中来选择. 例如用CScrollView作为应用程序视图类的基类,那么在Class View窗口中就会看到,应用程序视图类中含有一个成员函数 OnInitialUpdate.它是一个虚函数.它在生成视图对象且与文档结合时,被程序框架调用一次,因此这是初始化滚动条参数的地方. 其原型为: void SetScrollSizes( int nMapMode, //映射模式,一般为MM_TEXT SIZE sizeTotal, //文档尺寸 const SIZE& sizePage=sizeDefault, //每滚动一页的尺寸 const SIZE& sizeLine=sizeDefault); //每滚动一行的尺寸 在6_3的基础上 void CMy6_4View::OnInitialUpdate() { CScrollView::OnInitialUpdate(); //CSize sizeTotal; // TODO: calculate the total size of this view //sizeTotal.cx = sizeTotal.cy = 100; CSize sizeTotal(3000,2000); CSize sizePage(50,50); CSize sizeLine(10,10); SetScrollSizes(MM_TEXT, sizeTotal,sizePage,sizeLine); } 如果按上面的方法编写处理滚动条的代码,还是会出现一些问题的.因为使用滚动条后,窗口已经向大发生移动,从而使文档的坐标原点与视图的原点实际已不再重合了.但是由于视图类不能对此变化进行自动修正, 解决方法:在绘图时就需要把视图的坐标转换为文档的坐标,而在显示文档数据时则需把文档的坐标再转换为视力的坐标,可以用DC类的成员函数DPtoLP 和LPtoDP void DPtoLP( LPPOINT lpPoints, int nCount = 1 ) const; void DPtoLP( LPRECT lpRect ) const; void DPtoLP( LPSIZE lpSize ) const; 和 void LPtoDP( LPPOINT lpPoints, int nCount = 1 ) const; void LPtoDP( LPRECT lpRect ) const; void LPtoDP( LPSIZE lpSize ) const; 其中函数DPtoLP能把设备坐标(视图坐标)转换为逻辑坐标(文档坐标) 而LPtoDP则相反 把6_4的OnLButtoDown()和OnUpdate()的代码做如下修改. void CMy6_4View::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CClientDC dc(this); //获得视图的DC OnPrepareDC(& dc); //这是一个和坐标映射相关的函数 dc.DPtoLP(& point); //在绘图之前把鼠标位置传票转换为逻辑坐标. CMy6_4Doc *pDoc=GetDocument(); int r=rand()%50+5; CRect Ret(point.x-r, point.y-r, point.x+r, point.y+r); pDoc->m_Rectag.Add(Ret); m_ViewDrRect->m_DrawRect=Ret; dc.LPtoDP(&Ret);//显示数据之前把逻辑坐标转换为设备坐标 InvalidateRect(Ret,FALSE); pDoc->UpdateAllViews(this, 0L, m_ViewDrRect); CScrollView::OnLButtonDown(nFlags, point); } void CMy6_4View::OnUpdate(CView * pSender, LPARAM lHint, CObject * pHint) { CDrawRect *pDrawRect=(CDrawRect *)pHint;////////////////////////kuan CClientDC dc(this); //获得视图的DC dc.LPtoDP(& pDrawRect->m_DrawRect); InvalidateRect(pDrawRect->m_DrawRect,FALSE); }. |