Members

Technology Zones

IBM Learning Center

Articles

Hosted By

MaximumASP

Info

Rated
Read 16,641 times

Contents

Related Categories

Attaching and Detaching Objects - CWnd

flounder

CWnd

Windows: FromHandle and FromHandlePermanent

 For CWnd-derived classes, you can get a temporary CWnd * object from FromHandle. Thus, if you have a class CMyCoolWindow and you do something like GetFocus you may or may not get an actual pointer to your CMyCoolWindow * object. I've had numerous failures in this way. For example, I've taken to doing

CWnd * capture = GetCapture();
if(capture != NULL && capture->m_hWnd == m_hWnd)
    { /* I have capture */
     // ... do something
    } /* I have capture */

If you need a handle to your actual object for a given HWND, you should use CWnd::FromHandlePermanent. This will return a handle from the permanent window map. Note that CWnd::FromHandlemight return a handle to a permanent window, and then again, it might not. You have no guarantee.

CWnds and Threads

The object maps are thread-local. This means that if you are in a thread and do a CWnd::FromHandle you will get a new, temporary window object which is not the same C++ object that represented your class initially. Thus this is always fatal in a thread:

CMyCoolWindowClass * me = 
            (CMyCoolWindowClass *)CWnd::FromHandle(hWnd);
me->MyCoolVariable = 17; // modifies some location you've never 
                         // heard of!

You will actually get a generic CWnd pointer, and if you did

me->IsKindOf(RUNTIME_CLASS(CMyCoolWindowClass))

you would get FALSE. If you did

CMyCoolWindowClass * me = 
          (CMyCoolWindowClass *)CWnd::FromHandlePermanent(hWnd);

you would always get NULL because the permanent handle map for the thread is empty, unless you actually created the window in that UI-thread.

If you need access to a window class in a thread, particularly in a worker thread, pass it into the thread via the thread routine's initial pointer. See my essay on Worker Threads for more details.

Comments