How you handle this?

N

Ne

The first question is about coding a callback on Windows. In a class of
callback function, the function has to be static. Now the problem is that
from within this function, no non-static members can be accessed or invoked.
Seems like the only way is to change all the members to static.

I'd like to hear your opinions on such change.

Second question is generally how to implement callback in C++.

Thank you very much!
 
J

John Harrison

Ne said:
The first question is about coding a callback on Windows. In a class of
callback function, the function has to be static. Now the problem is that
from within this function, no non-static members can be accessed or invoked.
Seems like the only way is to change all the members to static.

Not at all.
I'd like to hear your opinions on such change.

It would kind of defeat the object of having a class if you made all the
functions static. You might as well have a bunch of global functions and
variables.

Here's how you should do it, this only works of the callback accepting
function is well designed. Fortunately in Windows most of them are.

I'll illustrate with the Windows API call EnumWindows, but this technique is
widely applicable.

The EnumWindows function requires a callback of the form

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);

This is what you must supply (although the name is up to you obviously), it
cannot be a member function, strictly speaking in cannot even be a static
member function although many compilers accept this. Suppose you want to
callback a method called addWindow in a WindowList class. Here's what you do

class WindowList
{
bool addWindow(HWND win);
};

BOOL CALLBACK EnumWindowsGlue(HWND hwnd, LPARAM lParam)
{
return reinterpret_cast<WindowList*>(lParam)->addWindow(hwnd);
};

WindowList myWindowList;
EnumWindows(EnumWindowsGlue, reinterprest_cast<LPARAM>(&myWindowList));

The way you pass the object you want to call a method on as a parameter to
EnumWindows and the way that parameter is recieved by the callback function
is the trick. The callback function is just a 'glue' that lets you attach
the member function to the EnumWindows routine.

Most Windows APIs have similar features, usually the extra parameter is
defined as LPVOID which is a bit more portable and means you only need one
static_cast instead of two reinterpret_cast's. (For the benefit of
non-Windows users, LPARAM is typedef'd as long, and LPVOID is typedef'd as
void*.

john
 
G

Gregg

The first question is about coding a callback on Windows. In a class
of callback function, the function has to be static. Now the problem
is that from within this function, no non-static members can be
accessed or invoked. Seems like the only way is to change all the
members to static.

You have to arrange to store the pointer to the object somewhere and
invoke the non-static function from the static function using that saved
pointer. If the callback function has a general-purpose argument, you can
use that to pass the object pointer.

For specific Windows callback functions, ask in a group that deals with
the Windows API. This group deals literally with the C++ langauge and
standard library.
Second question is generally how to implement callback in C++.

In C++ a callback is usually a call to a member function through a
pointer to a base class with one or more virtual functions (usually
pure). You implement a specific callback function in the derived class.

Gregg
 
G

Guest

The first question is about coding a callback on Windows. In a class of
callback function, the function has to be static. Now the problem is that
from within this function, no non-static members can be accessed or invoked.
Seems like the only way is to change all the members to static.

I'd like to hear your opinions on such change.

Second question is generally how to implement callback in C++.

I dont know the prototype of your callback
Many times, callbacks has user defined parameters in their parameter list
(or inside a structure parameter)
If your callback has, pass "this" with cast
(many times user defined parameters are void*)
 
K

Kevin Goodsell

John said:
Well it isn't really, its the usual newbie question about using a member
function in a routine that only accepts a pointer to a free function.

Hm... Well, I took his word for it. Perhaps that was a mistake.

-Kevin
 

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

No members online now.

Forum statistics

Threads
474,164
Messages
2,570,898
Members
47,439
Latest member
shasuze

Latest Threads

Top