设备环境类:CDC类、CPaintDC类、CClientDC类、CWindowDC类总结

http://blog.csdn.net/ltag0110rtag/article/details/7360295

  • DC    :   设备环境(Device Context)

                     1.  设备环境, 是 Window 内部的一种数据结构,用来保存与某个设备相关的绘制属性信息。

                     2.  所有的绘制调用都必须通过设备环境 dc 进行。这些对象封装了用于绘制线条、图形以及文本的 Window API 。

                     3. 设备环境允许 Window 在设备中进行与设备无关的绘制。

                     4. 设备环境可用于绘制到屏幕、打印机可图元文件。

  • HDC :   设备环境句柄

                     一个指针类型对像,指向 dc 对象 在 Window 内部的位置。

  • CDC、CClientDC、CPaintDC、CWindowDC的派生关系

          

------------------------------------------------------------------------------------------------------------------

1、CDC 类

        Window 使用与设备无关的设备环境dc来进行显示。MFC 基础类库定义了设备环境对象类 --  CDC

[cpp]  view plain copy
  1. 其构造函数如下:  
  2. CDC::CDC()  
  3. {  
  4.     m_hDC        = NULL;  
  5.     m_hAttribDC  = NULL;  
  6.     m_bPrinting  = FALSE;  
  7. }  
  8.   
  9. 其析构函数如下:  
  10. CDC::~CDC()  
  11. {  
  12.     if (m_hDC != NULL)  
  13.         ::DeleteDC(Detach());  
  14. }  

需要注意的是:在生成CDC对象的时候,并不像它的派生类那样,在构造函数里获取相应的Windows设备上下文句柄。

所以,最好不要使用::GetDC等函数来获取一个设备描述表,而是使用BOOL CreateCompatibleDC(CDC*pDC )创建一个设备描述表。

在 CDC析构函数中,如果设备描述表句柄不空,则调用DeleteDC删除它。这是直接使用CDC时最好创建Windows设备描述表的理由。

如果设备描述表不是创建的,则应该在析构函数被调用前分离出设备描述表句柄并用::RealeaseDC释放它,释放后m_hDC为空,则在析构函数调用时不会执行::DeleteDC

当然,不用担心CDC的派生类的析构函数调用CDC的析构函数,因为CDC::~CDC()不是虚拟析构函数。

使用CDC有两种做法:

[cpp]  view plain copy
  1. //  1.用 CWnd::GetDC()来初始化CDC对象  
  2. CDC     *pDC = GetDC();  
  3. pDC->MoveTo(m_ptOrigin);   
  4. pDC->LineTo(point);   
  5. ReleaseDC(pDC);  
  6.   
  7. //  2.CreateCompatibleDC(CDC* pDC ) 来创建 CDC 对象  
  8. //  用于为当前 dc 在内存创建一个兼容DC。这样要可消除闪烁  
  9. CDC     dcMem;   
  10. dcMem.CreateCompatibleDC(&dc);          //创建设备描述表  
  11. pbmOld = dcMem.SelectObject(&m_bmBall); //更改设备描述表属性  
  12.   
  13. //作一些绘制操作  
  14.   
  15. dcMem.SelectObject(pbmOld);             //恢复设备描述表的属性  
  16. dcMem.DeleteDC();                       //可以不调用,而让析构函数去删除设备描述表  

2、CClientDC 类

       CClientDC 类,在构造函数中调用 Window API 函数 GetDC(),在析构函数中调用ReleaseDC()。

       CClientDC 类只能在客户区绘图。面所谓的客户区是指窗口区域去掉边框、标题栏、菜单栏、工具栏、状态栏等之外的部分。

       它是用户可操作的区域。

       CClientDC类的窗口句柄保存在成员变量m_hWnd,为构造CClientDC,需将CWnd作为参数传递给构造函数。 

    在使用CClientDC进行绘图时,一般要调用GetClientRect()函数来获取客户区域的大小;

[cpp]  view plain copy
  1. //CClientDC : public CDC  特点:构造函数时候GetDC()  析构函数时候调用ReleaseDC   
  2. // CClientDC dc(GetParent());   GetParent view的父窗口 也就是frame 但不能出客户区域   
  3. CClientDC dc(this);       //指针构造DC   
  4. dc.MoveTo(m_ptOrigin);   
  5. dc.LineTo(point);  

3、CPaintDC类

        CPaintDC 用于响应窗口重绘消息(WM_PAINT)是的绘图输出。

        CPaintDC在构造函数中调用BeginPaint()取得设备上下文,在析构函数中调用 EndPaint()释放设备上下文。

        EndPaint()除了释放设备上下文外,还负责从消息队列中清除WM_PAINT消息。

        因此,在处理窗口重画时,必须使用CPaintDC,否则WM_PAINT消息无法从消息队列中清除,将引起不断的窗口重画

        CPaintDC也只能用在WM_PAINT消息处理之中。

