According to msdn, when I get a CWnd* with CWnd::FromHandle,
The pointer may be temporary and should not be stored for later use.
What is meant by "later use" is not clear to me. Is it only the scope of the current method? As far as I know, there is no GC in Win32!
FromHandle is basically used for getting a transient reference to an already existing window object. MFC stores these references in an internal structure called a temporary handle map (a handle map is a map of Windows HWNDs to MFC CWnd objects used by MFC to make Win32 calls to manipulate the actual Windows window the MFC object corresponds to). In order to avoid the number of objects in this structure from growing beyond all bounds, items are deleted from the handle map during MFC's idle loop processing.
As you may have guessed, there is also a permanent handle map that won't have this automatic clean up behavior. If you need to get a CWnd object that doesn't put its HWND reference in the temporary handle map you can call FromHandlePermanent().
-Ron
Typically they only want you to use this handle with in the scope of your function. And not to store it as a class field where you reference it through out the life of your object.
MFC maintains a number of handle maps, from HWND to CWnd, HDC to CDC etc, which are stored in the thread state. Each handle map contains a permanent map and temporary map - permanent entries are added when you call a method such as CWnd::Create or CDC::Attach, while temporary entries are created when you call FromHandle on a handle that doesn't have a permanent entry.
Temporary entries are cleaned up during idle processing (in CWinApp::OnIdle), so they can only safely be used while processing the current message. As soon as you return to the message loop, or enter another modal loop (e.g. by calling DoModal) then they may be deleted.
Based on the same MSDN description, I would assume that this means that if no CWnd is attached to the hWnd provided as an object, it will create a temporary CWnd which probably gets destroyed once something goes out of scope, or a destructor elsewhere is called, or a CWnd is explicitly created for the hWnd in question. So if you already have a CWnd created, you should be OK, otherwise you will probably need to be very careful with storing the pointer you receive.