Learning

导航

CScrollView坐标转换

转载自:http://blog.beaplat.com/257310/item/2459.html

CView的几个派生类

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

posted on 2011-07-23 10:48  xinjie  阅读(1430)  评论(0编辑  收藏  举报