Thread: subclassing a wndproc from within a class

  1. #1
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401

    subclassing a wndproc from within a class

    yep, i'm back with more class based problems. this time, ive made a class that encapsulates an edit control and makes it easy to use blah blah. my window procedure is still static, because i guess those rules still apply about things existing at certain times and this pointers and all that crap. anyway, inside the edit window procedure, there is no WM_NCCREATE message where i can retrieve a pointer to the class like i did with my other application class. so therefore i have no way to access any member functions or data members. help me, im stuck again!

    Code:
    class cEdit
    {
    public:
        WNDPROC wpProc;
        static LRESULT CALLBACK EditProc(...);
        cEdit();
    };
    
    cEdit::cEdit()
    {
        HWND hwnd=CreateWindowEx(...,(void *)this);
        wpProc=(WNDPROC)SetWindowLong(hwnd,GWL_WNDPROC,(LONG)EditProc);
    }
    
    LRESULT CALLBACK cEdit::EditProc(...)
    {
        cEdit *ce;
        //there's code here to check whether pointer to class is stored yet
        //and if so, store it in cEdit *ce
        return CallWindowProc(ce->wpProc,...);
    }
    the error message is an access violation on the CallWindowProc command, obviously because it is called at some stage before there is a valid pointer to put into ce. Since i'm using an edit control, and i get no WM_NCCREATE message, how am i supposed to retrieve the necessary pointers to make things work?
    Last edited by bennyandthejets; 01-04-2003 at 07:34 AM.
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  2. #2
    Registered User
    Join Date
    Dec 2002
    Posts
    119

    Re: subclassing a wndproc from within a class

    Originally posted by bennyandthejets
    Code:
    LRESULT CALLBACK cEdit::EditProc(...)
    {
        cEdit *ce;
        //there's code here to check whether pointer to class is stored yet
        //and if so, store it in cEdit *ce
        return CallWindowProc(ce->wpProc,...);
    }
    I might be missing something here, or not understanding what you're trying to accomplish, but why do you call your own EditProc from the EditProc?

    >> inside the edit window procedure, there is no WM_NCCREATE message where i can retrieve a pointer to the class

    just use the this keyword, that's what it's for.

    If what you want is a handle to the edit control, save it when you create the edit.

    If this is way off, you're going to have to explain your question a bit better

    -Futura
    If you speak or are learning Spanish, check out this Spanish and English Dictionary, it is a handy online resource.
    What happens is not as important as how you react to what happens. -Thaddeus Golas

  3. #3
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Subclass after window creation. As i've mentioned before in previous threads there are a number of messages sent during system processing of CreateWindow/CreateWindowEx. WM_CREATE and WM_NCCREATE are the two main culprits.

    Control subclassing is to be found by example, explanation and discussion through a search of this board.

    Good luck.

    edit: Sorry if i'm a bit grumpy today, it's because i'm a bit grumpy.

    By way of clarification: You can retrieve your this directly from your static wndproc via GetWindowLong because the control has not been subclassed until after wnd creation.

    If you still want that degree of control over your - er - control, then look to window superclassing: use GetClassInfoEx to fill a WNDCLASSEX structure, change a few things like the instance, wndproc and classname (your class, you name it) and then register and create as required. This way you get the default functionality of the control (provided you use the system wndproc for default handling) but can handle most messages in a manner identical to any other diy registered and created window.

    Hope that helps.
    Last edited by Ken Fitlike; 01-04-2003 at 11:12 AM.

  4. #4
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    sorry ken, but you'll have to clarify on the first stuff you said. does during system processing mean that the messages wont be sent to my wndproc? because i had the wndproc of an edit control ouput to a file every message that went through it, and there were no create messages at all. so whats going on?

    next:
    By way of clarification: You can retrieve your this directly from your static wndproc via GetWindowLong because the control has not been subclassed until after wnd creation.
    could clarify this? It seems to make no sense at all, which is not your usual style.

    for the last bit, window superclassing, are you saying create an edit control, get its class structure, stick in my own static wndproc instance etc, then do things like its my own window? ie, i can call defwindowproc() instead of callwindowproc()?
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  5. #5
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Bummer. Wrote two pages, wrong password. Gone.
    You can retrieve your this directly from your static wndproc via GetWindowLong because the control has not been subclassed until after wnd creation.
    Consider, within your static wndproc:
    Code:
    //beware: pseudocode!!!
    MyClass *pWnd=(MyClass*)GetWindowLong(...);
    if (!pWnd)
       {
       /*must be a diy registered and created wnd class
       so get and set this from WM_NCCREATE*/
       }
    //this is good so do stuff
    pWnd->MyMsgHandler(...);
    When you register a diy wnd class and create windows of that class, ALL the msgs go to your wndproc because that's the way it's set up. When you create a control, the initial creation messages go to the system defined wndproc; your diy wndproc does not kick in until you subclass the control after you have created the control using CreateWindowEx.

    When you superclass a control what you are doing is copying the details - including the default wndproc - for a control and then registering those details with a different class name,instance and diy wndproc; in effect you are creating a 'normal' window but based on the original control. Now, just like your normal window, ALL messages go to YOUR wndproc, because that's how that particular class of window was registered with the system. When you want default 'control' behaviour for it just ensure you use CallWindowProc using the original, system wndproc returned in the WNDCLASSEX when you initially called GetClassInfoEx.

    edit: just about everything.
    Last edited by Ken Fitlike; 01-04-2003 at 07:00 PM.

  6. #6
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    yeah i understand now. its all pretty clever huh? i cant register my superclass though. here's my code:

    Code:
    WNDCLASSEX wcx;
    GetClassInfoEx(NULL,"EDIT",&wcx);
    wcx.lpszClassName="cNewEdit";
    fpEditPrevProc=wcx.lpfnWndProc;
    wcx.lpfnWndProc=(WNDPROC)cEditProc;
    wcx.hInstance=(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE);
    if (!RegisterClassEx(&wcx))
    	exit(1);
    registerclassex isn't working for me. what have i done wrong?
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  7. #7
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Code:
    wcx.cbSize=sizeof(wcx);

  8. #8
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    you always have the right answers ken. now i can finally start making useful programs.
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

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. structure vs class
    By sana in forum C++ Programming
    Replies: 13
    Last Post: 12-02-2002, 07:18 AM