MFC加入滚动条

来源:互联网 发布:人工智能平台有哪些 编辑:程序博客网 时间:2024/05/16 00:49

OnPaint和OnDraw
为什么发生重绘消息的时候,OnDraw会响应?
因为OnPaint调用了OnDraw.
如果自己添加了OnPaint函数,应先加条OnPrepareDC函数调整设备上下文,然后再调用OnDraw

加入滚动条

1. 可以在新建MFC程序时从CScrollView中派生类,也可以手动修改选择VC菜单项Edit-Replace

2.


第一步做好后,当你编译运行时,程序会出错!并且不会出现滚动条,我们还要在窗口创建完毕后,我们可以添加个虚函数OnInitialUpdate()。在OnInitialUpdate()调用SetScrollSizes函数设置滚动条范围,因为OnInitialUpdate()函数是窗口创建之后所会调用的第一个函数。SetScrollSizes第一个参数是要你指定映射模式,我选择的是MM_TEXT,然后第二个参数要你传递个CSize对象,,我们可以构造一个CSize对象用于指定滚动条纵向和横向的范围!第三个参数是你指定滚动条空白栏部位被点击所滚动的数量,第四个是点击向上向下箭头滚动的范围,三四个参数为默认实参,我们不必在指定值!

void CMFC_View::OnInitialUpdate()

{

CScrollView::OnInitialUpdate();


// TODO: Add your specialized code here and/or call the base class

       SetScrollSizes(MM_TEXT,CSize(1000,800));

}

编译运行一下,你会发现窗口已经具有了滚动条的功能!

 

滚动条的画图的问题

当你把窗口的滚动条拉到下端然后画图时!
然后只要发生了能够让窗口产生重绘消息的事件之后呢,你会发现你所画的线已经跑到了上面!

这是为什呢,为什么我们在画线条的时候没发生这种情况呢而是重绘时发生的呢?因为在窗口重绘的时候调用了OnPrepareDC(&dc);在OnPrepareDC(&dc)中调整了视口的原点!假设我们的坐标点位(893,315),此时在OnPrepareDC函数中已经将视口原点设置为了(0,-292)

我们在重绘显示图形的时候要将逻辑坐标转换为视口坐标!

根据公式:

视口X坐标=窗口X坐标-窗口X原点坐标+视口X原点

893=893-0+0

视口Y坐标=窗口Y坐标-窗口Y原点坐标+视口Y原点

23=315-0+(-292)

   所以见公式,图形当然会显示在上方!

  

   那么该如何解决呢?

   我们应该在保存坐标点的前的时候调用OnPrepareDC调整视口原点!然后将调用DPtoLP设备坐标转换为逻辑坐标保存!Windows对于所有的消息用的都是设备坐标!GDI函数用逻辑坐标!

   根据公式:

       窗口X坐标=视口X坐标-视口X原点+窗口X原点

              893=893-0+0

窗口Y坐标=视口Y坐标-视口Y原点+窗口Y原点

       607=315-(-292)+0

   然后在重绘将逻辑坐标映射为设备坐标时,窗口重绘再次调用OnPrepareDC再次调整市口的原点

   根据公式:

视口X坐标=窗口X坐标-窗口X原点坐标+视口X原点

893=893-0+0

视口Y坐标=窗口Y坐标-窗口Y原点坐标+视口Y原点

          315=607-0+(-292)

   这样就刚好坐标点没变!

   代码实现:

   void CMFC_View::OnLButtonUp(UINT nFlags, CPoint point)

{

       // TODO: Add your message handler code here and/or call default

       CClientDC  dc(this);

       dc.MoveTo(BegPt);

       dc.LineTo(point);

 

      OnPrepareDC(&dc);

       dc.DPtoLP(&BegPt);  //设备坐标转换成逻辑坐标

       dc.DPtoLP(&point); 

       Line=new CLine;

       Line->BegPt=BegPt;

       Line->EndPt=point;

      

       LineAry.Add(Line);

       CScrollView::OnLButtonUp(nFlags, point);

}

最后补充下OnPrepareDC会根据滚动条的位置从而改变视口原点!所以坐标为(893,315)的线理应在移动滚动条最顶端能看见的,但是经过OnPrepareDC调整视口原点之后,就变得看不见了,只能 在原来画线的地方看见!

 

原创粉丝点击