使窗口具有滚动条的步骤
如何使窗口具有滚动条?
本程序的CGraphicView 类是从View类继承的 class CGraphicView : public Cview 首先将基类改成CScrollView class CGraphicView : public CScrollView 然后将源文件cpp文件中的CView全部替换成CScrollView 在文件中替换字或词的步骤, 从菜单中选择 Edit->Replace, 在弹出的对话框中再选择 Match whole word only(仅全词匹配) -------------------------------------------------------------------------------- 要使窗口可以滚动,还需要设置一些滚动的参数: 用SetScrollSizes方法来设置映射模式、滚动视图总的尺寸等等 而这个函数最好在虚函数的重载函数OnInitiaUpdate里面调用。 这个虚函数在一个视图与一个文档关联之后调用,也就是在窗口完全创建之后第一个调用的函数。 不过它的调用是在OnDraw函数调用之前。所以这个函数可以做一些窗口创建之后的初始化工作。void CGraphyicView::OnInitialUpdate()
{ CScrollView::OnInitialUpdate(); SetScrollSizes(MM_TEXT,CSize(800,600)); }--------------------------------------------------------------------------------
程序运行之后,将窗口的大小调到小到800*600时,就可以看到滚动条了。
但是我们发现一个问题,先将垂直滚动条下拉一些,然后在窗口右下角画一条直线,将其最小化,还原之后直线的位置上移了,这是什么原因呢?调试之后,可以断定OnLButtonDown与重绘函数OnDraw中所画图形的三个要素相同,所以不是它们的问题。
在前面研究窗口重绘为什么调用OnDraw函数的时候,
void CView::OnPaint() { // standard paint routine CPaintDC dc(this); OnPrepareDC(&dc); OnDraw(&dc); } 发现在调用OnDraw之前调用了OnPrepareDC ,问题就出在这里。 在MFC资源文件中去查看OnPrepareDC 发现这样一条代码:pDC->SetViewportOrg(ptVpOrg); 调试一下,发现ptVpOrg=(x=0, y= -150); 可见OnPrepareDC调整了显示上下文的属性将视口的原点设置为(0,-150),根据公式yViewPort=yWindow-yWinOrg+yViewOrg;得到设备点y坐标出现在原先显示地方的上方。 -------------------------------------------------------------------------------- 关于解决办法的说明: 首先,绘制图形之后保存坐标点之前调用OnPrepareDC调整显示上下文的属性,将视口原点设置为(0,-150)然后调用设备坐标转换逻辑坐标函数DPtoLP将设备坐标(680,390)转换为逻辑坐标, 根据公式 yWindow=yViewport-yViewOrg+yWinOrg;得到y坐标为540。 窗口重绘时会先调用OnPrepareDC,调整显示上下文的属性,将视口的原点设置为(0,-150) 然后GDI函数用逻辑坐标点(680,540)绘制图形,被转换为(680,390)所以解决的办法就是在OnLButtonDown函数中,绘制完图形之后,保存图形元素之前 加入下面代码:
OnPrepareDC(&dc); dc.DPtoLP(&m_ptOrigin); //视口(设备)坐标和窗口(逻辑) dc.DPtoLP(&point);当滚动条在最上端,窗口发生重绘时OnPrepareDC调整显示上下文,
会将视口的原点设置为(0,0),而不是(0,-150) OnPrepareDC会随时根据滚动窗口的位置来调整视口的原点我的问题是:
OnPrepareDC(&dc); 这句代码在这里是必要的吗? 将它去掉之后,图形重绘也不会再出现错位现象, 它在这里似乎没什么作用啊? 大家说说你的意见吧! 欢迎您登录 http://blog.csdn.net/teshorse 留言 或者写信给我 teshorse@hotmail.com