The Problem
Windows objects are normally represented by HANDLEs. The MFC classes wrap Windows object handles with C++ objects. The handle wrapping functions of the MFC class library provide a way to find the C++ object that is wrapping the Windows object with a particular handle. There are times when a Windows object does not have a C++ wrapper object, however, and at these times a temporary object is created to act as the C++ wrapper.
mfc 映射的 windows object ---->c++ wrapper
以下使用 mfc 的函数 如:fromhandle, getdlgitem,都会返回temporary 和 pemanent c++ wrapper object
注意:
零时的 对象 会被在空闲时(OnIdle()函数)被删除,不能存下在下次消息处理中 使用
The default OnIdle processing in CWinThread automatically calls DeleteTempMap for each class that supports temporary handle maps
////////////////////////////////////////////////////////////
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)
///////////////////////////////////////////////
Given a handle to any of these objects, you can find the MFC object that wraps the handle by calling the static member function FromHandle. For example, given an HWND called hWnd:
CWnd::FromHandle(hWnd)
will return a pointer to the CWnd that wraps the hWnd. If that hWnd does not have a specific wrapper object, then a temporary CWnd is created to wrap the hWnd. This makes it possible to get a valid C++ object from any handle.
Once you have a wrapper object, you can get to its handle through a public member variable. In the case of a CWnd, m_hWnd contains the HWND for that object.
Attaching Handles to MFC Objects
Given a newly created handle-wrapper object and a handle to a Windows object, you can associate the two by calling Attach. For example:
CWnd myWnd;
myWnd.Attach(hWnd);
////mywnd 析构时会调用 destroywindow ,连同 hwnd 一起销毁
This makes an entry in the permanent map associating myWnd and hWnd.
Calling CWnd::FromHandle(hWnd) will now return a pointer to myWnd.
When myWnd is deleted, the destructor will automatically destroy the hWnd by calling the Windows DestroyWindow function. If this is not desired, the hWnd must be detached from myWnd before the myWnd object is destroyed (normally when leaving the scope at which myWnd was defined). The Detach member function does this.
myWnd.Detach();
More About Temporary Objects
Temporary objects are created whenever FromHandle is given a handle that does not already have a wrapper object. These temporary objects are detached from their handle and deleted by the DeleteTempMap functions. The default OnIdle processing in CWinThread automatically calls DeleteTempMap for each class that supports temporary handle maps. This means that you cannot assume a pointer to a temporary object will be valid past the point of exit from the function where the pointer was obtained, as the temporary object will be deleted during the Windows message-loop idle time.
很重要:
在多线程中传递 c++ wrapper object 是无效的(无论是 temporary 还是 permanent)
只能传递 windows handle, 换句话就是说, 线程 只能 访问 自己创建的c++ wrapper object
Wrapper Objects and Multiple Threads
Both temporary and permanent objects are maintained on a per-thread basis. That is, one thread cannot access another threads C++ wrapper objects, regardless of whether it is temporary or permanent. As stated above, temporary objects are deleted when the thread which that temporary object belongs enters OnIdle.
To pass these objects from one thread to another, always send them as their native HANDLE type. Passing a C++ wrapper object from one thread to another will often result in unexpected results.
posted on 2006-06-30 11:33
黄大仙 阅读(1661)
评论(1) 编辑 收藏 引用 所属分类:
c++