DC、CDC及CDC的各个子类

设备描述表是一个包含设备信息的结构体(物理设备如显示器、打印


机),MFC中关于图像操作都需要DC来完成。HDC是Windows的一种数据


类型,是设备描述句柄;CDC是MFC封装的Windows 设备相关的一个类


;CClientDC是CDC的衍生类,产生对应于Windows客户区的对象,在构


造的时候调用GetDC,在析构的时候调用ReleaseDC;CWindowDC也是CDC


的衍生类,在构造的时候调用GetWindowDC,在析构时调用ReleaseDC


,可访问CWnd的整个屏幕,包括客户去和非客户区。


CDC是Windows绘图设备的基类。


CClientDC:(客户区设备上下文)用于客户区的输出,与特定窗口关


联,可以让开发者访问目标窗口中客户区,其构造函数中包含了


GetDC,析构函数中包含了ReleaseDC。 


CPaintDC:
(1)仅限于OnPaint处理程序,用于响应窗口重绘消息(WM_PAINT)时


的绘图输出。CPaintDC在构造函数中调用 BeginPaint()取得设备上下


文,在析构函数中调用EndPaint()释放设备上下文。EndPaint()除了


释放设备上下文外,还负责从消息队列中清除WM_PAINT消息。因此,


在处理窗口重画时,必须使用CPaintDC,否则WM_PAINT消息无法从消


息队列中清除,将引起不断的窗口重画。CPaintDC也只能用在


WM_PAINT消息处理之中。
(2)CPaintDC在构造函数中调用BeginPaint()取得设备上下文,在析构


函数中调用EndPaint()释放设备上下文。EndPaint()除了释放设备上


下文外,还负责从消息队列中清除WM_PAINT消息。因此,在处理窗口


重画时,必须使用CPaintDC,否则WM_PAINT消息无法从消息队列中清


除,将引起不断的窗口重画。
(3)CPaintDC也只能用在WM_PAINT消息处理之中。


CWindowDC:
(1)可在非客户区绘制图形,而CClientDC,CPaintDC只能在客户区绘


制图形。
(2)坐标原点是在屏幕的左上角,CClientDC,CPaintDC下坐标原点是


在客户区的左上角。
(3)关联一特定窗口,允许开发者在目标窗口的任何一部分进行绘图,


包含边界与标题,这种DC同WM_NCPAINT消息一起发送。


  
说明:在绘图时推荐使用


CClientDC,CPaintDC和CWindowDC对象,而不推荐直接使用CDC对


象,CWindowDC的构造函数调用GetWindowDC获取窗口DC(包含非客户区


),析构函数中调用ReleaseDC,当需要对窗口非客户区操作时使用。


以画线为例,上面几种DC的使用代码如下:


HDC hDC;  


hDC = ::GetDC(m_hWnd);  


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


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


::ReleaseDC(m_hWnd,hDC); 


  


CDC * pDC = GetDC(); 


pDC->MoveTo(m_ptOrigin); 


pDC->LineTo(point); 


ReleaseDC(pDC); 




CClientDC dc(this);  


//CClientDC dc(GetParent()); 


dc.MoveTo(m_ptOrigin); 


dc.LineTo(point); 


  


//


CWindowDC dc(this);//this代表只能在view区域绘画


//CWindowDC dc(GetParent());//在整个frame区域绘画


CWindowDC dc(GetDesktopWindow());//可在整个桌面区域绘画


dc.MoveTo(m_ptOrigin); 


dc.LineTo(point);  


 
HDC就是最原始的DC 句柄,很多API的第一个参数就是一个HDC类型,


比如


HDC hDC = ::GetDC( m_hWnd); 
::MoveToEx( hDC, 0,0, NULL ); 


::LineTo( hDC, 0, 100, );  


::ReleaseDC( m_hWnd, hDC ); 


  
在MFC中,为了将API封装成一个类来操作,因此多出来了一个CDC。所


以在MFC中,都是


CDC dc = GetDC(); 
dc.MoveTo( 0,0 );  
dc.LineTo( 0,100 );  
this->ReleaseDC( &dc ); 


  
但这样还不够,因为CDC还要你自己去释放,所有MFC中又多出来一个
CClientDC, 这样你就可以这样了:


CClientDC dc(this); 
dc.MoveTo( 0,0 ); 
dc.LineTo( 0,100 ); 
 
CClientDC的析构函数自己会释放自己。DC不是什么对象,就是设备上


下文的简称。与CClientDC一样,还有CWindowDC,CPaintDC,只是它


们的绘制范围不一样。但弄到底,都只是HDC的一些封装而已,你可以


