如何使窗口具有滚动条?
本程序的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