Nicht in WM_PAINT zeichnen



  • Hallo!

    Ich versuche mich einmal kurz zu fassen:
    Wenn ich Linien und so zeichnen will mache ich das in WM_PAINT.
    ABER:
    Ich mag zum Beispiel einen Punkt malen wenn ich wo drauf drücke, also zum Beispiel im "Bereich" von LBUTTONDOWN. Wenn ich da den Code (der mir, wenn ich ihn in den WM_PAINT "Bereich" stelle funktioniert) einfüge funktioniert der nicht.
    Warum und wie kann ich das am besten beheben?

    Vielen Dank fürs Lesen und vielleicht Antwort schreiben!

    Steve 🤡



  • Immer in WM_PAINT zeichnen, in WM_LBUTTONDOWN nur eine Variable setzen und InvalidateRect aufrufen.



  • Du könntest ja einfach bei WM_LBUTTONDOWN

    InvalidateRect(hwnd,0,false);
    UpdateWindow(true);
    

    machen und dafür sorgen das es gezeichnet wird. Ich bin mir aber nicht sicher ob es das ist was du suchst.

    BR

    //Edit da bin ich doch zuspät 🤡



  • UpdateWindow brauch man eigentlich nie. 🤡



  • Wahnsinn, das ging echt schnell, vielen Dank!

    Ich schaue mir das einmal an! Wenn ich es nicht verstehe dann melde ich mich!

    Nochmal danke!

    Steve 🤡



  • Ich poste einmal was ich habe:

    case WM_LBUTTONDOWN:
        CRect test; //bitte ignoriert die Namensgebung ;)
        CPoint ptDown (200,200);
        test.BottomRight() = pwDown;
        int hoehe, breite;
        hoehe = 200;
        breite = 250;
        test.Height() = hoehe;
        test.Width() = breite;
        InvalidateRect(hwnd, test, false);
        UpdateWindow(hwnd);
    

    So habe ich es mir aus der MSDN rausgesaugt, wirkt aber irgendwie umständlich ...

    Es geht leider nur bis CPOINT. Es steht zwar in der MSDN aber er nimmt es nicht 😞

    Es kommt dann der Fehler
    error C2065: 'CPOINT': undeclared identifier

    Nun ???



  • Sir_Steve schrieb:

    Ich poste einmal was ich habe:

    case WM_LBUTTONDOWN:
        CRect test; //bitte ignoriert die Namensgebung ;)
        CPoint ptDown (200,200);
        test.BottomRight() = pwDown;
        int hoehe, breite;
        hoehe = 200;
        breite = 250;
        test.Height() = hoehe;
        test.Width() = breite;
        InvalidateRect(hwnd, test, false);
        UpdateWindow(hwnd);
    

    So habe ich es mir aus der MSDN rausgesaugt, wirkt aber irgendwie umständlich ...

    Es geht leider nur bis CPOINT. Es steht zwar in der MSDN aber er nimmt es nicht 😞

    Es kommt dann der Fehler
    error C2065: 'CPOINT': undeclared identifier

    Nun ???

    Das ist MFC und kein WinAPI in der WinAPI gibt es keinen C Prefix für Klassen
    POINT und RECT sind aus der WinAPI

    Edit: Probiers mal so: ich weis zwar auch nicht was du da machst aber probiers einfach mal

    case WM_LBUTTONDOWN:
        RECT test; //bitte ignoriert die Namensgebung ;)
        test.top = 200;
        test.left = 200; 
        test.bottom = test.top  + 200;
        test.right  = test.left + 250;
        InvalidateRect(hwnd, &test, false);
        UpdateWindow(hwnd);
    


  • Man lasst doch das updatewindow sein, das ist unnütz



  • Sorry 4 that!!!

    Also, dank RECT konnte ich jetzt einige Zeilen kürzen, es sieht nun wie folgt aus:

    case WM_LBUTTONDOWN:
        InvalidateRect (hwnd, &test, false);
        //Test ist so ein RECT und hat 4 Werte, dank Watch weiß ich auch dass diese okay sind...
    

    Das Gute: Ich bekomme keinen Fehler mehr.
    Das Schlechte: Ich bekomme gar nichts, er zeichnet mir das Ding nicht 😞



  • Lol. Dieses Rechteck was du da definierst ist nur der Bereich der neugezeichnet werden soll. Rechtecke zeichnet man mit der Funktion Rectangle.



  • (.)(.) schrieb:

    Man lasst doch das updatewindow sein, das ist unnütz

    ich das hab grad auch nur angepasst, ist mir gar net aufgefallen. Aber naja egal.



  • Hört auf mich zu verwirren!!!

    Kann mir mal wer bitte 4 Zeilen Quellcode schicken???

    Danke



  • bool paintRectangle = false; // eine Variable die mit deinem Fenster assoziiert ist
    
    case WM_LBUTTONDOWN:
        paintRectangle = true;
        InvalidateRect(hWnd, NULL, TRUE);
        return 0;
    case WM_PAINT:
    {
        PAINTSTRUCT paintData;
        HDC hDC = BeginPaint(hWnd, &paintData);
        if(paintRectangle)
        {
            Rectangle(hDC, 0, 0, 100, 100);
        }
        EndPaint(hWnd, &paintData);
        return 0;
    }
    


  • Gut, nachdem ich es noch leicht angepasst habe funktioniert das jetzt, danke einmal.

    Und nur ob ich das jetzt verstanden habe:
    Ich sage ich will den Bereich den ich in dem InvalidateRect definiere noch mal zeichnen oder wie, und dann wird paint aufgerufen ... huh??



  • Du fügst mit InvalidateRect einen Bereich zur Update Region hinzu.

    Dabei wird nicht sofort eine WM_PAINT Nachricht generiert.
    (Über UpdateWindow könntest du das erzwingen.)

    Erst GetMessage/PeekMessage generieren die WM_PAINT Nachricht, wenn die Update Region nicht leer ist und keine anderen Nachrichten für das Fenster vorhanden sind.



  • Okay, dann verstehe ich inetwa was da vorgeht, werde mich noch spielen!
    Jedenfalls danke an alle beteiligten!

    Steve 🤡



  • er koennte sich aber auch den device kontext in einer beliebiegen funktion ueber GetDC() anfordern und dann nicht in WM_PAINT zeichnen... dann spart man sich diese kontroll-variablen.



  • dann ist es aber beim nächsten neuzeichnen nicht mehr da.



  • verdammt, stimmt ja... vergessen



  • Also, das funktioniert echt gut, main Zeichenprogramm (dank unglaublicher Benutzerunfreundlichkeit und schmerzhafter Bedinung Pain(t) genannt 😃 ) funktioniert einigermaßen.
    ABER: Wenn ich ein paar Sachen zeichne und das Fenster dann minimiere und wieder aufrufe ist alles weg 😞
    Nicht dass das bei meinen Zeichenkünsten schade ist aber ...
    Wie verhindere ich das?
    Gibt es dazu ein Event das ich abfangen kann?

    Grüße, Steve! 🤡


Anmelden zum Antworten