WINAPI Klasse, Vererbung Problem
-
Ich glaube die Parameter in CreateWindowEx() solltest Du schon selber einsetzen. Ich kenne Dein Programm ja auch nicht so gut. Für den letzten Parameter (LPVOID lpParam // pointer to window-creation data) jedenfalls musst Du
this
eintragen (zumindest solange der Aufruf innerhalb einer Klassenfunktion erfolgt).Deine CreateWindowEx() sieht sonst ja auch nicht schlecht aus, so weit ich sehen kann.
In meiner eigenen Window Klasse habe ich das CreateWindowEx in einer eigenen Funktion Create(). Du scheinst die ganze Fenster-Erstellung in den Konstruktor der FRM_CLASS unterbringen zu wollen. Ich weiss im Augenblick keinen Grund warum das nicht gehen soll, aber dass Du auch noch den Messageloop im Constructor hast, wird auf die Dauer wohl zu Problemen führen. Der Constructor der abgeleiteten Klasse wird dann erst aufgerufen, wenn das Programm praktisch schon zu Ende ist.
NB:
Bist Du sicher, dass Du hInstance initialisiert hast? Kann nichts finden.
-
Das Problem ist die "Windows Procedure"-Funktion:
int WINAPI FRM_CLASS::WindowsProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { if ( uMsg == WM_CREATE ) SetWindowLong( hWnd, GWL_USERDATA, lParam); FRM_CLASS *wnd = (FRM_CLASS*)GetWindowLong(hWnd, GWL_USERDATA); return wnd->WndProc(hWnd, uMsg, wParam, lParam); }Wenn du der CreateWindowEx-Funktion den this-Zeiger als lParam übergibst, erwartest du, dass die Funktion zu allererst eine WM_CREATE Nachricht an die WindowsProc-Funktion sendet. Es ist aber so, dass CreateWindowEx noch andere Nachrichten an die Procedure-Funktion sendet bevor es die WM_CREATE Nachricht versendet. Daher erhält der Zeiger "wnd" einige male den Wert NULL, weil SetWindowLong erst aufgerufen wird wenn die WM_CREATE Nachricht erhalten wird, und das passiert erst ein wenig später.
Lösung: Du nimmst eine Dummy-Procedure-Funktion her, die einfach nur DefWindowProc aufruft. Du gibst diese bereits im WNDCLASS struct an:
wc.lpfnWndProc = WndProc_DUMMY; // wird später ersetzt
Wenn die CreateWindowEx-Funktion zurückkehrt machst du folgendes:
CreateWindowEx(...); // hier brauchst du kein "this" angeben
SetWindowLong(hwnd, GWL_USERDATA, (LONG)this); //"this"-pointer speichern
SetWindowLong(hwnd, GWL_WNDPROC, (LONG)FRM_CLASS::WindowsProc); //richtige procedure-funktion einstellenUnd so sollten die Funktionen aussehen:
LRESULT WndProc_DUMMY(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { return DefWindowProc(hWnd, 0, uMsg, wParam, lParam); } LRESULT WINAPI FRM_CLASS::WindowsProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { static FRM_CLASS *wnd = NULL; wnd = (FRM_CLASS*)GetWindowLong(hWnd, GWL_USERDATA); return wnd->WndProc(hWnd, uMsg, wParam, lParam); }