Zugriffsverletzung während WndProc
-
Hallo,
ich bin etwas unschlüssig über den Namen des Themas, da ich mir über den Fehler nicht ganz im klaren bin.
Ich hoffe jemand kann mir weiterhelfen mein Problem zu lösen.Ich bekomme folgende Fehlermeldung:
Unbehandelte Ausnahme bei 0x009E19FA in XXX.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00000058
Der Fehler tritt beim ShowWindow auf, liegt allerdings nicht an dieser einen Funktion, da er z.B. bei DestroyWindow derselbe ist.
Hier möchte ich erreichen, das durch den Klick auf ein Button der andere ausgeblendet oder zerstört wird.
Hier die WndProcs, eine Static für die Übergabe in der WndClassEx.LRESULT CALLBACK Main_Wnd::WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ){ switch( msg ){ case WM_COMMAND: switch( wParam ){ case ID_BUTTON_OPT: ShowWindow( hButtonProjects, SW_HIDE ); break; case ID_BUTTON_PROJECTS: ShowWindow( hButtonOptions, SW_HIDE ); break; } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc( hWnd, msg, wParam, lParam ); } } LRESULT CALLBACK Main_Wnd::StaticWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ){ Main_Wnd* pMain_Wnd; if( msg == WM_CREATE ){ pMain_Wnd = (Main_Wnd*) ( ((LPCREATESTRUCT)lParam)->lpCreateParams ); SetWindowLongPtr( hWnd, GWL_USERDATA, (LONG_PTR) pMain_Wnd ); } else{ pMain_Wnd = (Main_Wnd*) GetWindowLongPtr( hWnd, GWL_USERDATA ); } return pMain_Wnd->WndProc( hWnd, msg, wParam, lParam ); }
Die Buttons sind in einer Funktion der gleichen Klasse definiert.
bool Main_Wnd::CreateStartScreen(){ hButtonOptions = CreateWindow( "button", "Einstellungen", WS_CHILD | WS_VISIBLE, 50, 50, 100, 25, hMainWnd, ( HMENU ) ID_BUTTON_OPT, hInstButtons, NULL ); hButtonProjects = CreateWindow( "button", "Projekte", WS_CHILD | WS_VISIBLE, 50, 90, 100, 25, hMainWnd, ( HMENU ) ID_BUTTON_PROJECTS, hInstButtons, NULL ); return true; }
Die MessageLoop:
while( true ){ if( MainWndStart.key_handle() ){ break; } }
unsigned char Main_Wnd::key_handle(){ if( PeekMessage( &msg, NULL, NULL, NULL, PM_REMOVE ) ){ if( msg.message == WM_QUIT ){ return true; } TranslateMessage( &msg ); DispatchMessage( &msg ); } return 0; }
Falls noch unklar ist, wie ich mein Programm aufgebaut habe, kann ich natürlich noch nachliefern. Allgemein ist bis jetzt alles in die Main_Wnd - Klasse eingegliedert, nach bestem Wissen und gewissen nach dem OOP Konzept.
Ich hoffe ihr könnt mir weiterhelfen.
Viele Dank für eure Hilfe schon im Voraus.Grüße
-
...
-
CreateWindow bei deinem Hauptfenster benötigt als letzten Parameter this.
Außerdem würde ich noch in deiner StaticWndProc WM_GETMINMAXINFO abfragen und DefWindowProc zurückgeben.
-
Swordfish: Ich denke daran liegt es nicht grundsätzlich, aber ich nehme trotzdem noch ein if Überprüfung rein
Floorball: Der letzte Parameter der CreateWindow meines Hauptfensters stand wirklich auf NULL. Geändert, und siehe da es funktioniert.
Vielen Dank für die schnelle Info; das das this in der CreateWindow benötigt wird, war mir nicht klar.
Das WM_GETMINMAXINFO hab ich nachgeschaut und mit aufgenommen, auch wenn ich das ändern der Fenstergröße zurzeit deaktiviert habe.Danke euch beiden + Grüße
Kleiner Falke
-
Das abfragen von WM_GETMINMAXINFO hat den Sinn, dass es die erste Nachricht ist die ein Fenster bekommen kann. Das heißt, wenn dein Fenster erstellt wird, und dann deine staticWndProc WM_GETMINMAXINFO bekommt, dann wird dir GetWindowLongPtr nichts vernünftiges zurückgeben. Wenn du dann versuchst in deiner WndProc auf ein Attribut deiner Klasse zuzugreifen bekommst du wieder einen Fehler.
-
floorball schrieb:
Das abfragen von WM_GETMINMAXINFO hat den Sinn, dass es die erste Nachricht ist die ein Fenster bekommen kann
Ich denke nicht. WM_CREATE wird ja noch direkt in der CreateWindow-Funktion gesendet in nicht der Messagequeue hinzugefügt. Anders wäre es auch nicht möglich, CreateWindow mit Rückgabe von -1 als Reaktion auf WM_CREATE scheitern, d.h. ein Nullhandle zurückliefern zu lassen.
KleinerFalke schrieb:
das das this in der CreateWindow benötigt wird, war mir nicht klar.
Du brauchst das, da
pMain_Wnd = (Main_Wnd*) ( ((LPCREATESTRUCT)lParam)->lpCreateParams );
lpCreateParams in der CREATESTRUCT genau das enthält, was als LPARAM bei CreateWindow(Ex) übergeben wurde.
-
Je nachdem wie das Fenster erstellt wird werden noch ganz andere Messages vor WM_CREATE an die WndProc gesendet. Es ist nur sicher, dass das WndProc WM_NCCREATE und WM_CREATE erhält.
Weiter unten schreibt zwar jemand das bei CreateWindow WM_CREATE die erste Nachricht ist, ich habe allerdings eher die selbe Erfahrungen wie der Fragende gemacht.