在CDC类中直接引用m_hDC,这就是那个原始的HDC句柄了-  
HDC、CDC、CClientDC、CWindowDC、CpaintDC  hdc是dc的句柄,cdc是


一个封装的dc类,后面这三个dc就是使用的场合稍有区别,都是派生自


cdc的,第一个是客户区dc,经常用,第二个是窗口dc,针对整个窗口绘图
,cpaintdc好像只在onpaint函数中使用吧。CDC是MFC对HDC的封装,


CDC
和HDC可以相互转换:
HDC hdc = pDC->GetSafeHdc(); // pDC is CDC*,由CDC得到HDC 
CDC* pDC = CDC::FromHandle(hdc);//由HDC得到CDC


FromHandle:
static CDC* PASCAL FromHandle( HDC hDC ); 
返回值:用于立即使用的临时指针。


备注:当给定设备上下文的指针时,则返回CDC对象的指针。如果CDC
对象未与句柄相连,将创建一个临时CDC对象并与之相连。(看看句柄


所指窗口是否存在,存在的话就会返回这个窗口指针。)




CClientDC、CWindowDC这两个尽量不用吧,它们对于WS_CLIPCHILDREN
属性是忽略的。


CPaintDC是MFC里面用得最多的,实际上CDC*往往是CPaintDC的对象。


WS_CLIPCHILDREN 兄弟:
不要管那些XXDC,只要记住怎么用HDC就可以了,所有的DC类,地层都是


在折腾HDC,不如你直接学会玩HDC.别搭理那些鸟DC,那些DC,都可以提


炼出
HDC的,提出来就像


CDC *pDC;提炼HDC:pDC->m_hDC;搞到HDC自己用API画什么不行? 
 
CDC类及其子类---CClientDC、CWindowDC和CPaintDC CDC类Windows使


用与设备无关的图形设备环境(DC :Device Context) 进行显示。


MFC基础类库定义了设备环境对象类----CDC类。
父类:从CObject 直接继承而来。继承了CObject类的各种特性,如动


态创建等等。


例如用GDI画矩形要Rectangle(hDC,...),而使用CDC则是


dc.Rectangle(...),由此可见CDC主要是把原本需要HDC作为参数的
GDI函数封装了一下,HDC成了它的一个成员变量。


CPaintDC 


CWindowDC 


CClientDC:


他们都是从CDC继承,分别是对上面所说的BeginPaint,GetWindowDC, 
GetDC调用对进行封装(CPaintDC构造时调用BeginPaint,析构时调用
EndPaint,其余同理)。




数据成员只有两个:


HDC m_hDC : CDC对象使用的输出设备上下文


HDC m_hAttribDC : CDC对象使用的属性设备上下文


CClientDC子类


CClientDC类只能在客户区绘图;


所谓客户区指窗口区域中去掉边框、标题栏、菜单栏、工具栏、状态


栏等之外的部分,它是用户可以操作的区域;


在使用CClientDC进行绘图时,一般要调用GetClientRect()函数来获


取客户区域的大小;


CClientDC类在构造函数中调用Windows API函数GetDC(),在析构时响


应ReleaseDC();


CClientDC类的窗口句柄保存在成员变量m_hWnd,为构造CClientDC,


需将CWnd作为参数传递给构造函数。




CWindowDC子类




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


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




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


角。




在使用CWindowDC进行绘图时,一般要调用GetWindowRect函数来获取


整个应用程序窗口区域的大小;


CWindowDC类的窗口句柄保存在成员变量m_hWnd,为构造CClientDC,


需将CWnd作为参数传递给构造函数。




CPaintDC子类通常CPaintD用来响应WM_PAINT消息。一般应用OnPaint
函数。




CClientDC也是从CDC派生出来的。构造时自动调用GetDC函数,析构时


自动调用ReleaseDC函数。




一般应用于客户区窗口的绘制。


CPaintDC只能在WM_PAINT消息中使用, 用于有重画消息发出时才使用


的内存设备环境, 而CClientDC和客户区相关,有重画消息发出时才使


用的内存设备环境, 可在任何地方使用。


  


在处理窗口重画时,必须使用CPaintDC,否则WM_PAINT消息无法从消


息队列中清除,将引起不断的窗口重画。


 
GDI是什么?
GDI是微软提供的图形编程库。


DC是什么?
DC是GDI库里定义的一种概念而已。执着于DC到底是什么,没有任何意


义,因为微软没有暴露出任何关于DC的实现。


 
HDC是一种HGDIOBJ。就像奥迪是汽车的一种。


创建透明画刷:


CBrush *pBrush=CBrush::
FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); 


 


函数原型:


HGDIOBJ GetStockObject(int fnObject)





 


  
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值