WinApi Fenster Ausgabe stoppt bei Window Events



  • Hallo,
    Hoffe der Titel ist selbsterklärend, aber wahrscheinlich bedarf es doch einer Erklärung.

    Ich bin von der Konsolenausgabe hin zu einem "echten" Fenster, was im Nachhinein viel kürzer und unproblematischer ist. Was ich an Arbeit in diese Konsolenausgabe gesteckt habe, ich hoffe ich habe wenigstens Erfahrung gewonnen.

    Der Umstieg ging auch wunderbar und ist wie schon geschrieben deutlich einfacher als vorher. Nun ist es aber so, wenn ich mit der Maus das Fenster bewege, das dann die Ausgabe stoppt. Die Berechnungen gehen weiter, nur die Ausgabe stoppt.

    Nun gibt es mehrere Möglichkeiten, wann die Ausgabe beginnt. Zum einen in der

    static LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
    {
    	switch (msg)
    	{
    	case WM_CLOSE:
    	{
    		PostQuitMessage(0);
    		break;
    	}
    	default:
    		return DefWindowProc(hwnd, msg, wparam, lparam);
    	}
    	return 0;
    }
    

    Da kann man dann einen BEGIN_PAINT einfügen, aber wie ich das in die Graphic Engine übertragen soll? Als virtuelle Funktion?

    Dann gibt es den Standard:

    bool zp::DotEngine::onWindowEvents()
    {
      MSG msg = {};
      while (PeekMessage(&msg, nullptr, 0u, 0u, PM_REMOVE))
      {
      	if (msg.message == WM_QUIT)
      		return false;
    
      	TranslateMessage(&msg);
      	DispatchMessage(&msg);
      }
      return true;
    }
    

    So mache ich das. Nur das dann die Fensterausgabe stoppt.

    Meine gesamte MainLoop sieht so aus:

    void zp::DotEngine::mainLoop()
    {
    	// prepare timing
    	auto timePointA = std::chrono::system_clock::now();
    	auto timePointB = std::chrono::system_clock::now();
    
    	while (Running)
    	{
    		// handle timing
    		timePointB = std::chrono::system_clock::now();
    		std::chrono::duration<float> duration = timePointB - timePointA;
    		timePointA = timePointB;
    		FrameDeltaTime = duration.count();
    
    		// handle key & mouse input
    		if (!onMainInput())
    		{
    			Running = false;
    		}
    
    		// handle frame update
    		if (!onMainUpdate())
    		{
    			Running = false;
    		}
    
    		// handle window events
    		if (!onWindowEvents())
    		{
    			Running = false;
    		}
    
    		updateWindow();
                    // in dieser geerbten Methode sind dann
                    // InvalidateRect(Renderer->windowHandle(), NULL, FALSE);
                    // UpdateWindow(Renderer->windowHandle());
    
    		if (ShowConsole)
    			printWindowInfo();
    	}
    }
    

    Hat da jemand einen Plan, wie ich überhaupt meine Frage korrekt formulieren kann? Außerdem habe ich das Gefühl, das meine Ausgabe zu langsam ist. Es sind bei leerem Fenster um die 1000 fps. Müssten das nicht mehrere Tausend sein?

    Vielen Dank fürs Lesen und verzeiht die Ausdrucksfehler.

    (Und wenn es was kritikwürdiges gibt, keine Angst, das habe ich hinter mir 😉 )



  • Laut einem Microsoft-Forenbeitrag soll man während der Behandlung der Nachricht WM_PAINT das Fensterrechteck per InvalidateRect ungültig machen und ein Neuzeichnen anstossen. Dann soll das Neuzeichnen auch während der Fensterbewegung funktionieren.

    Edit:
    Was passiert, wenn du einen Handler für WM_WINDOWPOSCHANGINGergänzt und darin das Fenster per RedrawWindow sofort neu zeichnest?

    Edit2:
    Ansatz 1) führt dazu, dass dein Fenster ständig neu gezeichnet wird, musst dann mal schauen, welche Auswirkungen das hat. Vielleicht kann man da noch auf ein Mouse Down oder sowas prüfen, um das einzuschränken.



  • Huh, danke für die Antwort, ich müsste mich tatsächlich erst über diese Methoden / Anweisungen klug machen, aber ich habe einen neuen Ansatz bekommen.

    War nämlich etwas ratlos, weil in vielen anderen Antworten sollte schon

    InvalidateRect(Renderer->windowHandle(), NULL, FALSE);
    UpdateWindow(Renderer->windowHandle());
    

    reichen.

    Also vielen Dank schonmal, ich habe ein neues Ziel zum suchen 😉

    Zum Glück beeinträchtigt mich das nicht, weiterhin meine Engine zu benutzen, die läuft eigentlich wirklich gut. Denn wann ist es schon relevant, das die Ausgabe bei Mausklick auf die Titelbar stoppt? Das bisschen Fenterbewegen macht man ein- zwei Mal. Und auch wenn nur wegen der Darstellung. Trotzdem wäre es besser, dies zu lösen.

    Viele Grüße


Anmelden zum Antworten