473,387 Members | 1,798 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Window class

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

this is in window1.h (the base class)

#ifndef WINDOW1CLASS_DEFINED

#define WINDOW1CLASS_DEFINED

class Window1

{

public:

//variables:

HWND hWnd;

HCURSOR hcWait, hcArrow;

BOOL bWaiting;
//methods:

void Create( HINSTANCE hInst,

HICON hIcon,

HICON hIconSm,

HBRUSH hbrBackground,

LPCTSTR lpszCaption,

int nClassStyle,

int nWindowStyle);

static LRESULT CALLBACK WPHandler(

HWND hWnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam);

virtual LRESULT WndProc(HWND hWnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam) = 0;

virtual int ShowModally(int nCmdShow) = 0;

//constructor/destructor:

Window1() : hWnd(NULL) {};

virtual ~Window1() {};

Window1( HINSTANCE hInst,

HICON hIcon,

HICON hIconSm,

HBRUSH hbrBackground,

LPCTSTR lpszCaption,

int nClassStyle,

int nWindowStyle);

};

#endif

//this is in Window1.cpp

//======================================

#include "Generics.h"

#include "Window1.h"

Window1::Window1( HINSTANCE hInst,

HICON hIcon,

HICON hIconSm,

HBRUSH hbrBackground,

LPCTSTR lpszCaption,

int nClassStyle,

int nWindowStyle)

{

Create(hInst, hIcon, hIconSm, hbrBackground,

lpszCaption, nClassStyle, nWindowStyle);

}

LRESULT CALLBACK Window1::WPHandler( HWND hWnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam)

{

if(uMsg == WM_NCCREATE)

{

LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;

SetWindowLong(hWnd, GWL_USERDATA, (long)lpcs->lpCreateParams);

}

Window1* pThis = (Window1*)(LPVOID)(::GetWindowLong(hWnd, GWL_USERDATA));

//Window1* pThis = (Window1*)(GetWindowLong(hWnd, GWL_USERDATA));

if(pThis) return pThis->WndProc(hWnd, uMsg, wParam, lParam);

else return DefWindowProc(hWnd, uMsg, wParam, lParam);

}

void Window1::Create(HINSTANCE hInst,

HICON hIcon,

HICON hIconSm,

HBRUSH hbrBackground,

LPCTSTR lpszCaption,

int nClassStyle,

int nWindowStyle)

{

bWaiting = FALSE;

WNDCLASSEX wcx;

memset(&wcx, 0, sizeof(WNDCLASSEX));

wcx.cbSize = sizeof(WNDCLASSEX);

wcx.style = nClassStyle;

wcx.lpfnWndProc = Window1::WPHandler;

wcx.hInstance = hInst;

wcx.hIcon = NULL;

wcx.hCursor = NULL;

wcx.hbrBackground = hbrBackground;

wcx.lpszMenuName = NULL;

wcx.lpszClassName = lpszCaption;

wcx.hIconSm = NULL;

hcWait = (HCURSOR)LoadImage( NULL,

IDC_ARROW,

IMAGE_CURSOR,

CW_USEDEFAULT,

CW_USEDEFAULT,

LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED);

hcArrow = (HCURSOR)LoadImage( NULL,

IDC_WAIT,

IMAGE_CURSOR,

CW_USEDEFAULT,

CW_USEDEFAULT,

LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED);

ATOM ClassName = RegisterClassEx(&wcx);

hWnd = CreateWindow( (LPCTSTR)ClassName,

lpszCaption,

nWindowStyle,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

(HWND)NULL,

(HMENU)NULL,

(HINSTANCE)hInst,

(LPVOID)this);

}


//and the base class is defined as such (settingsdlg.h)

#include "Window1.h"

class SettingsDlg : public Window1

{

public:

//constructor/destructor:

SettingsDlg( HINSTANCE hInst,

HICON hIcon,

HICON hIconSm,

HBRUSH hbrBackground,

LPCTSTR lpszCaption,

int nClassStyle,

int nWindowStyle) :

Window1( hInst,

hIcon,

hIconSm,

hbrBackground,

lpszCaption,

nClassStyle,

nWindowStyle) {};

//SettingsDlg() {};

//~SettingsDlg() {};
LRESULT WndProc(HWND hWnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam);

int ShowModally(int nCmdShow);

};

