Library tutorials & articles

Attaching and Detaching Objects

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

  1. 13 Sep 2006 at 07:43

    Sorry posted in wrong thread

  2. 13 Sep 2006 at 06:14
    Hi

    i am new to VC++, while creating a model dialog from a cwnd class i am getting a Assertion error.
    can any one tell me where i did wrong.

    class CAuthen:: public CWnd
    {
      ............
    ..
    public:
     
    CAuthenDlg auth_dlg;
    ..

    public :

     void checkAuthentication();
     

    };

    void CAuthen :: checkAuthentication()
    {
    ..
    ..
    ..

       if(  auth_dlg.DoModal() == IDOK)
        {
           ...
           // some operation goes here
        }
    ..
    ..
    }



































  3. 01 Jan 1999 at 00:00

    This thread is for discussions of Attaching and Detaching Objects.

Leave a comment

Sign in or Join us (it's free).

Joseph M. Newcomer

Want to stay in touch with what's going on? Follow us on twitter!