都知道,从HWND可以通过方法GetSafeHDC获得一个HDC句柄,用CDC::GetWindow方法可以获得一个CWnd指针。我就犯嘀咕了,dc和窗口两个类(对象)之间,究竟是怎么一种关系?他们是怎么互相获得的?通过什么联系?
GetSafeHDC是CDC的函数吧。
CDC::GetWindow调用的是API函数WindowFromDC(),从窗口句柄得到客户区DC句柄的API函数是GetDC()。
窗口句柄,将所有窗口有关的资源联系在一起。
象窗体,按钮等其他图元其实都是视频显示器上的一块区域。而所有的图元都有一个dc,这个dc是用户用于GDI的一些参数,建议看看《Windows程序设计》
在windows操作系统中,
hdc属于GDI句柄(由gdi32.dll管理),hwnd属于用户句柄(由user32.dll管理),
两者是不同的概念!!!
楼主可以这样设想:
hwnd句柄是描述一个窗口的形状、位置、大小、是否显示、
它的父窗口、兄弟窗口、等等的一组数据结构;
hdc句柄是一个实实在在的用于具体表现这个窗口时,需要对这个窗口有个场合
来实现的地方。
这像国家与政府很相似。
为什么说GetDC后一定要ReleaseDC?这也让我感到可疑。(不ReleaseDC不会致命的)
----------------------------------------------------------------------------
现在不致命了,以前版本是致命的!
说实在,现在不致命也是有个度。
对于hdc来说,系统中有个叫用户dc,还在一个叫系统dc,
一般来说调用 API:GetDC()得到一个系统dc 的复制,说得简单点,一个复制位需要
内存空间,它需要一个索引值等信息描述以及指向一个内部数据结构的指针。
如果不释放,系统会直到进程结束才释放,这样将会浪费句柄表的空间,而
这个表在全系统范围内是共享,所以得释放。
1.dc实际上是从显示驱动过来的,用过dx的都知道有surface的概念
2.其实显示驱动中的surface在用户空间被加上一些额外信息之后就成了dc
3.surface是一个很大的显示资源结构,因为你要在屏幕上绘制字符与图形图象时,这些信息是必须的
4.因为窗口是windows界面管理的基本单位,当然也是一很大的数据结构,故每个窗口中得保存与窗口所定义的这块屏幕的相关的显示数据,就是窗口DC,由于一些dc与窗口相关了,所以在dc中也得有相应窗口的索引
5.窗口由窗口管理器管理,surface由显示驱动管理,但是hdc,hwnd是由句柄管理器管理,负责创建,销毁,索引等等
********************************************************
CDC与HDC
CDC是设备上下文类
HDC是设备上下午句柄
CDC-->HDC与HDC->CDC
CDC dc;
HDC hDC;
hDC=dc.m_hDC;
dc=CDC::FromHandle(hDC);
或者
hDC=dc.GetSafeHdc();
pDC 是 类指针
HDC 是 windows句柄
通过pDC获得hdc:
HDC hdc=pDC->GetSafeHdc();
通过hdc获得pDC:
CDC *pDC=new CDC;
pDC->Attach(hdc);
*************************************************************
嗯,CXX是封装后的类,HDC,HWND是名柄。
可以通过类中的 FromHandle或Attach()将句柄---》CXX类
也可以通过GetSafeHwnd() GetSafeHDC()获得相关句柄
对楼上的补充:
CXX(封装后的 HDC、HWND等),有一定的“时效”性,它并不是全局存在的,MFC框架会在“空闲”时间短内删除这些对象(并不绝对),所以,在MFC程序里要想“永久”保存例如句柄HWND,则需要将CWnd对象“转存”为HWND来保存。
微软在MFC里使用CXX,是从C++语言本身、MFC框架、效率等方面考虑而得出的一个折衷的办法,可以概括的说是为了保持MFC的“一致性”。
HDC,HWND是Windows对象的句柄,在用API对这些对象操作时要作为参数传递
CDC,CWnd是MFC类,对Windows对象进行封装
H 开头是句柄,可作为参数传递或作为函数的返回值,C开头的是mfc的类可定义对象的