//(settingsdlg.cpp)

#include "Generics.h"

#include "settingsdlg.h"

int SettingsDlg::ShowModally(int nCmdShow)

{

{

if(hWnd)

{

ShowWindow(hWnd, nCmdShow);

UpdateWindow(hWnd);

}

else

return -1;

}
{

MSG msg;

while(GetMessage(&msg, hWnd, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return (int)msg.wParam;

}

}



LRESULT SettingsDlg::WndProc( HWND hWnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam)

{

switch(uMsg)

{

case WM_MOUSEMOVE:

{

SetCursor((bWaiting) ? (hcWait) : (hcArrow));

return 0;

}

/*

case WM_CLOSE:

{

PostMessage(hWnd, WM_QUIT, 0, 0);

return 0;

}

*/

}

return DefWindowProc(hWnd, uMsg, wParam, lParam);

}

//and my winmain cpp file looks like this:

#include "Generics.h"

#include "SettingsDlg.h"

int WINAPI WinMain( HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpszCmdLine,

int nCmdShow

)

{

HICON hIcon = (HICON)LoadImage( hInstance,

MAKEINTRESOURCE(IDI_TRANS),

IMAGE_ICON,

GetSystemMetrics(SM_CXICON),

GetSystemMetrics(SM_CYICON),

LR_DEFAULTCOLOR | LR_SHARED),

hIconSm = (HICON)LoadImage( hInstance,

MAKEINTRESOURCE(IDI_TRANS),

IMAGE_ICON,

GetSystemMetrics(SM_CXSMICON),

GetSystemMetrics(SM_CYSMICON),

LR_DEFAULTCOLOR | LR_SHARED);
SettingsDlg sdlg( hInstance,

hIcon,

hIconSm,

(HBRUSH)(COLOR_3DFACE + 1),

"SpaceMaze settings",

CS_OWNDC | CS_HREDRAW | CS_VREDRAW,

WS_OVERLAPPEDWINDOW);

return sdlg.ShowModally(SW_SHOWMAXIMIZED);

}



Thanks ever so much to anybody that can help me out of this !


Nov 17 '05 #1
12 1860
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:uO****************@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

Nov 17 '05 #2
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" <vo**@trolltech.com> wrote in message
news:uw****************@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:uO****************@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


Nov 17 '05 #3
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:uO****************@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

Nov 17 '05 #4
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" <vo**@trolltech.com> wrote in message
news:uw****************@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:uO****************@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


Nov 17 '05 #5
Now that we know that you are going through all that trouble because
you use Borland. I just wanted to remind you that posting questions about
windowing code done in Borland in a VC news group is probably not
the most efficient way of doing things. That said, i have never used Borland
but something tellsme that over the long years since Borland has been
around,
im sure that somebody , somewhere has written code to wrap win32 windows
and that it would make more sense to base your work on solid ground
rather then re-inventing the wheel and risk running into a world of problems
and hoping that this news group, wich isnt specialised in Borland will be
solve all those issues.

Im only suggesting all that to save you some time though.

cya

Nov 17 '05 #6
How do you *know* that, with regards to this specific problem? Guessing
generically more like.
You're wrong in that I'm going through this trouble because I use Borland.
It compiles fine with either Borland or VC7.0.
Using the .NET 2002 compiler gave exactly the same error before I fixed the
bug, which I now have, and gave no more information as to the cause of the
error than bcc32 and td32 did.

You're right in that somebody has written code to wrap a Win32 window, the
designers of MFC for one. Which is what I may end up using, if I was writing
applications in a commercial environment. However, this particular project
is more of a hobbyist thing, so I want to design it the way I want, with
just the features I want and not the ones I don't. I want to be able to
genericise all the various portions of utility code and algorithms needed in
both my actual application, and any utility tools I write and use to aid me
in creating it, archive them for possible future use, and then specialise
them as required - as opposed to having to shoehorn my wishlist into
something like MFC. Not that MFC's bad - it's just I've got the "want it
just-so" bug with this particular project, and I want to construct all the
parts myself just to see how it's done if nothing else / in the rare case
that someone else has invent the exact wheel I'm trying to craft.

In terms of posting to these newsgroups - without sounding patronising, many
have tried to see me off before and failed (I'm still here) so I don't see
how you think you can sunshine. If you are genuinely suggesting for my own
benefit and there really is a free, high-volume, on-topic newsgroup that's
more specific to Borland development that'll work with OE, then I'll admit I
don't know about it and I apologise, and would appreciate if you would point
me to the news server name. But even then I'll be more likely to use it in
addition to this one rather than instead of.

Incidentally my reason for using Borland is that I simply don't trust
Microsoft tools any more, since reinstalling their SDK doesn't produce a
windows.h file, and many others. Reinstalling windows hasn't fixed this
problem, so there must be something up with the way the complex web of .msi
files works. Consequently, I can't trust it - and besides, they don't give
an optimizing compiler for free.

However, none of my questions are specific to Borland products in any way,
and are just as relevant to Microsoft development, and since I have GOT
Microsoft VS.NET, including VC7.0, and since my project compiles OK with
that aswell as Borland, as far as you're concerned my questions might as
well be about developing with Microsoft Visual C++ - as if you answered it
as if that was the case, I would be perfectly capable of interpreting the
result - not that any interpretation has thus far been required, nor can I
foresee any being required.

If you're not feeling too good about the fact that I'm motoring along
very-nicely-thank-you with my project using an optimizing compiler I got for
free while you spent a 4-figure sum on your MS equivalent, but were hoping
that as comuppance you'd watch me run into problems of Borland's compiler
not being able to compile Windows code half as good, then I'm sorry but your
delusions have been shattered - because it can do it just as well.

Sorry!

"a.m.a" <am*********@videotron.ca> wrote in message
news:N6*********************@wagner.videotron.net. ..
Now that we know that you are going through all that trouble because
you use Borland. I just wanted to remind you that posting questions about
windowing code done in Borland in a VC news group is probably not
the most efficient way of doing things. That said, i have never used Borland but something tellsme that over the long years since Borland has been
around,
im sure that somebody , somewhere has written code to wrap win32 windows
and that it would make more sense to base your work on solid ground
rather then re-inventing the wheel and risk running into a world of problems and hoping that this news group, wich isnt specialised in Borland will be
solve all those issues.

Im only suggesting all that to save you some time though.

cya

Nov 17 '05 #7
Now that we know that you are going through all that trouble because
you use Borland. I just wanted to remind you that posting questions about
windowing code done in Borland in a VC news group is probably not
the most efficient way of doing things. That said, i have never used Borland
but something tellsme that over the long years since Borland has been
around,
im sure that somebody , somewhere has written code to wrap win32 windows
and that it would make more sense to base your work on solid ground
rather then re-inventing the wheel and risk running into a world of problems
and hoping that this news group, wich isnt specialised in Borland will be
solve all those issues.

Im only suggesting all that to save you some time though.

cya

Nov 17 '05 #8
How do you *know* that, with regards to this specific problem? Guessing
generically more like.
You're wrong in that I'm going through this trouble because I use Borland.
It compiles fine with either Borland or VC7.0.
Using the .NET 2002 compiler gave exactly the same error before I fixed the
bug, which I now have, and gave no more information as to the cause of the
error than bcc32 and td32 did.

You're right in that somebody has written code to wrap a Win32 window, the
designers of MFC for one. Which is what I may end up using, if I was writing
applications in a commercial environment. However, this particular project
is more of a hobbyist thing, so I want to design it the way I want, with
just the features I want and not the ones I don't. I want to be able to
genericise all the various portions of utility code and algorithms needed in
both my actual application, and any utility tools I write and use to aid me
in creating it, archive them for possible future use, and then specialise
them as required - as opposed to having to shoehorn my wishlist into
something like MFC. Not that MFC's bad - it's just I've got the "want it
just-so" bug with this particular project, and I want to construct all the
parts myself just to see how it's done if nothing else / in the rare case
that someone else has invent the exact wheel I'm trying to craft.

In terms of posting to these newsgroups - without sounding patronising, many
have tried to see me off before and failed (I'm still here) so I don't see
how you think you can sunshine. If you are genuinely suggesting for my own
benefit and there really is a free, high-volume, on-topic newsgroup that's
more specific to Borland development that'll work with OE, then I'll admit I
don't know about it and I apologise, and would appreciate if you would point
me to the news server name. But even then I'll be more likely to use it in
addition to this one rather than instead of.

Incidentally my reason for using Borland is that I simply don't trust
Microsoft tools any more, since reinstalling their SDK doesn't produce a
windows.h file, and many others. Reinstalling windows hasn't fixed this
problem, so there must be something up with the way the complex web of .msi
files works. Consequently, I can't trust it - and besides, they don't give
an optimizing compiler for free.

However, none of my questions are specific to Borland products in any way,
and are just as relevant to Microsoft development, and since I have GOT
Microsoft VS.NET, including VC7.0, and since my project compiles OK with
that aswell as Borland, as far as you're concerned my questions might as
well be about developing with Microsoft Visual C++ - as if you answered it
as if that was the case, I would be perfectly capable of interpreting the
result - not that any interpretation has thus far been required, nor can I
foresee any being required.

If you're not feeling too good about the fact that I'm motoring along
very-nicely-thank-you with my project using an optimizing compiler I got for
free while you spent a 4-figure sum on your MS equivalent, but were hoping
that as comuppance you'd watch me run into problems of Borland's compiler
not being able to compile Windows code half as good, then I'm sorry but your
delusions have been shattered - because it can do it just as well.

Sorry!

"a.m.a" <am*********@videotron.ca> wrote in message
news:N6*********************@wagner.videotron.net. ..
Now that we know that you are going through all that trouble because
you use Borland. I just wanted to remind you that posting questions about
windowing code done in Borland in a VC news group is probably not
the most efficient way of doing things. That said, i have never used Borland but something tellsme that over the long years since Borland has been
around,
im sure that somebody , somewhere has written code to wrap win32 windows
and that it would make more sense to base your work on solid ground
rather then re-inventing the wheel and risk running into a world of problems and hoping that this news group, wich isnt specialised in Borland will be
solve all those issues.

Im only suggesting all that to save you some time though.

cya

Nov 17 '05 #9
Instead of calling "Create" in the constructor, you need to do it in a
separate initialization function, so that the object can be completely
constructed. Otherwise, you are falling victim to "object slicing".

Here's some links:
http://www.ezdefinition.com/eng/cata...p/430/430.html
http://www-h.eng.cam.ac.uk/help/tpl/...+/tic0159.html
http://groups.google.com/groups?hl=e...AA70%40sun.com
http://groups.google.com/groups?hl=e...8B%40corel.com
Also, note that you might want to use ATL/WTL, or look at how this is
done there (it does something similar, but doesn't use SetWindowLong
although it could).

-Daniel
Bonj wrote:
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

this is in window1.h (the base class)

#ifndef WINDOW1CLASS_DEFINED

#define WINDOW1CLASS_DEFINED

class Window1

{

public:

//variables:

HWND hWnd;

HCURSOR hcWait, hcArrow;

BOOL bWaiting;
//methods:

void Create( HINSTANCE hInst,

HICON hIcon,

HICON hIconSm,

HBRUSH hbrBackground,

LPCTSTR lpszCaption,

int nClassStyle,

int nWindowStyle);

static LRESULT CALLBACK WPHandler(

HWND hWnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam);

virtual LRESULT WndProc(HWND hWnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam) = 0;

virtual int ShowModally(int nCmdShow) = 0;

//constructor/destructor:

Window1() : hWnd(NULL) {};

virtual ~Window1() {};

Window1( HINSTANCE hInst,

HICON hIcon,

HICON hIconSm,

HBRUSH hbrBackground,

LPCTSTR lpszCaption,

int nClassStyle,

int nWindowStyle);

};

#endif

//this is in Window1.cpp

//======================================

#include "Generics.h"

#include "Window1.h"

Window1::Window1( HINSTANCE hInst,

HICON hIcon,

HICON hIconSm,

HBRUSH hbrBackground,

LPCTSTR lpszCaption,

int nClassStyle,

int nWindowStyle)

{

Create(hInst, hIcon, hIconSm, hbrBackground,

lpszCaption, nClassStyle, nWindowStyle);

}

LRESULT CALLBACK Window1::WPHandler( HWND hWnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam)

{

if(uMsg == WM_NCCREATE)

{

LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;

SetWindowLong(hWnd, GWL_USERDATA, (long)lpcs->lpCreateParams);

}

Window1* pThis = (Window1*)(LPVOID)(::GetWindowLong(hWnd, GWL_USERDATA));

//Window1* pThis = (Window1*)(GetWindowLong(hWnd, GWL_USERDATA));

if(pThis) return pThis->WndProc(hWnd, uMsg, wParam, lParam);

else return DefWindowProc(hWnd, uMsg, wParam, lParam);

}

void Window1::Create(HINSTANCE hInst,

HICON hIcon,

HICON hIconSm,

HBRUSH hbrBackground,

LPCTSTR lpszCaption,

int nClassStyle,

int nWindowStyle)

{

bWaiting = FALSE;

WNDCLASSEX wcx;

memset(&wcx, 0, sizeof(WNDCLASSEX));

wcx.cbSize = sizeof(WNDCLASSEX);

wcx.style = nClassStyle;

wcx.lpfnWndProc = Window1::WPHandler;

wcx.hInstance = hInst;

wcx.hIcon = NULL;

wcx.hCursor = NULL;

wcx.hbrBackground = hbrBackground;

wcx.lpszMenuName = NULL;

wcx.lpszClassName = lpszCaption;

wcx.hIconSm = NULL;

hcWait = (HCURSOR)LoadImage( NULL,

IDC_ARROW,

IMAGE_CURSOR,

CW_USEDEFAULT,

CW_USEDEFAULT,

LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED);

hcArrow = (HCURSOR)LoadImage( NULL,

IDC_WAIT,

IMAGE_CURSOR,

CW_USEDEFAULT,

CW_USEDEFAULT,

LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED);

ATOM ClassName = RegisterClassEx(&wcx);

hWnd = CreateWindow( (LPCTSTR)ClassName,

lpszCaption,

nWindowStyle,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

(HWND)NULL,

(HMENU)NULL,

(HINSTANCE)hInst,

(LPVOID)this);

}


//and the base class is defined as such (settingsdlg.h)

#include "Window1.h"

class SettingsDlg : public Window1

{

public:

//constructor/destructor:

SettingsDlg( HINSTANCE hInst,

HICON hIcon,

HICON hIconSm,

HBRUSH hbrBackground,

LPCTSTR lpszCaption,

int nClassStyle,

int nWindowStyle) :

Window1( hInst,

hIcon,

hIconSm,

hbrBackground,

lpszCaption,

nClassStyle,

nWindowStyle) {};

//SettingsDlg() {};

//~SettingsDlg() {};
LRESULT WndProc(HWND hWnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam);

int ShowModally(int nCmdShow);

};

//(settingsdlg.cpp)

#include "Generics.h"

#include "settingsdlg.h"

int SettingsDlg::ShowModally(int nCmdShow)

{

{

if(hWnd)

{

ShowWindow(hWnd, nCmdShow);

UpdateWindow(hWnd);

}

else

return -1;

}
{

MSG msg;

while(GetMessage(&msg, hWnd, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return (int)msg.wParam;

}

}



LRESULT SettingsDlg::WndProc( HWND hWnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam)

{

switch(uMsg)

{

case WM_MOUSEMOVE:

{

SetCursor((bWaiting) ? (hcWait) : (hcArrow));

return 0;

}

/*

case WM_CLOSE:

{

PostMessage(hWnd, WM_QUIT, 0, 0);

return 0;

}

*/

}

return DefWindowProc(hWnd, uMsg, wParam, lParam);

}

//and my winmain cpp file looks like this:

#include "Generics.h"

#include "SettingsDlg.h"

int WINAPI WinMain( HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpszCmdLine,

int nCmdShow

)

{

HICON hIcon = (HICON)LoadImage( hInstance,

MAKEINTRESOURCE(IDI_TRANS),

IMAGE_ICON,

GetSystemMetrics(SM_CXICON),

GetSystemMetrics(SM_CYICON),

LR_DEFAULTCOLOR | LR_SHARED),

hIconSm = (HICON)LoadImage( hInstance,

MAKEINTRESOURCE(IDI_TRANS),

IMAGE_ICON,

GetSystemMetrics(SM_CXSMICON),

GetSystemMetrics(SM_CYSMICON),

LR_DEFAULTCOLOR | LR_SHARED);
SettingsDlg sdlg( hInstance,

hIcon,

hIconSm,

(HBRUSH)(COLOR_3DFACE + 1),

"SpaceMaze settings",

CS_OWNDC | CS_HREDRAW | CS_VREDRAW,

WS_OVERLAPPEDWINDOW);

return sdlg.ShowModally(SW_SHOWMAXIMIZED);

}



Thanks ever so much to anybody that can help me out of this !


Nov 17 '05 #10
a.m.a <am*********@videotron.ca> wrote:
[...] That said, i have never used Borland
but something tellsme that over the long years since Borland has been
around,
im sure that somebody , somewhere has written code to wrap win32 windows
It's called VCL (aka Visual Component Lib)
and it makes creating C++ GUI apps as easy
as using VB. Unfortunately, they seem to be
dropping the C++ support for it. (It's a
Delphi lib.)
[...]
cya


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Nov 17 '05 #11
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:Oj***************@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" <vo**@trolltech.com> wrote in message
news:uw****************@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:uO****************@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



Nov 17 '05 #12
If you were considering MFC for a window wrapper, i would suggest
the ATL classes instead. that way you dont have to bundle MFC.dll .

ATL window classes are also open source.
classes like CWindowImpl defined in <atlwin.h>

As far as windows.h goes, Re-installing Windows has nothing to do with the
SDK.
And we still dont know where this SDK you describe comes from.
The one from Microsoft.com ?

PS: i am realy just trying to help.

Nov 17 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: D. Alvarado | last post by:
Hello, Just wanted to check if this was possible. I have n blocks of text and I would like each to pop up in a window. Hoever, I don't want to create n different HTML pages and invoke each one...
4
by: Altramagnus | last post by:
I have 30 - 40 type of different window. For each type I need about 20 instances of the window. When I try to create them, I get "Error creating window handle" My guess is there is a maximum...
1
by: stellabein | last post by:
Hi friends, I am very very new to programing. i have a one main window from that window i am opening one modal window using showmodaldialog(m.jp...). in that modal window i have a form. when i...
2
by: Enrique Bustamante | last post by:
Casting arrays that works on watch and command window but not in code. My application is casting arrays in a way it should work. To test if I was doing something invalid, I wrote a test code that...
1
by: tony | last post by:
Hello! Assume I have three window forms called Frm1, Frm2 and Frm3 each of these have a method called foo1 and foo2. Now instead of having this foo1 and foo2 in each of the three window forms...
11
by: gg9h0st | last post by:
i saw a code refactorying onload event listener window.onloadListeners=new Array(); window.addOnLoadListener=function(listener) { window.onloadListeners=listener; } why declare the...
5
by: Tom Gur | last post by:
Hi, I was wondering how do I get control over a window (Win32). to be more specific, I need to find a handle to a window of a certain program and minimize the window.
2
by: wreed06 | last post by:
Hello, I have 2 problems. In my webpage, I have a dropdown list with a button that takes the user to a popup window specific to the option. I am using Firefox 2.0.0.13. I have successfully...
1
by: soms2m | last post by:
HELLO ALL, I want to fill the parent window height with respect to the sub window height which is loading using ajax (mootools). For example if the parent window height is normal and the loading...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.