Functionpointer

Hi,
Ich habe eine Klasse geschrieben die Windowsmessages an bestimmte Funktionen weiterleiten soll, ähnlich wie es bei der MFC gemacht wird.

class Window
{
 public:
 typedef long (Window::\*MH) (HWND, long, long);
 typedef std::map MessageMap;
 typedef MessageMap::iterator MessageIterator;

 Window(HINSTANCE hInstance);
 ~Window();

 // Interface for the user
 HWND CreateWnd(char\* name, long flags);
 void RegisterMessageHandler(long message, MH handler);
 bool HandleMessages();
 long GetExitCode();

 // WM\_Close and WM\_Destroy are by default handled internaly 
 long OnClose(HWND hwnd, long param0, long param1);
 long OnDestroy(HWND hwnd, long param0, long param1);

 // Callback
 long DeliverMessage(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
 static LRESULT CALLBACK MsgRouter(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);

 private:
 HINSTANCE m\_hInstance;
 HWND m\_hwnd;

 MessageMap m\_MsgHandlers;

 long ExitCode;
};

Jedes Fenster hat eine eigene Klasse die von Window abgeleitet ist und alle anfallenden Messages verarbeitet.

class MainDialog : public Window
{
 MainDialog();
 ~MainDialog();

 OnCreate(HWND hwnd, long param0, long param1);
}


MainDialog::MainDialog() : Window(GetModuleHandle(0))
{
 long (Window::\*ptr)(HWND, long, long);
 ptr = &MainDialog::open\_mouth:nCreate;
 RegisterMessageHandler(WM\_CREATE, ptr);

 CreateWnd("window", WS\_OVERLAPPEDWINDOW|WS\_VISIBLE);
}

MainDialog::~MainDialog()
{
}

long MainDialog::open\_mouth:nCreate(HWND hwnd, long param0, long param1)
{
 MessageBox(hwnd, "OnCreate", "WM\_CREATE was successfully delivered", MB\_OK);
}

Die Fensterklasse MainDialog muss ihre Messagehandler (=OnCreate(…)) im Konstruktor bei der Windowklasse registieren.

long (Window::\*ptr)(HWND, long, long);
ptr = &MainDialog::open\_mouth:nCreate; // 
Was muss ich machen damit der Compiler meinen Pointer auf eine MainDialog Methode als Pointer auf eine Window Methode akzeptiert. Das sollte doch eigentlich kein Problem sein, da MainDialog ja von Window abgeleitet ist - oder doch ?

Grüße,
Daniel Raffler

ptr = &MainDialog::open_mouth:nCreate; //

Ohne &

ptr = &MainDialog::open_mouth:nCreate; //

Ohne &

Hi Nicos,
mein Code würde funktionieren wenn OnCreate() eine Methode von Window wäre und nicht von MainDialog. Ich glaube deshalb nicht dass es am & liegt - werde es aber sicherheitshalber mal probieren.

Grüße,
Daniel Raffler

Hallo,

nebenbei würde mich interessieren, wie man eine solche Funktion, die du über

long (Window::\*ptr)(HWND, long, long);
ptr = MainDialog::open\_mouth:nCreate;

definiert hast aufruft. Ich habe es mit ptr() versucht, aber der Compiler meckert, daß der Ausdruck keine Funktion sei. Auch (*ptr)() ging nicht.

Schöne Grüße,

Daniel.

Hallo,

nebenbei würde mich interessieren, wie man eine solche
Funktion, die du über

long (Window::*ptr)(HWND, long, long);
ptr = MainDialog::open_mouth:nCreate;

definiert hast aufruft. Ich habe es mit ptr()
versucht, aber der Compiler meckert, daß der Ausdruck keine
Funktion sei. Auch (*ptr)() ging nicht.

Mit ptr allein geht das nicht. ptr weist zwar auf die Funktion (die gibt es ja nur einmal im Speicher), nicht aber auf die Daten (also der this-Zeiger).

Beispiel:

class Foo {
 void bar(int);
};

typedef (Foo::\*Methode)(int);

void callback( Foo\* \_this, Methode \_method, int param )
{
 (this-\>\*\_method)( \_param );
}

Diese Art des Aufrufes, also direkt mit this-Zeiger und Methode, findet man recht selten. Viel üblicher ist da der Header um Zusammenhang mit
dem Header :

std::vector myVec;
// ... vector mit Elementen füllen
// und and die Klasse Foo weiterleiten:

Foo myFoo;
std::for\_each(
 myVec.begin(),
 myVec.end(),
 std::bind1st( std::mem\_fun( &Foo::bar ), &myFoo)
);

=> für jedes Element x im Container rufe die Methode myFoo.bar(x) auf

Gruß Markus

1 Like

Hallo Wortfuchs,

danke für die rasche Antwort. Die erste Variante is genau diejenige, die ich suche, da nur Methoden der aktuellen Klasse aufgerufen werden sollen, mir also der this-Zeiger ausreicht.

Schöne Grüße,

Daniel.