views:

248

answers:

4

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!

A: 

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.

MBillock
A: 

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.

Aaron Fischer
Not that much the scope of the function as while processing the same message I guess.
EFraim
+8  A: 

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.

Phil Devaney
Does this mean that you could get the HWND from the (possibly temporary) CWnd and store that instead? Then, later on when required, you could call FromHandle using the stored HWND to get a CWnd.
Steg
Yes, that would be fine, the HWND will be valid for the lifetime of the window.
Phil Devaney
Excellent, cheers Phil
Steg
+1  A: 

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

Ron Pihlgren