WndProc in Klasse, ShowWindow stürzt ab



  • Wenn ich folgenden Code ausführe, blitzt kurz das Fenster auf, danach wird das Programm beendet.

    Anhand der Ausgabe habe ich herausgefunden das ShowWindow abstürzt, allerdings warum?

    Nachricht: 1 (WM_CREATE)
    Vor ShowWindow
    Nachricht: 24 (WM_SHOWWINDOW)
    Nachricht: 70 (WM_WINDOWPOSCHANGING)
    

    Die betreffenden Teile im Code der Fenster Klasse sehen so aus:

    class Window
    {
    private:
    	HDC deviceContext_;
    	HWND windowHandle_;
    	HINSTANCE windowInstance_;
    
    public:
    	// ...
    
    	static LRESULT CALLBACK CallbackProxy(HWND, unsigned int, WPARAM, LPARAM);
    	LRESULT Callback(HWND, unsigned int, WPARAM, LPARAM);
    };
    
    LRESULT CALLBACK Window::CallbackProxy(HWND windowHandle, unsigned int message, WPARAM wParam, LPARAM lParam)
    {
    	Window *instance = (Window*)GetWindowLong(windowHandle, GWL_USERDATA);
    
    	if (message == WM_CREATE)
    	{
    		instance = (Window*)((CREATESTRUCT*)lParam)->lpCreateParams;
    		SetWindowLong(windowHandle, GWL_USERDATA, (long) instance);
    	}
    
    	if (instance == 0)
    	{
    		return DefWindowProc(windowHandle, message, wParam, lParam);
    	}
    
    	return instance->Callback(windowHandle, message, wParam, lParam);
    }
    
    LRESULT Window::Callback(HWND windowHandle, unsigned int message, WPARAM wParam, LPARAM lParam)
    {
    	cerr << "Nachricht:" << message << endl;
    
    	// ...
    }
    
    windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    windowClass.lpfnWndProc = (WNDPROC) Window::CallbackProxy;
    windowClass.cbClsExtra = 0;
    windowClass.cbWndExtra = 0;
    windowClass.hInstance = windowInstance_;
    windowClass.hIcon = LoadIcon(0, IDI_WINLOGO);
    windowClass.hCursor = LoadCursor(0, IDC_ARROW);
    windowClass.hbrBackground = 0;
    windowClass.lpszMenuName = 0;
    windowClass.lpszClassName = "testklasse";
    
    windowRect.left = posX_;
    windowRect.top = posY_;
    windowRect.right = width_;
    windowRect.bottom = height_;
    
    AdjustWindowRectEx(&windowRect, WS_OVERLAPPEDWINDOW, false, WS_EX_APPWINDOW);
    
    windowHandle_ = CreateWindowEx(WS_EX_APPWINDOW, "testklasse", "Test Fenster",
    		WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW,
    		windowRect.left, windowRect.top,
    		windowRect.right - windowRect.left,
    		windowRect.bottom - windowRect.top,
    		0, 0, windowInstance_, this);
    
    cerr << "Vor ShowWindow" << endl;
    ShowWindow(windowHandle_, SW_SHOW);
    cerr << "Nach ShowWindow" << endl;
    


  • Was sagt denn der Debugger ?! 🙄



  • Debugger ist keiner vorhanden weil ich das Visual C++ 2003 Toolkit verwende 😉



  • Dann lad Dir doch einen runter:
    Microsoft Debugging Tools for Windows



  • nehme nicht CREATESTRUCT für den this Pointer, ich hatte damit auch Probleme, ich hatte das so (unelegant) gelöst, in dem ich den this wert als string in classname schrieb und in der WndProc ausgelesen und zu einem long wert rückgewandelt hatte, hatte auch den Vorteil das ich immer andere classnamen hatte bei mehren Fenstern.

    char szClassname[24];
    sprintf(szClassname,"%i",long(this));
    //...
    RegisterClassEx(...
    //...in WndProc ...
    long Pointer;
    char t[24];
    GetClassName(hwnd,t,24);
    sscanf(t,"%i",&Pointer);
    //...etc.
    

    für Controls kannste den this bei Menu speichern, da es da nicht benutzt wird.



  • MiC++ha schrieb:

    nehme nicht CREATESTRUCT für den this Pointer, ich hatte damit auch Probleme, ich hatte das so (unelegant) gelöst, in dem ich den this wert als string in classname schrieb und in der WndProc ausgelesen und zu einem long wert rückgewandelt hatte, hatte auch den Vorteil das ich immer andere classnamen hatte bei mehren Fenstern.

    auch ein übeler häck 😃

    was spricht eigentlich dagegen nach dem erstellen des fensters
    den this pointer an das fenster du binden (SetWindowLong(..))
    und in der statischen wndproc einfach sich wieder den pointer holen.
    habe schon öfter diese art der lösung gesehen und benutze sie auch selber.

    [offtopic]
    wieder reg. fertig mit deinem projekt?



  • miller_m schrieb:

    was spricht eigentlich dagegen nach dem erstellen des fensters
    den this pointer an das fenster du binden (SetWindowLong(..))
    und in der statischen wndproc einfach sich wieder den pointer holen.
    habe schon öfter diese art der lösung gesehen und benutze sie auch selber.

    Es spricht dagegen, wenn man WM_CREATE bearbeitet, den das wird gesendet bei CreateWindow..., und da ist noch kein Zeiger in GWL_USERDATA 😉

    Er benutzt USERDATA ja auch, aber erst nach dem das Fenster erstellt ist, bis dahin verwendet er CREATESTRUCT und das ist nichts gut.

    <OT> Jo, ich bin fertig, zum glück </OT>



  • MiC++ha schrieb:

    Es spricht dagegen, wenn man WM_CREATE bearbeitet, den das wird gesendet bei CreateWindow..., und da ist noch kein Zeiger in GWL_USERDATA 😉

    schon klar, deswegen returne ich wm_create einfach und erstelle die childs (unüberlicher weise) an anderer stelle.



  • MiC++ha schrieb:

    nehme nicht CREATESTRUCT für den this Pointer, ich hatte damit auch Probleme

    Schwachsinn, warum sollte das nicht gehen, da hast du nen Fehler gemacht.

    Bei .Callback wird der Zeiger ausserdem richtig gesetzt, sonst würde er doch nicht die beiden Nachrichten anzeigen, sondern schon vorher abstürtzen.

    @.Callback: Zeig doch mal deine ganze Window::Callback Methode, da müsste der Fehler sein.



  • LRESULT Window::Callback(HWND windowHandle, unsigned int message, WPARAM wParam, LPARAM lParam)
    {
    	switch (message)
    	{
    	case WM_ACTIVATE:
    		if (!HIWORD(wParam))
    		{
    			active_ = true;
    		}
    		else
    		{
    			active_ = false;
    		}
    
    		return 0;
    
    	case WM_KEYDOWN:
    	case WM_CLOSE:
    		PostQuitMessage(0);
    		return 0;
    	}
    
    	return DefWindowProc(windowHandle, message, wParam, lParam);
    }
    


  • D@niel $chumann schrieb:

    MiC++ha schrieb:

    nehme nicht CREATESTRUCT für den this Pointer, ich hatte damit auch Probleme

    Schwachsinn, warum sollte das nicht gehen, da hast du nen Fehler gemacht.

    Bei .Callback wird der Zeiger ausserdem richtig gesetzt, sonst würde er doch nicht die beiden Nachrichten anzeigen, sondern schon vorher abstürtzen.

    Ich hatte nicht gesagt das es nicht geht, ich sagte das Probleme auftauchten


Anmelden zum Antworten