WndProc in Klasse... again >.<
-
Hai,
hab eine Klasse, die auch mit 2 WndProcs arbeitet - einen statischen und einen member-WndProc. funktioniert auch wunderbar.... fast. und zwar passieren äußerst merkwürdige dinge - z.B werden die Variablen, die im WndProc() verändert werden, nach dem verlassen des WndProc()s einfach wieder auf den Zustand zuvor zurückgesetzt... oder man kriegt komische Zugriffsverletzungsfehler... Irgendjemand einen Tipp?achso, noch 2 links, erstmal der thread wo ich die einbindung des WndProcs in die klasse gelernt hatte:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-174421.html
und ein konkretes problem mit ner MultimediaKlasse (auf basis von directShow):
http://www.c-plusplus.net/forum/viewtopic-var-t-is-176363.html
-
ok, die klasse klappt, ich hab grad was anderes versucht:
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { static int Volume = 0; static MMMUSIC *mmm = NULL; switch(msg) { case WM_CREATE: mmm = (MMMUSIC*) lParam; break; case WM_CHAR: switch(wParam) { case '+': if(Volume < 0) Volume+= 100; mmm->SetVolume(Volume); break; case '-': if(Volume > -10000) Volume-= 100; mmm->SetVolume(Volume); break; default: break; } break; case WM_DESTROY: PostQuitMessage(0); break; default: break; } return DefWindowProc(hWnd, msg, wParam, lParam); }bei CreateWindow wird ein zeiger auf eine MMMUSIC instanz übergeben, dieser wird bei WM_CREATE in dem statischen Zeiger gespeichert. scheint ja alles ok zu sein. Jedoch wird mir der Zugriff auf die memberfunktionen verwehrt. die Funktionen funktionieren, hab sie (mit einer globalen Instanz) getestet... Ich verstehe nicht, was falsch ist.
Achso: beim debuggen hab ich gesehen, dass der Zeiger gültig ist, und mit dem Zeiger in der WinMain übereinstimmt.
-
hmmmm... darf ich bittebitte antwort haben?^^
-
Was meinst Du mit "Zugriff verwehrt" ?
-
http://xcpp.de/ressources/cpp/zv.jpg
das^^"
verstehe auch nicht, wie er auf 0x000000fc kommt...Weiß auch ganz sicher, dass die Klasse klappt - hatte sie schon mal im WndProc instanziert, dann klappt das. Im kleinen Pseudo-programm hier kann ich das ja machen, nur nicht im projekt^^".
-
Ich glaub, er würfelt alle Daten von mmm durcheinander - so sieht mmm zum selben Zeitpunkt aus, wenn alles klappt (Im WndProc Instanziert)
http://xcpp.de/ressources/cpp/richtig.jpgBringt mich aber kein stück weiter

