Re: Window class

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: Volker Hilsheimer (vohi_at_trolltech.com)
Date: 02/24/04


Date: Tue, 24 Feb 2004 10:58:46 +0100

Your window proc receiving the WM_CREATE message is called synchronously
from the constructor of the Window1 class (via create), which is called
from the SettingsDlg constructor.

The pointer you pass into the CreateWindow API (the "this" pointer)
references at this point an object of type Window1, which is going to be
an object of type SettingsDlg once the Window1 constructor is completed,
and the SettingsDlg constructor is entered. Not a single line of code of
that SettingsDlg constructor is executed, so the object behaves like a
Window1 object.

This is defined C++ behavior - it will happen with Borland, VC++ or gcc.
There is no way around it, other than calling an explicit create()
function to create the window after the C++ object has been completely
created (which leads to a rather awful design like in MFC), or to use a
dictionary (ie. a hash-table) to map the window handle for future window
messages to the C++ object that will then be complete (and then call a
virtual function). Pseudo-code:

LRESULT GenericWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

    Window1 *window = Dictionary.Find(hWnd);
    if (!window) // unkown handle - do nothing
        uMsg = WM_NULL;

    switch(uMsg) {
    case WM_SIZE:
        window->OnSize(wParam, lParam);
        break;

    ...

    default:
        return DefWindowProc(...);
    }

    return 0;
}

OnSize() in above code would be a virtual function of the Window1 class,
possibly reimplemented by your subclass.

Of course WM_CREATE messages cannot be handled, but since you have a
constructor in C++ you don't have to anyway :)

Cheers,
Volker

"Bonj" <a@b.com> wrote in message
news:OjLyqSk%23DHA.220@TK2MSFTNGP09.phx.gbl...
> But it wasn't trying to call a member function of the derived class from
the
> constructor, it was trying to do so from WndProcHandler, which is a
static
> method of the base class.
> It isn't really being 'subclassed' in the true sense of the word, I
suppose
> it is in a way but I thought subclassing involved replacing a WndProc
with
> another one in order to handle extra messages, this is just one central
> WndProc routing the messages to the derived class instantiations.
> I don't know what you mean by 'keep a dictionary'. But I've got it
working
> now, which is the main thing - I was just curious I guess as to why
calling
> the derived class member function on the actual WM_CREATE message (when
the
> pointer to its memory address is at this time known, albeit only just)
> causes it to crash on an 'invalid v-table' or something, but calling it
on
> the next message when the pointer has been forgotten and retrieved
again,
> works fine.....
> Thanks again
>
>
> "Volker Hilsheimer" <vohi@trolltech.com> wrote in message
> news:uwIvmzi%23DHA.3428@tk2msftngp13.phx.gbl...
> > The object you create when calling the constructor is still a
"Window1"
> > object when the Window1 constructor is executed. That's how C++ object
> > creation works - calling virtual functions (or functions with a
"virtual"
> > semantic, ie. like your's) in the constructor (or the destructor) is
> > pointless if you expect your class to be subclassed.
> >
> > But then you have a C++ class anyway. Keep a dictionary of HWND ->
Window1
> > class, and have your window procedure use that dictionary to find the
> > Window1 object for a certain message.
> >
> > Volker
> >
> > "Bonj" <a@b.com> wrote in message
> > news:uOA7JZX%23DHA.2664@TK2MSFTNGP09.phx.gbl...
> > > i'm trying to create a class that will contain all the features of
> > > instantiating a window and showing it. I've got the SetWindowLong /
> > > GetWindowLong pair to succesfully store the 'this' pointer in the
hWnd's
> > > GWL_USERDATA, but the pointer that it's referring to always seems to
> > point
> > > to the base class and never the derived class. I don't know what I'm
> > doing
> > > wrong, this has been driving me mad for hours. Consequently, the
static
> > > WndProc handler function can never route the messages to the class's
> > actual
> > > wndproc (which is virtual and implemented in the derived class) - it
> > gives
> > > me some low-level debug error of 'pure virtual function call' ....
WHY
> > can't
> > > I get it to see the derived class? help!....
> > > Thanks
> > >
> >
> >
>
>



Relevant Pages

  • Re: Window class
    ... from the SettingsDlg constructor. ... references at this point an object of type Window1, ... and the SettingsDlg constructor is entered. ... possibly reimplemented by your subclass. ...
    (microsoft.public.vc.language)
  • Re: Window class
    ... from the SettingsDlg constructor. ... references at this point an object of type Window1, ... and the SettingsDlg constructor is entered. ... possibly reimplemented by your subclass. ...
    (microsoft.public.win32.programmer.ui)
  • Re: Window class
    ... The object you create when calling the constructor is still a "Window1" ... > to the base class and never the derived class. ...
    (microsoft.public.vc.language)
  • Re: Window class
    ... The object you create when calling the constructor is still a "Window1" ... > to the base class and never the derived class. ...
    (microsoft.public.win32.programmer.ui)
  • Re: Window class
    ... The object you create when calling the constructor is still a "Window1" ... > to the base class and never the derived class. ...
    (microsoft.public.dotnet.languages.vc)