Problem mit Minimieren
-
Hi,
ich habe mit dem folgenden Code das folgende Problem: Der Code ist so geschrieben, dass die Anwendung GetMessage() verwendet, wenn das Fenster minimiert ist oder nicht den Fokus hat (Rechenzeit sparen), aber ansonsten PeekMessage() (weils eine 3D-Anwendung ist, die rendern soll).
Das klappt auch recht gut, nur wenn ich das Programm minimiere und dann wieder mit einem Klick in der Taskleiste öffnen will, bleibt der ganze PC hängen bzw. wird wirklich extrem gebremst (WinAMP gibt nur alle paar Sekunden einen Ton von sich usw.)
Aber ich find den Fehler einfach nicht.LRESULT CALLBACK CWindow::WindowProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) { // Bevor einer was sagt: Ich bin mir bewusst, dass GetWindowLong() nur "weißes Rauschen" // zurückgibt und der This-Zeiger in pWindowClass->HandleMessage() ungültig ist! // (ist aber egal, weil m_bFinished und m_bHasFocus noch statisch sind!) CWindow *pWindowClass = (CWindow*)GetWindowLong(hWnd, GWL_WNDPROC); return pWindowClass->HandleMessage(hWnd, Message, wParam, lParam); } CWindow::CWindow(HINSTANCE hInstance, const CEngineString &strTitel) { ENGINE_LOG("Creating window...\n") // Anwendungsklasse erstellen WNDCLASSEX WinClass; WinClass.cbSize = sizeof(WNDCLASSEX); WinClass.style = CS_HREDRAW | CS_VREDRAW; WinClass.lpfnWndProc = WindowProc; WinClass.cbClsExtra = 0; WinClass.cbWndExtra = 0; WinClass.hInstance = hInstance; WinClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WinClass.hCursor = LoadCursor(NULL, IDC_ARROW); WinClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); WinClass.lpszMenuName = NULL; WinClass.lpszClassName = strTitel.pchGetCharString(); WinClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if (!RegisterClassEx(&WinClass)) ENGINEERROR("RegisterClassEx failed!") m_hWnd = CreateWindowEx(NULL, strTitel.pchGetCharString(), strTitel.pchGetCharString(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 400, 300, NULL, NULL, hInstance, NULL); if (!m_hWnd) ENGINEERROR("CreateWindowEx failed!") } void CWindow::ProcessMessages() { MSG Message; if (m_bHasFocus) { while (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&Message); DispatchMessage(&Message); } } else { while (GetMessage(&Message, NULL, 0, 0) && !m_bHasFocus) { TranslateMessage(&Message); DispatchMessage(&Message); } } } LRESULT CWindow::HandleMessage(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) { switch (Message) { case WM_DESTROY: m_bFinished = true; PostQuitMessage(0); return 0; break; case WM_ACTIVATEAPP: m_bHasFocus = wParam; return 0; break; default: break; } return DefWindowProc(hWnd, Message, wParam, lParam); }
ChrisM
-
ich glaub das mit dem Focus musst du über WM_ACTIVATE anstatt WM_ACTIVATEAPP machen.
-
Hi,
habs jetzt so geschrieben:
case WM_ACTIVATE: m_bHasFocus = LOWORD(wParam); return 0; break;
Aber genau das gleiche Problem: Fokus verlieren und wieder kriegen geht wie gewünscht, aber beim Wiederherstellen nach dem Minimieren stockt der PC total.
ChrisM
-
So, hab jetzt weiter was rausgefunden: Es liegt an meinen Direct3D-Funktionen. Jetzt kann ich das Programm minimieren und ohne Performanceverlust wieder versuchen anzuzeigen, d.h. ich klicke auf das minimierte Fenster in der Taskleiste, aber es kommt nicht mehr
Weiß jemand, wie ich auf WM_ACTIVATEAPP reagieren muss, d.h. was DefWindowProc() da macht?Ich dreh hier noch durch mit den ****** Nachrichten!!
ChrisM
-
du kannst doch einfach nach deinen aktionen DefWindowProc aufrufen, wenn's dir nur darum geht
-
NEIN, jetzt ruf ich DefWindowProc von Hand auf, aber auch dann geht es nicht.
LRESULT CALLBACK CWindow::WindowProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) { // Bevor einer was sagt: Ich bin mir bewusst, dass GetWindowLong() nur "weißes Rauschen" // zurückgibt und der This-Zeiger in pWindowClass->HandleMessage() ungültig ist! // (ist aber egal, weil m_bFinished und m_bHasFocus noch statisch sind!) CWindow *pWindowClass = (CWindow*)GetWindowLong(hWnd, GWL_WNDPROC); ENGINE_LOG("Nachricht: Rufe HandleMessage() auf!\n") return pWindowClass->HandleMessage(hWnd, Message, wParam, lParam); } CWindow::CWindow(HINSTANCE hInstance, const CEngineString &strTitel) { ENGINE_LOG("Creating window...\n") // Anwendungsklasse erstellen WNDCLASSEX WinClass; WinClass.cbSize = sizeof(WNDCLASSEX); WinClass.style = CS_HREDRAW | CS_VREDRAW; WinClass.lpfnWndProc = WindowProc; WinClass.cbClsExtra = 0; WinClass.cbWndExtra = 0; WinClass.hInstance = hInstance; WinClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WinClass.hCursor = LoadCursor(NULL, IDC_ARROW); WinClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); WinClass.lpszMenuName = NULL; WinClass.lpszClassName = strTitel.pchGetCharString(); WinClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if (!RegisterClassEx(&WinClass)) ENGINEERROR("RegisterClassEx failed!") m_hWnd = CreateWindowEx(NULL, strTitel.pchGetCharString(), strTitel.pchGetCharString(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 400, 300, NULL, NULL, hInstance, NULL); if (!m_hWnd) ENGINEERROR("CreateWindowEx failed!") } void CWindow::ProcessMessages() { ENGINE_LOG("ProcessMessages(): Starte Verarbeitung ...\n") MSG Message; if (m_bHasFocus) { ENGINE_LOG("Verwende PeekMessage ...\n") while (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) { ENGINE_LOG("Nachricht!\n"); TranslateMessage(&Message); DispatchMessage(&Message); } } else { ENGINE_LOG("Verwende GetMessage ...\n") while (GetMessage(&Message, NULL, 0, 0) && !m_bHasFocus) { ENGINE_LOG("Nachricht!\n"); TranslateMessage(&Message); DispatchMessage(&Message); } } } LRESULT CWindow::HandleMessage(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) { ENGINE_LOG("HandleMessage(): Verarbeite Nachricht ...\n") switch (Message) { case WM_DESTROY: { ENGINE_LOG("Nachricht ist WM_DESTROY!\n") m_bFinished = true; PostQuitMessage(0); return 0; } break; case WM_ACTIVATEAPP: { ENGINE_LOG("Nachricht ist WM_ACTIVEAPP!\n") m_bHasFocus = (bool)wParam; if (m_bHasFocus) ENGINE_LOG("Programm hat den Fokus!\n") else ENGINE_LOG("Programm hat den Fokus nicht!\n") DefWindowProc(hWnd, Message, wParam, lParam); return 0; } break; default: break; } ENGINE_LOG("Nichtbehandeltete Nachricht, DefWindowProc() wird aufgerufen!\n") return DefWindowProc(hWnd, Message, wParam, lParam); }
Wenn ich das Fenster minimiere und wieder maximieren will, kommt es einfach nicht.
ChrisM
-
Wollt nur sagen, es lag an GetMessage(). Im Moment verwende ich nur PeekMessage (das Fenster ist ja eh die meiste Zeit aktiv) und dann gehts gut.
Später kümmer ich mich um das GetMessage().
ChrisM