Wie kann man die CPU Belastung verringern, wenn das Programm inaktiv ist?



  • Nö, das hilft nicht. Kann das Problem sein, dass ich es als Debug Version von der Entwicklungsumgebung ausführe?



  • WaitMessage()



  • Eigentlich nicht(außer wenn du etwa 50MHZ hättest). Der einzige Dauerloop der noch entstehen kann, ist wenn tausende Messages kommen. Dann würde das ohne Sleep(0) ablaufen. Welche windows version hast du und funktioniert das is_active() auch richtig?



  • Oh ja WaitMessage() wäre wirklich gut als else funktion. Dann müsste es auch funktionieren außer eben is_active() ist nicht richtig.



  • WinXP SP2 auf 1,7GHz, 512MB RAM.

    bool active_ = true;
    std::bitset<256> keys_;
    
    void activate() {
    	active_ = true;
    }
    
    void deactivate() {
    	active_ = false;
    }
    
    bool is_active() {
        return active_;
    }
    
    void set_key(WPARAM index, bool pressed) {
        keys_[index] = pressed;
    }
    
    bool key_pressed(WPARAM index) {
    	return keys_[index];
    }
    
    LRESULT CALLBACK WP(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    	switch (uMsg) {									// Check for windows messages
    		case WM_ACTIVATE:							// watch for window activate message
    		{
    			if (!HIWORD(wParam))					// Check minimization state
    				activate();			// Program is active
    			else
    				deactivate();		// Program is no longer active
    			return 0;								// Return to the message loop
    		}
    
    		case WM_SYSCOMMAND:							// Intercept system commands
    		{
    			switch (wParam)	{						// Check system calls
    				case SC_SCREENSAVE:					// Screensaver trying to start?
    				case SC_MONITORPOWER:				// Monitor trying to enter powersave?
    				return 0;							// Prevent from happening
    			}
    			break;									// Exit
    		}
    
    		case WM_CLOSE:								// Did we receive a close message?
    		{
    			PostQuitMessage(0);						// Send a quit message
    			return 0;								// Jump back
    		}
    
    		case WM_KEYDOWN:							// Is a key being held down?
    		{
    			set_key(wParam, true);	// If so, mark it as true
    			return 0;								// Jump back
    		}
    
    		case WM_KEYUP:								// Has a key been released?
    		{
    			set_key(wParam, false);	// If so, mark it as false
    			return 0;								// Jump back
    		}
    	}
    	// Pass all unhandled messages to DefWindowProc
    	return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    

    Es muss korrekt sein.



  • Dennis123 schrieb:

    Oh ja WaitMessage() wäre wirklich gut als else funktion. Dann müsste es auch funktionieren außer eben is_active() ist nicht richtig.

    Super!!! Vielen Dank! Es hat PRIMA funktioniert! Sogar der verbrauchte Speicher wird beim Deaktivieren verringert! 👍 🙂



  • Du hast aber kein case für WM_PAINT, oder? Das würde es eigentlich erklären. WM_PAINT muss immer behandelt werden sonst kommen glaube ich tausende WM_PAINT messages.



  • return DefWindowProc(hwnd, uMsg, wParam, lParam);
    

    Zwar ist es so, aber ich habe es noch nicht implementiert.
    Vielleicht kannst du mir helfen und zeigen, wie man WM_PAINT macht.



  • case WM_PAINT:
    {
        PAINTSTRUCT ps;
        BeginPaint(hWnd, &ps);
        // Hier kommt der zeichencode rein
        // - Also entweder die GDI funktionen oder Gdi+
        EndPaint(hWnd, &ps);
        return 0;
    }
    


  • Klasse! Noch 1 Frage! Ist es möglich die zum Zeichnen Quellcode irgendwo anders ausführen? Wie soll es dann aussehen? Und muss man explizit WM_PAINT schicken, oder?

    Vielen Dank!



  • Zum einen kannst du bei WM_PAINT den gesamten zeichencode auslagern und wenn du von woanders das zeichen starten willst dann benutze InvalidateRect(hWnd, NULL, TRUE/FALSE). Der 2. Parameter kann ein Rect* sein, der 3. bestimmt, ob der hintergrund neugezeichnet werden soll(sinnvoll).



  • Ich öffne mir mal ein neues Thema.



  • Dennis123 schrieb:

    Du hast aber kein case für WM_PAINT, oder? Das würde es eigentlich erklären. WM_PAINT muss immer behandelt werden sonst kommen glaube ich tausende WM_PAINT messages.

    Nur wenn man dann nicht die DefWindowProc() aufruft, die DefWindowProc() macht sonst quasi selber ein BeginPaint()/EndPaint()

    WM_PAINT wird solange ständig neu ans Fenster geschickt bis alle Fensterbereiche als "gültig" markiert sind.

    Wenn z.B. ein Fensterbereich zum Teil überdeckt wurde, wird der ehemals überdeckte Teil als "ungültig" markiert und WM_PAINT geschickt. Bei BeginPaint() kann man aus der PAINTSTRUCT lesen welchen Teil man neu zeichnen soll. Beim Aufruf von EndPaint() markiert Windows diesen Teil dann wieder als gültig.

    Mit InvalidateRect() kann man Teile auch selber als ungültig markieren. Gültig markieren kann man abgesehen von EndPaint() auch außerhalb von WM_PAINT mit ValidateRect().


Anmelden zum Antworten