LRESULT CALLBACK in Klasse

Jacal

Mitglied
Hallo,

Ich möchte in meiner Klasse einem bzw. mehreren Window-Handles eine Callback-Funktion zuweißen.

Dazu folgender Klassenentwurf:
Code:
class Dialog
{
      private:
          HWND  &hwndMain ;
          HWND    hwndFunc ;
          LRESULT CALLBACK    FuncProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
          WNDPROC             *wndprocFunc ;
     public:
          Dialog (HWND&) ;
};

// ********* Konstruktor ********** //
Dialog::Dialog (HWND &hwnd) : hwndMain(hwnd)
{
   hwndFunc   =   CreateWindow ("button", "Func", WS_CHILD, 10, 30, 70, 25, hwndMain,
                                 NULL, (HINSTANCE)GetWindowLong(hwndMain, GWL_HINSTANCE), NULL);

   wndprocFunc  = (WNDPROC) SetWindowLong (hwndFunc, GWL_WNDPROC, (LONG) FuncProc);
}

// *******   Callback Funktionen   ******* //
LRESULT CALLBACK   Dialog::FuncProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
       if ((lParam == (LPARAM)hwndFunc) && (HIWORD(wParam) == BN_CLICKED))
            MessageBox (NULL, "Sie haben soeben den Button 'Func' gedrückt!", "Dialog::FuncProc", MB_ICONINFORMATION | MB_OK);
    }

    return (CallWindowProc (wndprocFunc, hwnd, message, wParam, lParam));
}

Nun gibt es allerdings das Problem, dass sich der Compiler beim zuweisen der Callbackfunktion (Dialog::Dialog - SetWindowLong (...)) beschwert:
error: aggregate value used where an integer was expected|

Jetzt habe ich herausgefunden, dass es die Möglichkeit gäbe, die Callbackfunktion als Statisch zu deklarieren.

Code:
class Dialog
{
      private:
            [...]
            static LRESULT CALLBACK    FuncProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

      [...]
};

Die funktioniert auch, nur habe ich nun keine Berechtigung mehr, auf die Eigenschaften der Klasse zuzugreifen.

Gibt es dennoch eine Möglichkeit, die Callbackfunktion so in die Klasse zu integrieren, dass darüber noch auf alle Eigenschaften und Methoden zugreifen kann?

Mit freundlichen Grüßen,
Jacal
 
Hallo,

Die funktioniert auch, nur habe ich nun keine Berechtigung mehr, auf die Eigenschaften der Klasse zuzugreifen.

Gibt es dennoch eine Möglichkeit, die Callbackfunktion so in die Klasse zu integrieren, dass darüber noch auf alle Eigenschaften und Methoden zugreifen kann?
Du musst die Methode als statisch deklarieren, daran führt kein Weg vorbei. In dieser statischen Methode könntest du dir allerdings einen Zeiger auf die passende Instanz deiner Klasse besorgen eine entsprechende nicht-statische Methode dieser Instanz aufrufen. Eine Möglichkeit dies umzusetzen bestände darin, den Zeiger über SetWindowLong(hwnd, GWL_USERDATA, this) zu setzen und in der statischen Methode entsprechend über GetWindowLong(hwnd, GWL_USERDATA) wieder auszulesen.

Grüße, Matthias
 
Hallo,


Du musst die Methode als statisch deklarieren, daran führt kein Weg vorbei. In dieser statischen Methode könntest du dir allerdings einen Zeiger auf die passende Instanz deiner Klasse besorgen eine entsprechende nicht-statische Methode dieser Instanz aufrufen. Eine Möglichkeit dies umzusetzen bestände darin, den Zeiger über SetWindowLong(hwnd, GWL_USERDATA, this) zu setzen und in der statischen Methode entsprechend über GetWindowLong(hwnd, GWL_USERDATA) wieder auszulesen.

Grüße, Matthias
Das funktioniert leider nicht so wie gewollt:

Code:
SetWindowLong (hwndFunc, GWL_USERDATA,(LONG) this);
Hier musste ich, damit es überhaupt geht, this (also die Klasse) in den Typ LONG umwadeln?


Im weiteren:
Code:
LRESULT CALLBACK   Dialog::FuncProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    GetWindowLong(hwnd, GWL_USERDATA);
    this->hwndFunc;
};

Hier tritt ein Fehler beim Zugriff auf hwndFunc auf:
error: `this' is unavailable for static member functions|


Grüße :)
 
Das funktioniert leider nicht so wie gewollt:

Code:
SetWindowLong (hwndFunc, GWL_USERDATA,(LONG) this);
Hier musste ich, damit es überhaupt geht, this (also die Klasse) in den Typ LONG umwadeln?
Ja, das hatte ich nicht bedacht. Sollte aber kein Problem darstellen.

Im weiteren:
Code:
LRESULT CALLBACK   Dialog::FuncProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    GetWindowLong(hwnd, GWL_USERDATA);
    this->hwndFunc;
};

Hier tritt ein Fehler beim Zugriff auf hwndFunc auf:
In statischen Methoden kann man nicht auf this zugreifen, da es keine zugeordnete Instanz gibt. Außerdem verwirfst du das Ergebnis des Aufrufes von GetWindowLong einfach. Du solltest es stattdessen nach Dialog * casten und dann über diesen Zeiger auf die Instanz deiner Klasse zugreifen.

Grüße, Matthias
 
In statischen Methoden kann man nicht auf this zugreifen, da es keine zugeordnete Instanz gibt. Außerdem verwirfst du das Ergebnis des Aufrufes von GetWindowLong einfach. Du solltest es stattdessen nach Dialog * casten und dann über diesen Zeiger auf die Instanz deiner Klasse zugreifen.

Grüße, Matthias

Vielen Dank, das funktioniert :)

Allerdings habe ich jetzt noch ein neues Problem: Das Programm stürzt nämlich beim Ausführen der folgenden Zeile ab:

Code:
wndprocFunc  = (WNDPROC) SetWindowLong (hwndFunc, GWL_WNDPROC, (LONG) FuncProc);

Kennt jemand das Problem?

Jacal.


Edit:
Es scheint doch nicht (oder nur indirekt) an dieser Zeile zu liegen.
Die Callback-Funktion wird auf jeden fall noch aufgerufen, trotzdem stürzt das Programm ab.

Edit:
Ok, hat sich geklärt.
 
Zuletzt bearbeitet:
Zurück