By defining them in different processes. Why would you
like different functions for the class? Instead, after
creating a window using the class you can modify it's
wndproc pointer to your liking (called subclassing).
- Sten
Use a static member function.
'But the compiler won't let me access this!' You need to stash the pointer
to the particular object (aka this) somewhere that you can retrieve it
later.
Or save yourself time and effort and use ATL's CWindow class.
For example: (there are other ways to do this, but this is simple, and
sufficient for most cases)
HWND Window::Create()
{
HWND hwnd = CreateWindow(..., this);
if (hwnd == NULL)
return NULL;
assert(hwnd == m_hWnd);
return hwnd;
}
/*static*/ LRESULT Window::WndProc(HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam)
{
Window *This;
if (msg == WM_NCCREATE)
{
CREATESTRUCT *cs = (CREATESTRUCT*) lParam;
This = cs->lpCreateParams;
SetProp(hwnd, "WindowInstancePointer", (HANDLE) This);
This->m_hWnd = hwnd;
}
else
This = (Window*) GetProp(hwnd, "WindowInstancePointer");
if (This == NULL)
{
// This can happen for messages such as WM_GETMINMAXINFO
// which are received before WM_NCCREATE.
// If you want to handle these properly, you'll need some other
// way of communicating 'this' to Window::WndProc
return DefWindowProc(hwnd, msg, wParam, lParam);
}
else
return This->WndProc(msg, wParam, lParam);
}
/*virtual*/ LRESULT Window::WndProc(UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
/* ... */
}
return DefWindowProc(m_hWnd, msg, wParam, lParam);
}
--
Tim Robinson (MVP, Windows SDK)
http://mobius.sourceforge.net/
If you see the post I made just previous to this one - you will see what my
problem is.
Could you give me a pointer or two to look up in MSDN to get sublcalssing
working?
Thanks
Allan
I cant have a static member function - see me previous post to see my
problem.
>
> 'But the compiler won't let me access this!' You need to stash the pointer
> to the particular object (aka this) somewhere that you can retrieve it
> later.
>
> Or save yourself time and effort and use ATL's CWindow class.
even though I`m using C++, I am just using the basic win32 C calls, i.e.
RegisterClassEx(), CreateWindowEx(). Do you know of a solution using this
method?
Thanks
Allan
From your other post:
>>> but the global gCW appears to be static so this doesnt work.
Read my last post in some more detail...
You can! Because:
> > 'But the compiler won't let me access this!' You need to stash the
pointer
> > to the particular object (aka this) somewhere that you can retrieve it
> > later.
In other words, the static function needs to find out for which window
the call is and forward it to the approriate class:
static LRESULT ChatWindow::WndProc_ (HWNd h, ...)
{
ChatWindow* cw = from_hwnd (h);
cw->WndProc (h, ...);
}
WndProc_ is static (and yes, you *can* use this) and forwards the call
to the correct non-static member function. This is pretty much what Tim
said.
hth
--
jb
(replace y with x if you want to reply by e-mail)
what does the assert() do?
> return hwnd;
> }
>
>
> /*static*/ LRESULT Window::WndProc(HWND hwnd, UINT msg, WPARAM wParam,
> LPARAM lParam)
> {
> Window *This;
>
> if (msg == WM_NCCREATE)
> {
> CREATESTRUCT *cs = (CREATESTRUCT*) lParam;
> This = cs->lpCreateParams;
> SetProp(hwnd, "WindowInstancePointer", (HANDLE) This);
> This->m_hWnd = hwnd;
> }
> else
> This = (Window*) GetProp(hwnd, "WindowInstancePointer");
>
> if (This == NULL)
> {
> // This can happen for messages such as WM_GETMINMAXINFO
> // which are received before WM_NCCREATE.
> // If you want to handle these properly, you'll need some other
> // way of communicating 'this' to Window::WndProc
> return DefWindowProc(hwnd, msg, wParam, lParam);
> }
> else
> return This->WndProc(msg, wParam, lParam);
> }
>
>
> /*virtual*/ LRESULT Window::WndProc(UINT msg, WPARAM wParam, LPARAM
lParam)
why does this need to be virtual?
Thanks
Allan
I have read it and almost understand what you are doing. I replied to it
again.
Thanks
Allan
An assert is a way of documenting an assumption in a program's logic. If
that assumption is violated, you see a big message at run time.
For example:
int i = 3;
assert(i == 3);
i++;
assert(i == 4);
Assert statements are generally only compiled into debug builds, the
assumption being that any bug which results in an assert being fired would
have been discovered in a debug build, and that you don't want a release
build popping up messages saying that the program's broken.
[...]
>> /*virtual*/ LRESULT Window::WndProc(UINT msg, WPARAM wParam, LPARAM
>> lParam)
>
> why does this need to be virtual?
So that subclasses of the Window class can handle their own messages.
Window::WndProc would contain default processing which is shared by all
classes that derive from Window -- probably just a call to DefWindowProc.
You could implement a MyCrazyButton class, derived from Window, which
overrides WndProc. In there you might want to handle WM_PAINT,
WM_LBUTTONDOWN, etc. If Window::WndProc(UINT,WPARAM,LPARAM) was not virtual
then the static Window::WndProc(HWND,UINT,WPARAM,LPARAM) (note: two
functions with the same name but different parameters) would only ever call
Window's implementation of the function.
Thanks Tim,
It is all working now.
Allan
Just FYI, there's a discussion of this issue that I have found very
useful here:
http://www.rpi.edu/~pudeyo/articles/wndproc/index.html
-- Pete
> > Use a static member function.
>
> I cant have a static member function - see me previous post to
> see my problem.
Tim is 100% correct. To do what you require WILL need to make
the member function static.
> > 'But the compiler won't let me access this!'
There is a reason for this, no pung intended :)
Consider the following simple class:
class example {
void dynamic_member(void);
static void static_member(void);
};
In the case of the dynamic_member() function what the compiler
is actually compiling is not the obvious:
void dynamic_member(void)
{
}
but instead it is coding something closer to the following:
void dynamic_member(example *this);
{
}
where it adds a hidden 'this' pointer.
In the case of the static_member() what you see is what you
get so in fact:
void static_member(void)
{
}
is coded exactly as expected.
But this explains why the compiler will generate a 'this'
error message for static functions.
> even though I`m using C++, I am just using the basic win32 C
> calls, i.e. RegisterClassEx(), CreateWindowEx(). Do you know
> of a solution using this method?
The problem has nothing to do with Win32 and everything todo
with how the c++ compiler handles static and non-static member
functions. The end result is for the code to compiler the
member function MUST be static.
Jussi Jumppanen
Author of: Zeus for Windows (All new version 3.92 out now)
"The C/C++, Cobol, Java, HTML, Python, PHP, Perl programmer's editor"
Home Page: http://www.zeusedit.com