-
Hmm, die WndProc wird auch nur von einem Fenster verwendet?
-
in diesem Programm gibts nur ein fenster...
oder soll ich bei Peekmessage/GetMessage das hWnd mit angeben?
klappt aber auch so nicht
-
Die zv.jpg zeigt, dass der Zeiger mmm nicht inititialisiert ist.
Prüf mal, ob sich der Kompiler einen Scherz erlaubt hat :// hier einen Breakpoint und kontrollieren // ob bei jeder Message der Zeiger auf NULL gesetzt wird static MMMUSIC *mmm = NULL;Ich kann es mir zwar nicht vorstellen, aber wer weiss...
Danach prüf mal ob es läuft wenn die lokale Variable mmm global ist.
-
beobachtung: bei WM_CREATE wird alles richtig zugewiesen, in den nächsten 2 Durchläufen (die jeweils beim DefWindowProc() enden, stimmt alles, beim dritten wird der Zeiger auf irgendeinen wert gesetzt
hab das auch so versucht:
static MMMUSIC *mmm = NULL/* = new MMMUSIC*/; if(mmm) mmm = (MMMUSIC*) ((LPCREATESTRUCT)GetWindowLong(hWnd, 0))->lpCreateParams; switch(msg) { case WM_CREATE: SetWindowLong(hWnd, 0,(LONG) lParam); mmm = (MMMUSIC*) ((LPCREATESTRUCT)GetWindowLong(hWnd, 0))->lpCreateParams; mmm->InitDirectShow(); break;hat aber auch keine wirkung (wcex.cbWndExtra = 4; natürlich)
EDIT: bei weiteren durchläufen ändert sich der zeiger ab und zu auch noch paar mal, mal 0x0000000f mal 0xfeeefeee mal sonst irgendwas...
Ich versteh ganix mehr
-
Azrael, il Meraz schrieb:
beim dritten wird der Zeiger auf irgendeinen wert gesetzt
Das ist der Schlüsselsatz. Also nicht NULL sondern "irgendwas/wo".
Probier mal so :... case WM_CREATE: SetWindowLong(hWnd, 0,(LONG) lParam); // setzt voraus, dass lParam *mmm ist // mmm = (MMMUSIC*) ((LPCREATESTRUCT)GetWindowLong(hWnd, 0))->lpCreateParams; mmm = (MMMUSIC*) GetWindowLong(hWnd, 0); mmm->InitDirectShow(); break; ...
-
so kommt er garnicht dazu, einen richtigen Zeiger zu bekommen - der is dann schon von anfang an verwirrt. bei WM_CREATE wird schon irgendein schrott zugewiesen...
hmmm... weiß nicht warum, aber nun wird der Zeiger zwar nicht verändert, aber die daten der instanz werden überschrieben.. (also mit createstruct jetzt)
EDIT: hab ma die ganze sache geuppt ( da hatte ich noch ne kranke lösung ausprobiert xD):
http://xcpp.de/ressources/cpp/MulMed.rar
-
Das Set/GetWindowLong () und die CREATESTRUCT brauchst Du nur, wenn die WndProc in einer Klasse ist.
Allerdings ist sie das nicht. Deshalb reicht folgendes :// so übergeben : INT WINAPI WinMain (...) { ... MMMUSIC *mmm = new (MMMUSIC); ... CreateWindowEx (...,mmm); ... delete (mmm); ... } // so initialisieren : LRESULT WINAPI WndProc(...) { ... static MMMUSIC *mmm = 0; ... case WM_CREATE : { mmm = (MMMUSIC *) lParam; mmm -> InitDirectShow(); break; } ... }
-
ne - geht auch nicht
hab ausprobiert. aber eigentlich will ich das ja auch den WndProc in die klasse tun, hier ist halt nur ein anderes Beispiel. Ich vertseh überhauptnicht, wie das nicht klappen kann...
-
hmmm - ich hab mir jetzt ne eigene Message definiert, damit geht das Oo
#define WM_MMMCR WM_USER ... hWnd = CreateWindowEx(...); SendMessage(hWnd, WM_MMMCR, NULL, (LONG) mmm); .... case WM_MMMCR: mmm = (MMMUSIC*) lParam; mmm->InitDirectShow(); break; ...total krank, ich glaub, ich fass die WM_CREATE net mehr an...
mal schaun, ob das auch mit SetWindowLong klappt und den member-wndproc...
-
Such lieber eine geeignete Stelle, wo "mmm->InitDirectShow()" aufgerufen wird.
Vielleicht gleich nach CreateWindowEx () in der WinMain :// hier rein : WinMain (...) ... CreateWindowEx (...,mmm); mmm -> InitDirectShow(); ... // hier raus : WndProc (...) ... case WM_CREATE : { mmm = (MMMUSIC *) lParam; // mmm -> InitDirectShow(); break; } ...
-
ne - klappt nicht - der zeiger ist wieder verwirrt...
Ist die Lösung mit eigener Nachricht irgendwie schlechter Stil?
-
merker schrieb:
case WM_CREATE: mmm = (MMMUSIC *)lParam; break;Win32 Programmer's Reference schrieb:
WM_CREATE
lParam
Value of lParam. Points to a CREATESTRUCT structure that contains information about the window being created.
Ich hab das Problem in C auch mal gehabt...
-
Ahhh, Dank an "keksekekse" für den Hinweis

Funktioniert folgendes Casting :
WinProc (...) ... case WM_CREATE : { // mmm = (MMMUSIC *) lParam; mmm = (MMUSIC *) ((LPCREATESTRUCT) lParam) -> lpCreateParams; mmm -> InitDirectShow(); break; }P.S.: Eigene Nachrichten sind kein schlechter Stil.
-
ne - immer noch verwirrter zeiger.
Was spricht dann gegen ne eigene Nachricht?