Thread: Puting win32 callbacks into a class

  1. #1
    Registered User Josh Kasten's Avatar
    Join Date
    Jul 2002
    Posts
    109

    Question Puting win32 callbacks into a class

    How could I put a win32 callback into a class without making it static so I use member variables and fucticions in the callback?
    int a; don't make a program without it.

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Read to the end of this post.

    gg

  3. #3
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Hey Codeplug, have you managed to get the thunking method to properly handle the WM_CREATE message?

    Most people seem to use SetWindowLong after CreateWindow to get the thunk to work, but as WM_CREATE is sent during the call to CreateWindow, this would then be missed.

    Messing around a while ago I tried to attach the thunk to the WNDCLASS before the cal to CreateWindow, but it didnt seem to like this and CreateWindow returned 0. I was going to go back and have a proper look again at this, but this post reminded me.

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Almost forgot about this thread.......

    Using the thunk as the WNDPROC of the class works fine for me. CreateWindow() may of been failing for another reason (like not handling WM_NCCREATE with TRUE).

    There is a dilemma that isn't limited to just the WM_CREATE message since there are a few other messages that can be sent before WM_CREATE. I'll just call it the "creation dilemma". The dilemma is this: The whole purpose of using a thunk is to replace the HWND parameter of the window procedure with the "this" pointer of a class instance that already knows the HWND for which the message is targeted. We don't know the HWND until CreateWindow(), CreateDialog(), and the like returns, however these functions all dispatch several messages before returning the HWND. For all the messages dispatched within the creation function, the windows procedure will not know what HWND the message is targeted for. This isn't a problem when subclassing with a thunk since the HWND is known.

    Now to the solutions, of which the easiest is to use a special "creation" windows procedure. This procedure is only called once for the very first message, and it is not called using a thunk so that the HWND parameter is preserved. Here's what it does:
    - Store off the HWND parameter within the class instance responsible for creating the window.
    - Create and install (via subclassing) a thunk that uses the class instance as the first parameter of a new windows procedure (usually the static member function of your base "Window" class).
    - For the initial message being sent, call the new window procedure directly using the class instance pointer as first parameter (which is what the thunk will do on subsequent messages now that the HWND has been subclassed using the thunk).

    Once you've digested that, you should be asking "how do I know the class instance responsible for creating the window?" - Easy, use a global. And if thread safety is a goal, use thread local storage.

    This solution does have its problems. The solution requires you to be able to specify your special "creation" windows procedure before calling the creation function (CreateWindow() etc...). This isn't a problem for dialogs since the dialog procedure is a parameter to all the dialog creation functions. For non-dialogs the windows procedure is specified by the window's WNDCLASS, which cannot be changed. The article in the following link shows two solutions which MFC uses to overcome this dilemma.
    http://www.pocketpcdn.com/articles/wce_prefix.html

    As the article describes, desktop-MFC uses hooks and CE-MFC uses the re-class method. I use the re-class method myself so my stuff can run under CE as well.

    gg

  5. #5
    Registered User Josh Kasten's Avatar
    Join Date
    Jul 2002
    Posts
    109
    I haven't tried the methed that you sent me to try but i did try out the one here(http://cboard.cprogramming.com/showt...ghlight=static). It seems to work but the only only problem is that it does not return untill a EndDialog(); is called to close it. Any way to fix this? One more thing does your code work just work with dialogs and not windows? Sorry but i got one more too, why would they make a WIN32 callback so hard to OOPed?
    int a; don't make a program without it.

  6. #6
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    The example attached at the end of that thread creates a modal dialog despite the comments in the code saying it's modeless; sorry about any confusion that I may have caused you. In any event, the principles employed in that example are exactly the same for modeless dialogs and windows, although with windows, this is typically stored during processing of WM_NCCREATE messages. Of course, that approach uses a static window procedure which does not completely answer your original question.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  7. #7
    Registered User Josh Kasten's Avatar
    Join Date
    Jul 2002
    Posts
    109
    Its fine if there is a static in there but what i want is a way to get the messages to a callback in a class.
    int a; don't make a program without it.

  8. #8
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    This has been discussed at length in many previous threads: just forward the messages to a (usually) virtual 'window procedure' from the static 'window procedure using the pointer returned from GetWindowLong/GetWindowLongPtr.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  9. #9
    Registered User Josh Kasten's Avatar
    Join Date
    Jul 2002
    Posts
    109
    Yes I've seen that in the code but now I was asking how to make the program keep run because DialogBoxParam() stops your program untill EndDialog();.
    int a; don't make a program without it.

  10. #10
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    That's because DialogBoxParam creates a modal dialog - use a modeless dialog created with, for example, CreateDialog or a normal window if you don't want that (modal) behaviour.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  11. #11
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    For future reference or for anyone interested, here's a page that summarises and provides example code for many of the c++ window procedure member function techniques discussed on this board in the past:

    Window Procedures as Class Member Functions
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  12. #12
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Nice link.

    The part about MFC taking linear time to lookup CWnd pointers is incorrect. MFC uses a hash table for mapping all handles to class objects, including HWND's to CWnd*'s.

    Lookups into a hash table run in constant time (average case), but still not as fast as a thunk.

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 11:03 PM
  3. Replies: 8
    Last Post: 10-02-2005, 12:27 AM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM