CDC,RDC,cdc-pdc=getdc

  CDC,RDC,cdc*pdc=getdc

  首先,什么是DC(设备描述表)

  解决方案:Windows应用程序为指定的设备(屏幕、打印机等)创建设备上下文(DC)。)在以DC为代表的逻辑画布上绘制图形。DC是一种包含设备信息的数据结构,包含物理设备所需的各种状态信息。Win32程序在绘制图形之前需要获得DC的句柄HDC,当它不再被使用时释放它。

  C编程中经常会看到HDC、CDC、cclientdc、cpaintdc、cwindowdc等类。

  HDC是DC的句柄,API中类似指针的数据类型。

  是MFC的DC类。

  CDC等设备上下分类,都包含一个类成员变量:m _ nHdc也就是HDC类型的手柄。

  CDC及其派生类的继承视图:

  对象

  公共 -疾病预防控制中心

  public - - CClientDC

  public - - CPaintDC

  public - - CWindowDC

  public - - CMetaFileDC

  (注:除CMetaFileDC外的三个派生类用于绘制图形。)

  CDC类定义了一个与设备描述表相关的类,其对象提供了操作设备描述表的成员函数,如显示器、打印机、与显示器描述表相关的窗口客户区等。

  所有的绘图操作都可以通过CDC的成员函数来执行。提供了CDC成员函数来执行设备描述表的基本操作、使用绘图工具、选择类型安全图形设备结构(GDI)以及颜色和调色板。此外,它还提供了获取和设置绘图属性、地图、控制视口、窗口范围、变换坐标、区域操作、裁剪、画线和绘制简单图形(椭圆、多边形等)的成员函数。).成员函数还提供绘制文本、设置字体、改变打印机代码、滚动和处理图元文件。

  它的派生类:

  1.PaintDC:封装两个API的调用,BeginPaint和EndPaint。

  (1)绘图输出用来响应窗口重绘消息(WM_PAINT)。

  (2)CPaintDC在构造函数中调用BeginPaint()获取设备上下文,在析构函数中调用EndPaint()释放设备上下文。EndPaint()除了释放设备上下文之外,还负责从消息队列中清除WM_PAINT消息。所以在处理窗口重绘时,必须使用CPaintDC,否则无法从消息队列中清除WM_PAINT消息,会造成连续的窗口重绘。

  (3)CPaintDC只能在WM_PAINT消息处理中使用。

  2.CClientDC(客户区设备上下文):处理显示描述表的相关表单客户区。

  与特定窗口相关联的客户区中使用的输出允许开发人员访问目标窗口中的客户区。它的构造函数包含GetDC,它的析构函数包含ReleaseDC。

  3.CWindowDC:处理与显示描述表相关的整个表单区域,包括框架和控件(子表单)。

  (1)图形可以在非客户区绘制,而CClientDC和CPaintDC只能在客户区绘制图形。

  (2)坐标原点在屏幕的左上角,CClientDC和CPaintDC下的坐标原点在客户区的左上角。

  (3)关联一个特定的窗口,允许开发者在目标窗口的任何部分绘图,包括边界和标题。此DC与WM_NCPAINT消息一起发送。

  4.CMetaFileDC:与元文件相关的设备描述表相关联。

  CDC提供了两个函数,GetLayout和SetLayout,用于反转设备描述表的布局。方便阿拉伯语和希伯来语书写文化习惯的设计,以及非欧表中的字体布局。

  CDC包含两个设备描述表。m_hDC和m_hAttribDC对应同一个器件。CDC为m_hDC指定所有输出GDI调用,大部分GDI属性调用由m_hAttribDC控制。(比如GetTextColor是属性调用,SetTextColor是输出调用。)

  下面是一些简单的代码,看看你是否使用这些类

  用的是HDC,每次画线之类的操作不是MFC封装的,类就多了一个HDC参数。

  在哪个设备描述表操作中执行?

  HDC HDC=:GetDC(m _ hWnd);//m_hWnd==this- m_hWnd是当前窗口句柄。

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

  LineTo(hdc,point.x,point . y);

  * release DC(m _ hWnd,hdc);//必须与GetDC成对出现

  可见HDC使用起来比较麻烦,如果:GetDC和:ReleaseDC不配对的话会出错。

  CDC * pDC=GetDC();

  pDC-move to(m _ ptOrigin);

  pDC- LineTo(点);

  release DC(pDC);

  CClientDC dc(这个);

  华盛顿。move to(m _ ptOrigin);

  华盛顿。LineTo(点);

  CWindowDC dc(这个);

  CWindowDC dc2(GetDesktopWindow());//获取整个桌面的句柄,这是一些桌面特效程序使用的

  华盛顿。move to(m _ ptOrigin);

  华盛顿。LineTo(点);

  CPaintDC dc(这个);

  华盛顿。move to(m _ ptOrigin);

  华盛顿。LineTo(点);

  可以看出,MFC类使用起来要方便得多,因为它们都是在构造函数和析构函数中调用响应函数来获取和释放DC。

  下面说一些详细的知识点。

  CClientDC,CWindowDC区别不大。可以说CWindowDC包含了CClientDC。以记事本为例。

  CClientDC就是白的。我们可以编辑文本的区域是客户区。

  除了上面提到的白色区域,CWindowDC还包括菜单栏和工具栏。

  CClientDC和CWindowDC与CPaintDC不同。

  CClientDC和CWindowDC在收购DC时使用GetDC和ReleaseDC。

  CPaintDC使用并且只能使用BeginPaint和EndPaint。

  CPaintDC只能用于响应WM_PAINT事件。

  CClientDC、CWindowDC只能用于响应非WM_PAINT事件。

  在WM_PAINT事件上

  系统会在很多不同的时候发送WM_PAINT消息:第一次创建窗口的时候,窗口大小改变的时候,窗口从另一个窗口后面移出的时候,窗口最大化或者最小化的时候等等。这些动作都是由系统管理的,应用只是被动的接收消息,在消息处理函数中进行绘制操作;大多数时候,应用程序还需要能够在窗口中启动绘图操作。例如,当窗口中显示的数据发生变化时,这通常是通过invalidaterestment和InvalidateRgn函数来完成的。将指定区域添加到窗口的更新区域。当应用的消息队列中没有其他消息时,如果窗口的更新区域不为空,系统将自动生成WM_PAINT消息。

  为什么调用invalid时系统不发送WM_PAINT消息?为什么在发送WM_PAINT消息之前必须等待应用程序消息队列为空?这是因为系统将窗口中的绘图操作视为低优先级操作,所以尽可能推迟。但也有利于提高绘制效率:将两个WM_PAINT消息之间通过invalidating rect和invalidated无效的区域进行累加,然后在一个WM_PAINT消息中更新一次,不仅可以避免多次重复更新同一区域,还可以优化应用程序更新操作。依赖于系统在合适的时间发送WM_PAINT消息的invalidator和invalidating rgn使窗口区域无效的机制,实际上是一种异步工作模式,即在使窗口区域无效和发送WM_PAINT消息之间存在延迟;有时候这种延迟并不是我们想要的。当然这个时候我们可以使用SendMessage发送一个WM_PAINT消息来强制在窗口区域失效后立即重绘,但是最好使用Windows GDI提供的更方便更强大的函数:UpdateWindow和RedrawWindow。UpdateWindow将检查窗口的更新区域,并在它不为空时发送WM_PAINT消息;RedrawWindow给了我们更多的控制权:是否重绘非客户端区域和背景,是否不管更新区域是否为空都一直发送WM_PAINT消息等。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: