MFC中画线,坐标转换等问题小结

来源:互联网 发布:php session加密 编辑:程序博客网 时间:2024/06/13 23:40

1、MFC中屏幕坐标,窗口坐标问题

       设备坐标(Device Coordinate)又称为物理坐标(Physical Coordinate),是指输出设备上的坐标。通常将屏幕上的设备坐标称为屏幕坐标。设备坐标用对象距离窗口左上角的水平距离和垂直距离来指定对象的位置,是以像素为单位来表示的,设备坐标的X轴向右为正,Y轴向下为正,坐标原点位于窗口的左上角。
     逻辑坐标(Logical Coordinate)是系统用作记录的坐标。在缺省的模式(MM_TEXT)下,逻辑坐标的方向和单位与设备坐标的方向和单位相同,也是以像素为单位来表示的,X轴向右为正,Y轴向下为正,坐标原点位于窗口的左上角。逻辑坐标和设备坐标即使在缺省模式下其数值也未必一致,除了在以下两种情况下:
        1. 窗口为非滚动窗口;
  2. 窗口为滚动窗口,但垂直滚动条位于滚动边框的最上端,水平滚动条位于最左端,但如果移动了滚动条这两种坐标就不一致了。
 所以在绘图时经常出现,客户窗口变动时,画线效果没有达到预期的。所以特别注意以下两点:

  1、在VC中鼠标坐标的坐标位置用设备坐标表示,但所有GDI绘图都用逻辑坐标
   2、坐标表示,所以用鼠标绘图时,那么必须将设备坐标转换为逻辑坐标,
可以使用CDC 函数DptoLP()将设备坐标转化为逻辑坐标,同样可以              用LptoDP()将逻辑坐标转化为设备坐标。 
       ScreenToClient和ClientToScreen实际上是转换一个参照物的概念,如ie客户区上一个button,相对于ie的坐标是(x, y),ie客户区相对于屏幕原点的坐标是(x0 , y0),那么button的screen坐标就是(x+x0, y+y0)。
        ScreenToClient和ClientToScreen都假定坐标是设备坐标。在比较位置关系的时候注意转换成屏幕坐标比较。

2、MFC中画线的问题

首先应在View类中增加CPOINT类的一成员变量point,并在构造函数中将其初始化为0。

<1>画线

1、利用全局函数(SDK函数)实现画线

      HDC hdc; //定义DC

     hdc=::GetDC(m_hWnd);

    ::MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);

     //m_ptOriginLBUTTONDOWN时获取的点位置

    ::LineTo(hdc,point.x,point.y);//画线到当前点

    ::ReleaseDC(m_hWnd,hdc);//释放DC

2、利用CDC类实现画线

      CDC *pDC=GetDC();//此时利用的是CWnd的成员函数GetDC

       pDC->MoveTo(m_ptOrigin);

       pDC->LineTo(point);

       ReleaseDC(pDC);

3、利用CClientDC类实现画线

//构造时调用GetDC,析构时调用ReleaseDC,因此无需显式的调用GetDCReleaseDC

       CClientDC dc(this); //构造的DC仅与View类相关,画线仅能画在View窗口上

       //CClientDC dc(GetParent());

      //构造的DCView类的父窗口(框架窗口)相关,画线能画在工具栏上,不能画到菜单栏上

       dc.MoveTo(m_ptOrigin);

       dc.LineTo(point);

4、利用CWindowDC类实现画线——也不需要显式地调用GetDCReleaseDC

    //利用该类可在可在整个屏幕(包括客户区与非客户区)上画线

       //CWindowDC dc(this);    //CClientDC没有区别

       //CWindowDC dc(GetParent());      //可画到菜单栏

       CWindowDC dc(GetDesktopWindow());      //可画到桌面上

       dc.MoveTo(m_ptOrigin);

       dc.LineTo(point);

<2>画出其他颜色线条(利用画笔—CPen类)

     CPen pen(PS_DOT,1,RGB(0,255,0));

     / /创建画笔,参数分别为笔的类型,笔的粗细,笔的颜色

       CClientDC dc(this);

       CPen *pOldPen=dc.SelectObject(&pen);

//将新画笔的类型选择到设备描述表中,并返回原来画笔的类型

       dc.MoveTo(m_ptOrigin);

       dc.LineTo(point);

       dc.SelectObject(pOldPen);//将原先画笔的类型选择到设备描述表中 

<3>创建画刷CBrush类

1、创建颜色画刷

      CBrush brush(RGB(255,0,0));

       CClientDC dc(this);

       dc.FillRect(CRect(m_ptOrigin,point),&brush); 

2、创建位图画刷

     CBitmap bitmap;//定义位图

       bitmap.LoadBitmap(IDB_BITMAP2);//加载位图

       CBrush brush(&bitmap);//创建位图的画刷

       CClientDC dc(this);

       dc.FillRect(CRect(m_ptOrigin,point),&brush);//利用画刷填充

3、创建透明画刷

      CClientDC dc(this);

      CBrush *pBrush=CBrush

     ::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));

    //创建透明画刷(使先前画的仍能看到)

    //FromHandle函数将句柄转换为C++对象,GetStockObject函数获得画刷的句柄

       CBrush *pOldBrush=dc.SelectObject(pBrush);

       dc.Rectangle(CRect(m_ptOrigin,point));//画矩形

       dc.SelectObject(pOldBrush);

希望以上总结对大家有用!

参考文章:http://blog.csdn.net/infoncust/article/details/437632

                   http://blog.csdn.net/yi1538466096/article/details/8188452



原创粉丝点击