PatBlt funktioniert nur bei GetDC(0)?



  • Hi!
    Wegen einem Link, den Flenders mir in einem anderen Thread geschickt hat, habe ich mich mal mit PatBlt beschäftigt...damit ist es ja möglich Stellen mit einer bestimmten Farbe schnell zu färben...wie es in dem Link bei dem Rechteck geschieht, jetzt habe ich mal einfach probiert, in einer externen Anwendung ein Stück meines Fensters mit schwarz zu invertieren und wieder zurück. Das klappt aber nur, wenn ich als DC den kompletten Bildschirm hernehme, bei meinem eigenen Fenster funktioniert das nicht, hier die Codes:

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	PAINTSTRUCT ps;
    	HDC hDC;
    	switch(message)
    	{
    
    	case WM_LBUTTONDOWN:
    		InvalidateRect(hWnd, 0, TRUE);
    		break;
    	case WM_PAINT:
    		hDC = GetDC(hWnd);
    		HBRUSH hBR = CreateSolidBrush(RGB(255,255,255));
    		SelectObject(hDC, hBR);
    		PatBlt(hDC, 0, 0, 200, 200, PATINVERT);
                      DeleteObject(hBR);
    		DeleteDC(hDC);
    		break;
    
    	case WM_CREATE:
    		break;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		break;
    
    	}
    
    	return DefWindowProc(hWnd, message, wParam, lParam);
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	PAINTSTRUCT ps;
    	HDC hDC;
    	switch(message)
    	{
    
    	case WM_LBUTTONDOWN:
    		InvalidateRect(hWnd, 0, TRUE);
    		break;
    	case WM_PAINT:
    		hDC = GetDC(0);
    		HBRUSH hBR = CreateSolidBrush(RGB(255,255,255));
    		SelectObject(hDC, hBR);
    		PatBlt(hDC, 0, 0, 200, 200, PATINVERT);
    		DeleteDC(hDC);
                      DeleteObject(hBR);
    		break;
    
    	case WM_CREATE:
    		break;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		break;
    
    	}
    
    	return DefWindowProc(hWnd, message, wParam, lParam);
    }
    

    Der obere Code funktioniert, der untere nicht...

    Compiler



  • Ich würde mal BeginPaint und EndPaint nehmen statt GetDC(hWnd);



  • daran liegts aber nicht



  • Compiler schrieb:

    Das klappt aber nur, wenn ich als DC den kompletten Bildschirm hernehme, bei meinem eigenen Fenster funktioniert das nicht.

    HDC = GetDC(hWnd);
    
    hDC = GetDC(0);
    

    Der obere Code funktioniert, der untere nicht...

    Welcher funktioniert denn jetzt 😕



    1. GetDC erwartet kein DeleteDC !
    2. Ich hab mal was von Rückgabewerten im Wind säuseln hören...


  • Du solltest dich erstmal mit GDI allgemein beschäftigen. Du hast viel falsch gemacht. Zum Beispiel bei SelectObject.



  • Moin Compiler,

    Die Fensterfunktion sollte mit return 0; verlassen werden, wenn Du eine Nachricht behandelt hast. In Deinem Code wird jedesmal die DefWindowProc() aufgerufen. BÖSER FEHLER. Ersetze also das break; durch return 0;.

    Die WM_PAINT-Nachricht sollte so aussehen:

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
      PAINTSTRUCT ps;
      HDC         hDC;
      HBRUSH      hBR, hOldBR;
    
      .
      .
      .
    
        case WM_PAINT:
    
          hDC = BeginPaint(hWnd, &ps);
    
          hBR = CreateSolidBrush(RGB(255,255,255));
          hOldBR = SelectObject(hDC, hBR);
    
          PatBlt(hDC, 0, 0, 200, 200, PATINVERT);
    
          SelectObject(hDC, hOldBR);
          DeleteObject(hBR);
    
          EndPaint(hWnd, &ps);
    
          return 0;
    
       .
       .
       .
    

    Ciao...



  • case WM_PAINT:
    		{
    		hDC = BeginPaint(hWnd, &ps);;
    		HBRUSH hBR = CreateSolidBrush(RGB(255,255,255));
    		SelectObject(hDC, hBR);
    		PatBlt(hDC, 0, 0, 200, 200, PATINVERT);
    		EndPaint(hWnd, &ps);
    		}
    		return 0;[
    

    so funktionierts auch nicht 😞 Bleibt immer schwarz!



  • zeig doch das ganze programm :p



  • Weißt du was in der Function:

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

    passiert, bzw. wann sie Aufgerufen wird, und wenn ja weißt du was passiert ist
    wenn WM_PAINT drinn steht??

    Warum steckst du sowas nicht in die WinMain Routine, wo es hin soll?

    Es sind einige schönheitsfehler drinn, überlege das ganze mal mit Geduld und
    es wird klappen.

    Oder mal anders gesagt, wenn ich dich Anrufe und sag ich habe ein Bild gemacht
    dann ist das so als ob Windows sagt WM_PAINT:
    Also Windows sagt WM_PAINT wenn er was gezeichnet hat, auch bei UpdateWindow
    und RedrawWindow.

    Und noch ein ALSO: Überlege deine Vorgehensweise mal und lese in der MSDN.

    PS: GetDC(0), giebt den Desktop als Device.



  • MiC++ha schrieb:

    Oder mal anders gesagt, wenn ich dich Anrufe und sag ich habe ein Bild gemacht
    dann ist das so als ob Windows sagt WM_PAINT:
    Also Windows sagt WM_PAINT wenn er was gezeichnet hat, auch bei UpdateWindow
    und RedrawWindow.

    Möchtest Du diesen Satz evtl. etwas korrigieren?



  • Ja will ich, hatte was mit onPaint vom BCB durcheinander geworfen,
    man ich werde alt.

    Also (mal wieder) WM_PAINT steht in der Message wenn windows für die Applikation, oder einer anderen was zeichnen soll.
    Das bedeutet das eine Anfrage zum Zeichnen gemacht wurde, auf diese kann
    man dann reagieren, aber damit so was kommt zu dem Zeitpunkt wo du beim
    Prüfen auf WM_PAINT was machen willst mußt du auch so ein Request senden.
    Da du ein DC auf dem Desktop hast klappt das dann auch, aber nicht bei deiner
    Applikation, da diese keine Message zum Zeichnen sendet.
    Oder so.



  • @Compiler:

    Mir ging es erstmal darum Dir zu zeigen, was an Deiner Nachrichtenverarbeitung falsch ist. Das Du zwischen den inversen Zuständen hin- und herschalten möchtest, hatte ich überlesen.

    Du möchtest ein Ausschnitt Deines Fensters invertieren, wenn Du die linke Maustaste drückst. Warum benutzt Du die PatBlt()-Funktion nicht bei der Nachricht WM_LBUTTONDOWN?

    case WM_LBUTTONDOWN:
    
          hDC = GetDC(hwnd);
          PatBlt(hDC, 0, 0, 200, 200, PATINVERT);
          ReleaseDC(hwnd, hDC);      
    
          return 0;
    

    Die WM_PAINT-Nachricht löscht Du komplett aus Deiner Funktion!!!!

    Ciao...



  • Was willst du denn überhaupt invertieren, wenn du nichts ins Fenster zeichnest 😕 Dann kannst du doch auch gleich FillRect nehmen 🙄


Log in to reply