TN003:映射窗口句柄对象
translated by zhkza99c
这个笔记描述了MFC的规则,这个规则支持窗口的对象句柄到C++对象的映射。
问题
窗口对象通常以HANDLEs的方式表示出来,MFC的类通过C++的对象方法将窗口的句柄封装起来。MFC类库的句柄封装函数提供了一个通过特殊的句柄封装窗口对象成C++对象的方法,很多时候窗口的对象并不具有一个C++的封装对象,然而,很多时候一个临时的对象会被建立起来来充当C++封装对象的作用。
The Windows objects that use handle maps are:
使用句柄映射的窗口对象如下:
- HWND (CWnd and CWnd-derived classes)
- HDC (CDC and CDC-derived classes)
- HMENU (CMenu)
- HPEN (CGdiObject)
- HBRUSH (CGdiObject)
- HFONT (CGdiObject)
- HBITMAP (CGdiObject)
- HPALETTE (CGdiObject)
- HRGN (CGdiObject)
- HIMAGELIST (CImageList)
- SOCKET (CSocket)
通过给以上这些对象赋予句柄,你可以发现MFC的对象的封装操作是通过调用一个静态的成员函数 FromHandle来实现的。举例,已知一个值为hWnd的HWND
CWnd::FromHandle(hWnd)
将会返回一个指向CWnd的指针,这个指针封装了hWnd。如果hWnd并没有产生一个明确的对象,那么一个临时的CWnd将被创建出来封装hWnd。这使通过任何句柄获得一个有效的C++对象变得可能。
一点你有了一个被封装的对象,你就能通过一个共有成员变量获得他的句柄。在CWnd这种情况下,m_hWnd包含这个对象的HWND句柄。
Attaching Handles to MFC Objects
已知一个新创建的已封装的句柄对象和一个指向窗口对象的句柄,你可以将这两者通过调用Attach联系起来。例如:
CWnd myWnd;
myWnd.Attach(hWnd);
这会建立起一个项目,这个项目是永久性的关联myWnd 和hWnd的一个映射。调用CWnd::FromHandle(hWnd) 将会返回一个指向myWnd的指针。当myWnd 被删除后,析构函数会自动的通过窗口函数DestroyWindow 销毁hWnd。如果你并不愿意这么做,那么hWnd 必须在myWnd 的对象被销毁之前同myWnd 相分离。(通常离开myWnd 定义的作用域中)
成员函数Detach 做这些工作。
myWnd.Detach();
临时对象
当FromHandle 被付给一个句柄的时候的时候并没有一个已经封装的C++对象,那么就会产生一个临时的对象。这些临时的对象是同他们的句柄相分离的,并且通过调用DeleteTempMap 函数进行删除。默认状况下OnIdle 时刻CWinThread 自动调用DeleteTempMap 来使每一个类都支持临时的句柄映射。这就意味着你不能假定一个指向临时对象的指针可以在获得该指针的函数退出时依然保持有效,在Windows消息循环空闲时间这个临时的对象就会被删除。
封装对象和多线程
临时对象和永久对象都是每一个线程的基础,那就是说,一个线程不能够访问其他线程的C++对象,无论是临时对象还是永久的对象,正如以上所述,当线程进入OnIdle.状态的时候临时的对象就会被删除。
在线程间传递这些对象通常使用他们自身的HANDLE 类型,在线程间传递C++封装的对象经常会造成异常。
posted on 2008-03-25 16:22
田园的拾荒者 阅读(780)
评论(1) 编辑 收藏 引用 所属分类:
翻译