Results 1 to 4 of 4

Thread: subclassing

  1. #1

    Thread Starter
    Member
    Join Date
    Oct 2000
    Posts
    34

    subclassing

    I am wondering if it is possible to subclass a window from within a class. Consider the following class:

    Code:
    class Base
    {
    public:
      Base() {}
      virtual ~Base() {}
    
      BOOL Subclass(HWND hWnd)
      {
        long lpfnNewProc = (long)this->MsgHandler; //<-- This is my error
        long lpfnOldProc = SetWindowLong(hWnd, GWL_WNDPROC, lpfnNewProc);
    
        return TRUE;
      }
    
      LRESULT CALLBACK MsgHandler(HWND hWnd,
                                  UINT msg,
                                  WPARAM wParam,
                                  LPARAM lParam)
      {
        // Do something with the message
        return 0;
      }
    };
    Now, I realize this is not a complete class. I cannot get a function pointer to the MsgHandler function of the class. I realize this is because Windows wants (requires?) that the callback function be a global function and not an instance function, but is there some way around this? If not then I have to have a global MsgHandler and store all the hWnds and function pointers in global arrays and I really don't want to do this. If there is a way to pull off what I am trying to do, can somebody please let me know how.

    Thanks

  2. #2
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    This is what seems to be the best option...

    Make the MsgHandler function static, and also have an InternalMsgHandler function of the same type, just not static:
    Code:
    class Base {
        static LRESULT CALLBACK MsgHandler(...) { ... }
        LRESULT InternalMsgHandler(...) { ... }
    };
    You put the specific code into the InternalMsgHandler function.

    This is where it gets clever When you subclass it, use SetWindowLong like so:
    Code:
    SetWindowLong(hWnd, GWL_USERDATA, (long)this);
    This associates your class with the window, since the GWL_USERDATA property is a 4-byte long integer (how useful... ). Then, in MsgHandler, just use:
    Code:
    Base *pHandler = GetWindowLong(hWnd, GWL_USERDATA);
    if(pHandler) {
        pHandler->InternalMsgHandler(hWnd, uMsg, wParam, lParam);
    }
    // Call the previous function here
    It's a bit nasty I know...can you see what I'm getting at?
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  3. #3

    Thread Starter
    Member
    Join Date
    Oct 2000
    Posts
    34
    Ahhh...pretty clever indeed. Thank you very much.

    You could also use the GetProp and SetProp functions to associate the pointer with the window.

    Again thanks.

  4. #4
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Proudly stolen from Microsoft's own samples

    You can use the properties, but I think it's simpler this way. Oh, and for your information, I think this is called delegating...not sure though Looks a bit like the description.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width