WM_SIZE wird vor WM_CREATE aufgerufen?
-
Ich verfolge die Tutorials hier: http://www.relisoft.com/win32/generic.html
Das Programm soll nach dem MVC - Prinzip funktionieren.
In dem Beispiel werden controller und auch model und view im WndProc im WM_CREATE generiert.
Ich würde gerne ganz früher im Programm diese Objekte erstellen. Deshalb dachte ich mir die LPARAM-Methode zu benutzen. Leider scheint WM_CREATE nicht die erste Message sein, denn WM_SIZE funzt nicht korrekt.template <class T> inline T get_data(HWND hwnd, int what = GWL_USERDATA) { return reinterpret_cast<T> (GetWindowLong (hwnd, what)); } template <class T> inline void set_data(HWND hwnd, T value, int what = GWL_USERDATA) { SetWindowLong(hwnd, what, reinterpret_cast<long> (value)); } void save_controller(HWND h, LPARAM p) { CREATESTRUCT* pcs = reinterpret_cast<CREATESTRUCT*>(p); void* d = pcs->lpCreateParams; controller* pc = reinterpret_cast<controller*>(d); pc->set_hwnd(h); set_data(h, pc); } LRESULT CALLBACK wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { controller* pc = get_data<controller*>(hwnd); switch (msg) { case WM_CREATE: save_controller(hwnd, lparam); return 0; case WM_SIZE: // hier ist pc nicht gültig!? return 0; case WM_DESTROY: set_data<controller*>(hwnd, 0); delete pc; return 0; } return DefWindowProc(hwnd, msg, wparam, lparam); }
-
wie wärs mit static ...
schirrmie
-
static sollte keinen großen Einfluß dabei haben. Wenn WM_CREATE erstens aufgerufen wird, wird den controller-Zeiger vom lparam entnommen und direkt in die Fensterstruktur mittels set_data gespeichert. Dann sollte alles ok sein, oder denke ich falsch?
-
yop WM_CREATE muss ned die erste Message sein, die ein Fenster bekommt.
-
Hmm. Eine Ahnung wie man das überwinden kann?
-
Zdravko schrieb:
static sollte keinen großen Einfluß dabei haben. Wenn WM_CREATE erstens aufgerufen wird, wird den controller-Zeiger vom lparam entnommen und direkt in die Fensterstruktur mittels set_data gespeichert. Dann sollte alles ok sein, oder denke ich falsch?
Also so wie ich das sehe schon wieso probierst du es nicht einfach mal aus

-
WM_SIZE und WM_GETMINMAXINFO werden zum Teil vor WM_CREATE gesendet.
Ignoriere einfach alle Nachrichten bei denen Dein Datenzeige noch NULL ist und leite sie an DefWindowProc weiter. Alles vor WM_CREATE ist erstmal uninteressant für Dich!
In WM_CREATE wird der Datenzeiger ja gesetzt. Später wird WM_SIZE noch einmal gesendet...
-
Martin Richter, vielen Dank!
-
Nee, das funzt wieder nicht.
Es scheint zu sein, dass:controller* pc = get_data<controller*>(hwnd);nicht 0 zurückgibt. Kann man es im Voraus auf 0 setzen?
-
Kann nicht sein:
Siehe Doku zu GetWindowLong:
If the function succeeds, the return value is the requested 32-bit value.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
If SetWindowLong has not been called previously, GetWindowLong returns zero for values in the extra window or class memory.
-
Kann es sein, dass die WNDCLASS Struktur oder CreateWindow nicht korrekt initializiert werden?
wc_.cbClsExtra = 0; wc_.cbWndExtra = 0;hwnd_ = CreateWindow( classname_, windowname_, style_, x_, y_, w_, h_, hparent_, hmenu_, hInstance, new controller());
-
Hat damit nichts zu tun.
1. Dein Fenster wir dja erzegt, Du bekommst ja Nachrichten.
2. GWL_USERDATA ist immer vorhanden.Laut Doku: Selbst wenn es einen Fehler gibt müsstest Du NULL bekommen!
-
Kann das Problem sein, dass die controller Methoden virtual sind?
-
Also das Problem ist irgendwo hier:
case WM_SIZE: if (pc) pc->resize(0, 0); return 0;Die Fehlermeldung ist:
First-chance exception at 0x00000000 in generic2.exe: 0xC0000005: Access violation reading location 0x00000000.
Unhandled exception at 0x00000000 in generic2.exe: 0xC0000005: Access violation reading location 0x00000000.Das Objekt controller sieht so aus:
class controller { HWND hwnd_; public: controller(); virtual ~controller(); virtual void command(UINT what) {} virtual void resize(int new_x, int new_y) {} virtual void paint() {} void set_hwnd(HWND h) { hwnd_ = h; } controller::controller() :hwnd_(0) { } controller::~controller() { PostQuitMessage(0); }
-
Zeig mal wie Du Dein Fenster erzeugst!
-
Zdravko schrieb:
hwnd_ = CreateWindow( classname_, windowname_, style_, x_, y_, w_, h_, hparent_, hmenu_, hInstance, new controller());Reicht das, oder soll ich das ganzes hier posten?
Das Fenster wird richtig gezeigt. Aber gleichzeitig kriege ich diese seltsame Fehlermeldung...
-
Also so kann ich jetzt auf Anhieb kein Problem sehen.
Wird denn der Zeiger korrekt gesetzt? Hast Du Den Wert nach WM_CREATE mal geprüft, as Du eingetragen hast?
Hast Du ein kleines Demo, das Du mir senden kannst?
-
Ich habe das ganze Projekt neu rebuilt und auf ein mal ist alles ok gegangen!
Vielen Dank!