[cpp]  view plain copy
  1. // MFC中 CView 对 WM_PAINT 消息的实现方法如下:  
  2. void CView::OnPaint()  
  3. {  
  4.     // standard paint routine  
  5.     CPaintDC dc(this);  
  6.     OnPrepareDC(&dc);  
  7.     OnDraw(&dc);  
  8. }  
  9.   
  10. // 在栈中定义了CPaintDC类型的变量dc,随着构造函数的调用获取了设备描述表;  
  11. // 设备描述表使用完毕,超出其有效范围就被自动地清除,随着析构函数的调用,其获取的设备描述表被释放。  
  12.   
  13. // 如果希望在堆中创建,例如  
  14.   
  15. CPaintDC *pDC;  
  16. pDC = new CPaintDC(this)  
  17.   
  18. // 则在使用完毕时,用delete删除pDC:  
  19. delete pDC;  

4、CWindowDC 类

       CWindowDC对象在构造时调用Windows API函数GetWindowDC,在析构时调用相应的API函数ReleaseDC。

       这意味着CWindowDC对象可访问CWnd所指向的为整个全屏幕区域; 

       CWindowDC允许在显示器的任意位置绘图。坐标原点在整个窗口的左上角。 

       在使用CWindowDC进行绘图时,一般要调用GetWindowRect函数来获取整个应用程序窗口区域的大小; 

       CWindowDC类的窗口句柄保存在成员变量m_hWnd,为构造CClientDC,需将CWnd作为参数传递给构造函数。 

[cpp]  view plain copy
  1. // CWindowDC 也是派生于CDC 构造、析构也是类似ClientDC 。可以访问整个程序区域 包括客户区与非客户区   
  2. // CWindowDC dc(GetParent());           绘制父窗体 文档结构中 可以绘制到框架类 乃至非客户区上   
  3. // CWindowDC dc(GetDesktopWindow());    可以绘制到整个非客户区 桌面上   
  4. CWindowDC dc(this);  //绘制当前窗口   
  5. dc.MoveTo(m_ptOrigin);   
  6. dc.LineTo(point);  

 

=================================================

 

附: Windows 程序设计 对 图形基础的描述:
 

1. 取得设备上下文句柄

       Windows 提供了几种取得设备上下文句柄的方法。如果在处理一个消息时取得了设备上下文句柄,应该在退出窗口函数之前释放它(或者删除它)。

       一旦释放了句柄,它就不再有效了。对于打印机设备上下文句柄,规则就没有这么严格。

       最常用的用于取得并释放设备上下文句柄的方法是:在处理WM_PAINT 消息时,使用 BeginPaint 和 EndPaint 调用:

       hdc = BeginPaint(hwnd, &ps);   

       // 其他操作

       EndPaint(hwnd, &ps); 

      其中,ps 为PAINTSTRUCT 结构对象,该结构中的 hdc 字段是 BeginPaint 传回的设备上下文句柄,PAINTSTRUCT 结构又包含一个名为rcPaint 的RECT(矩形)结构,

     rcPaint 定义一个包围窗口显示区域无效的矩形。使用从BeginPaint获得的设备上下文句柄,只能在这个区域内绘图。BeginPaint 调用使该区域有效。

 

     Windows 程序还可以在处理非WM_PAINT消息时取得设备上下文句柄

     hdc = GetDC(hwnd);

     // 其他操作

     ReleaseDC(hwnd, hdc);

 

     这个设备上下文适用于窗口句柄为hwnd 的显示区域。

     这些调用与BeginPaint 和 EndPaint 的组合之间的区别是,利用从GetDC传回的句柄可以在整个显示区域上绘图。

     当然,GetDC 和 ReleaseDC 不使显示区域中任何可能的无效区域变成有效。

 

     Windows 程序还可以取得适用于整个窗口的设备上下文句柄:

     hdc = GetWindowDC(hwnd);

     // 其他操作

     ReleaseDC(hwnd, hdc);

   

     这个设备上下文除了显示区域之外,还包括窗口的标题栏、菜单、滚动条、和框架。

     GetWindowDC 函数很少使用,如果想尝试用一用它,则必须拦截处理WM_NCPAINT 消息,

     Windows 使用该消息在窗口的非显示区域上绘图。

     BeginPaint、GetDC和GetWindowDC获得的设备上下文句柄都和显示器上的某个特定窗口相关。

     取得设备上下文句柄的另一个更通用的函数是CreateDC:

     hdc = CreateDC(pszDreiver, pszDevice, pszOutput, pData);

     // 其他操作

     DeleteDC(hdc);

     .......


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值