Problem mit MoveWindow



  • Moin,

    ich habe mir eine eigene Schaltfläche erstellt, welches ein Bitmap via AlphaBlend zeichnet.
    Das klappt soweit auch prima.
    Nun wollte ich einen "Klick-Effekt" einbauen. Ich habe MoveWindow dazu benutzt, die Schaltfläche ein wenig zu bewegen, wenn der Benutzer auf dieses mit der Maus klickt.
    Das klappt auch, aber hier ist schon die erste Merkwürdigkeit.
    Obwohl ich den Parameter bRepaint von MoveWindow auf TRUE gesetzt habe kommt keine WM_PAINT in der Fensterprozedur der Schaltfläche an. Das ist aber nicht weiter schlimm, denn es funktioniert ja auch so.

    Wenn aber nach dem Aufruf von MoveWindow eine WM_PAINT an die Fensterprozedur der Schaltfläche gesendet wird, schlägt AlphaBlend fehl. Das betrifft aber nur die Schaltfläche auf die geklickt wurde, bzw. die mit MoveWindow bewegt wurde.

    Habe schon alles mögliche ausprobiert, aber ich finde den Fehler nicht.

    Hat jemand eine Idee woran es liegen könnte ?

    Gruß
    Greenhorn


  • Mod

    MoveWindow löst auch nihct unbedingt WM_PAINT aus.

    Benutzt Du denn InvalidateWindow um ein Neuzeichnenzu erzwingen wenn Du es benötigst, oder was machst Du?

    Ansonsten zeige Code...



  • Hallo,

    laut MSDN ruft MoveWindow wiederum UpdateWindow auf ...

    Remarks

    If the bRepaint parameter is TRUE, the system sends the WM_PAINT message to the window procedure immediately after moving the window (that is, the MoveWindow function calls the UpdateWindow function). If bRepaint is FALSE, the application must explicitly invalidate or redraw any parts of the window and parent window that need redrawing.

    Wenn ich nach dem Aufruf von MoveWindow ein Neuzeichnen erzwingen möchte, z.B. mit InvalidateRect oder InvalidateRgn, dann schlägt wie oben beschrieben AlphaBlend fehl.

    Hier mal die Fensterprozedur:

    //
    //   StarButton window procedure
    //
    LRESULT CALLBACK StarBtnWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	LPSTARBUTTON lpsb ;
    	RECT rcClient ;
    
    	// Retrieve the pointer to the window's STARBUTTON structure
    	lpsb = (LPSTARBUTTON)GetWindowLongPtr (hwnd, 0) ;
    
    	switch (message)
    	{
    	case WM_LBUTTONDOWN:
    
    		//GetWindowRect (lpsb->hWndParent, &rcParent) ;
    		GetWindowRect (lpsb->hWnd, &rcClient) ;
    		ScreenToClient (lpsb->hWndParent, (LPPOINT)&rcClient) ;
    		MoveWindow (lpsb->hWnd, rcClient.left-1, rcClient.top+1, rcClient.right, rcClient.bottom, TRUE) ;
    		break ;
    
    	case WM_LBUTTONUP:
    
    		GetWindowRect (lpsb->hWnd, &rcClient) ;
    		ScreenToClient (lpsb->hWndParent, (LPPOINT)&rcClient) ;
    		MoveWindow (lpsb->hWnd, rcClient.left+1, rcClient.top-1, rcClient.right, rcClient.bottom, TRUE) ;
    		//InvalidateRgn (lpsb->hWnd, lpsb->hRgn, TRUE) ;
    		//InvalidateRect (lpsb->hWnd, NULL, FALSE) ;
    
    		// Send the SBN_CLICKED notification via WM_COMMAND
    		SendMessage (
    			lpsb->hWndParent, 
    			WM_COMMAND, 
    			MAKEWPARAM(GetDlgCtrlID (lpsb->hWnd), SBN_CLICKED), 
    			(LPARAM)lpsb->hWnd
    			) ;
    		break ;
    
    	case WM_PAINT:
    		return OnPaintStarButton (lpsb) ;
    
    	case WM_GETFONT:
    		return (LRESULT)lpsb->hFont ;
    
    	case WM_SETFONT:
    		lpsb->hFont = (HFONT)wParam ;
    		break ;
    
    	case WM_NCCREATE:
    		return OnCreateStarButton (lpsb, hwnd, wParam, lParam) ;
    
    	case WM_NCDESTROY:
    		return OnDestroyStarButton (lpsb, hwnd) ;
    
    	default:
    		return DefWindowProc (hwnd, message, wParam, lParam) ;
    	}
    	return 0 ;
    }
    

    Wenn Du mehr sehen möchtest, dann Bescheid, sind aber ca. 550 Zeilen.

    Gruß



  • Martin Richter schrieb:

    Benutzt Du denn InvalidateWindow um ein Neuzeichnenzu erzwingen wenn Du es benötigst, oder was machst Du?

    Die einzige Situation wo ein Neuzeichnen statt findet (bzw. die Fensterprozedur der Schaltfläche eine erneute WM_PAINT erhält) ist eigentlich nur, wenn das Elternfenster minimiert und wiederhergestellt wird ...



  • Nur der Vollständigkeit halber...
    Mit SetWindowPos klappt es prima. 😉


  • Mod

    Greenhorn__ schrieb:

    Nur der Vollständigkeit halber...
    Mit SetWindowPos klappt es prima. 😉

    Kann ich mir kaum vorstellen, dass es hier einen Unterschie gibt. MoveWindow benutzt nämlich SetWindowPos. Welche Flags hast Du verwendet?

    Zudem Du die Doku nichtkorrekt gelesen. hast. Das bPaiont beeinflusst nurBeeiche, die durch den Move "uncovered" wedren. Ist das Fenster also ganz sichtbar passiert natürlich nichts.
    Du müüsstest schon mit UpdateWindow/RedrawWindow ein neuzeichnen erzwingen.
    Aber selbst das ist aoft nicht nötig, weil der Windows Manager den ganzen Inhalt des fensters selber verschiebt und ein Repaint so grundsätzlich vermieden wird.



  • Hi,

    ob MoveWindow nun wiederum SetWindowPos aufruft habe ich noch nicht nachgesehen ...

    Wie auch immer, Sie haben Post. 😉

    Gruß


  • Mod

    Greenhorn__ schrieb:

    Wie auch immer, Sie haben Post. 😉

    Für so etwas habe ich keine Zeit... Sorry!


Anmelden zum Antworten