Problems with WindowProcedure

I

Ikke

Hi everybody,

I have a problem with the callback WndProc. Based on a setting, I'm
trying to start one of two windows. Basically, what I'm trying to do is
the following:

- main.cpp is my main source file, and is the one which contains int
WINAPI WinMain.
- inside WinMain, I decide which class to instantiate (A or B)
- both classes should create a window, handle the messages for the
window, and call further/other stuff

The problem is that I cannot add WindowProcedure as a function inside
class A (nor B). If I do so, I get the following messages:

error C3867: 'A::WindowProcedure': function call missing argument list;
use '&A::WindowProcedure' to create a pointer to member
error C2440: '=' : cannot convert from 'LRESULT (__stdcall A::* )
(HWND,UINT,WPARAM,LPARAM)' to 'WNDPROC'

On the internet, I've found a few solutions to solve this - the first one
was to make the function static. This works perfectly, the code compiles,
but of course I cannot call any class functions from within a static
function, so this is a bit useless for me.

The second solution was to define the function call as before, but
change:
winClass.lpfnWndProc = WindowProcedure;
to
winClass.lpfnWndProc = (WNDPROC) WindowProcedure;

However, this doesn't compile at all: the message I'm getting now is:
error C2440: 'type cast' : cannot convert from 'overloaded-function' to
'WNDPROC'

My question now is, of course, how can I make this WindowProcedure
function part of a class?

There's another solution (I guess), that is to keep the classes as they
are, and keep the WindowProcedure in main.cpp, and pass a pointer to the
function to the class. However, I've only just begun learning C++, and I
have no idea how to do this.

Can anybody please help me out here?

Thanks in advance!

Ikke
 
T

Thomas J. Gritzan

Ikke said:
Hi everybody,

I have a problem with the callback WndProc. Based on a setting, I'm
trying to start one of two windows. Basically, what I'm trying to do is
the following:
[...specifying a member function as WindowProc...]

In general, your problem is to specify a class member function as
callback from a C library.
The short answer is: You cannot do that.

The long answer is: You can specify a non-member function (formally, it
must be specified as extern "C"), and let the non-member function call
the member function. But you have to somehow bring the "this" pointer, a
pointer to the class' instance, into this stub function. Some callback
mechanisms let you pass a context argument (a void*, mostly) that will
be forwarded to your stub function, but that won't work with WindowProcs.

The details on how to get this context/instance pointer into the stub
function is beyond the topic of this newsgroup which handles C++
language issues only. So you should ask in a Windows newsgroup. Some
suggestions are in the FAQ:
http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.9
 
P

Paul N

Hi everybody,

I have a problem with the callback WndProc. Based on a setting, I'm
trying to start one of two windows. Basically, what I'm trying to do is
the following:

- main.cpp is my main source file, and is the one which contains int
WINAPI WinMain.
- inside WinMain, I decide which class to instantiate (A or B)
- both classes should create a window, handle the messages for the
window, and call further/other stuff

The problem is that I cannot add WindowProcedure as a function inside
class A (nor B). If I do so, I get the following messages:

  error C3867: 'A::WindowProcedure': function call missing argument list;
use '&A::WindowProcedure' to create a pointer to member
  error C2440: '=' : cannot convert from 'LRESULT (__stdcall A::* )
(HWND,UINT,WPARAM,LPARAM)' to 'WNDPROC'

On the internet, I've found a few solutions to solve this - the first one
was to make the function static. This works perfectly, the code compiles,
but of course I cannot call any class functions from within a static
function, so this is a bit useless for me.

The second solution was to define the function call as before, but
change:
  winClass.lpfnWndProc = WindowProcedure;
to
  winClass.lpfnWndProc = (WNDPROC) WindowProcedure;

However, this doesn't compile at all: the message I'm getting now is:
  error C2440: 'type cast' : cannot convert from 'overloaded-function' to
'WNDPROC'

My question now is, of course, how can I make this WindowProcedure
function part of a class?

There's another solution (I guess), that is to keep the classes as they
are, and keep the WindowProcedure in main.cpp, and pass a pointer to the
function to the class. However, I've only just begun learning C++, and I
have no idea how to do this.

You might get better answers if you post on comp.os.ms-
windows.programmer.win32, which deals with programming Windows.
However, part of the problem is to do with C++ itself, so I'll have a
go at answering it here.

If you want to call a member function (other than a static one), you
need to specify an object to apply it to. For instance:

anobject -> runfunction();

The point of the WndProc function is that it gets called by Windows.
But Windows isn't expecting a member function, and there is no way (as
far as I know) to tell Windows which object you are interested in even
if you could persuade it to use a member function.

As far as I can tell, you only have one object. One possible way might
be to use a global to store its value, and a wrapper function -
something like:

class Base { public: LRESULT handle(args...); stuff here.... };

class One : public Base { stuff here... };

class Two : public Base { stuff here... };

Base *Theobject;

LRESULT wrapper(args...) {
Theobject -> handle(args...);
}

.... in WinMain ...
winClass.lpfnWndProc = wrapper;
if(something) Theobject = new One; else Theobject = new Two;


I think that will work, if you fill in the gaps correctly.

Hope that helps.
Paul.
 
B

Balog Pal

Ikke said:
The problem is that I cannot add WindowProcedure as a function inside
class A (nor B). If I do so, I get the following messages:

error C3867: 'A::WindowProcedure': function call missing argument list;
use '&A::WindowProcedure' to create a pointer to member
error C2440: '=' : cannot convert from 'LRESULT (__stdcall A::* )
(HWND,UINT,WPARAM,LPARAM)' to 'WNDPROC'

On the internet, I've found a few solutions to solve this - the first one
was to make the function static. This works perfectly, the code compiles,
but of course I cannot call any class functions from within a static
function, so this is a bit useless for me.

Naturally. (nonstatic) Member function has one extra hidden argument thet
carries the value for 'this'. So any kind of nonstatic member function is
not fit as WNDPROC. You must create a free or static-member function to
pass, and inside it possibly forward to a member function.

To do that you must smuggle that 'this' pointer somehow. One way is to put
it in the extra window-class or window-instance data. At registering the
window class you can ask for extra spece, and manupilate it with some api
(SetWindowLong ?).

So your free function registered as wndproc can use the HWND to retrieve the
info for type and/or instance, and call what is needed to call with the rest
of args.

A likely better way is to forget this whole Petzold-level stuff and use a
C++ windowing library (MFC, ATL, etc...) that does that for you and much
more, so you can just write the meat of your program isntead of recreating a
broken wheel.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,159
Messages
2,570,879
Members
47,414
Latest member
GayleWedel

Latest Threads

Top