Problem mit GDI



  • Das geht so nicht. Du darfst BeginPaint/EndPaint ausschließlich in WM_PAINT benutzen. Und dort soll auch gezeichnet werden. Ebenso merkwürdig finde ich die Angaben der Koordinaten. Ich habe es jetzt mal ein klein wenig geändert:

    LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
            PAINTSTRUCT ps;
            LONG_PTR lCoords;
            switch (message)
            {
               case WM_LBUTTONDOWN:
                    if(hwnd == Design)
                    {
                        // Koordinaten des Clicks merken
                        SetWindowLongPtr(hWnd, GWLP_USERDATA, lParam); 
                        // Neu zeichnen, ohne den Hintergrund zu löschen
                        InvalidateRect(hWnd, NULL, FALSE);
                    }
                    break;
               case WM_PAINT:
                    lCoords = GetWindowLongPtr(hWnd, GWLP_USERDATA);
                    BeginPaint(hwnd, &ps);
                    Rectangle (ps.hdc, (int)LOWORD(lCoords), (int)HIWORD(lCoords), 100, 100);
                    EndPaint(hwnd, &ps);
                    return(0);
               case WM_DESTROY:
                               PostQuitMessage(0);
                               break;
               case WM_CREATE:
                              SetWindowLongPtr(hWnd, GWLP_USERDATA, MAKELONG(-100, -100));
                              return 0;
               case WM_COMMAND:
                    return 0;
               default:
               return DefWindowProc(hwnd, message, wParam, lParam);
            }
            return 0;
    }
    

    So zwar das letzte Rechteck immer neu gezeichnet, aber dafür kannst Du ja noch ein Flag 'reinfummeln'.

    [ Dieser Beitrag wurde am 27.12.2002 um 21:06 Uhr von -King- editiert. ]



  • Original erstellt von -King-:
    [QB]Das geht so nicht. Du darfst BeginPaint/EndPaint ausschließlich in WM_PAINT benutzen. Und dort soll auch gezeichnet werden. Ebenso merkwürdig finde ich die Angaben der Koordinaten.
    So zwar das letzte Rechteck immer neu gezeichnet, aber dafür kannst Du ja noch ein Flag 'reinfummeln'.

    [QB]

    Ähhh mein Compiler sagt: SetWindowLongPtr not found.
    Wenn ich versuche, die Funktion SetWindowLong zu usen, sagt er mir GWLP_USERDATA not found 😞 😞 😞 ich use den C++ Builder

    Gruss, code_pilot 😞



  • Das hatten wir doch schon x-mal. GWL_USERDATA ist in Deinem Fall das Richtige.



  • nee moment, runnt doch, ich musste nur ein paar dinge anpassen! blödes MS mit diesen Extrawürstchen (oder isses doch Borland???) ich hasse inkompatibilitäten ...

    ok runnt besten dank 🙂 🙂 🙂

    habe später sicherlich noch mehr fragen 😉

    code_pilot



  • ok!
    da ist auch schon meine nächste Frage:

    a) was heisst

    SetWindowLong(hwnd, GWL_USERDATA, MAKELONG(-100, -100));
    

    b) warum wird das Rechteck immer von der Positon 100 | 100 auf dem Fenster bis zu der Position, an der ich mit der Maus klicke, gezeichnet?? Also immer um den Punkt 100|100 herum, es soll aber so sein das das Rechteck da beginnt, wo ich mit der Mausklicke, und dann 100 land unt 100 tief ist (angaben in Pix 😉 )

    Thx for your help!

    code_pilot ...



  • a) was heisst

    SetWindowLong(hwnd, GWL_USERDATA, MAKELONG(-100, -100));
    

    Das erste Rechteck hat den Ursprung an x = -100 und y = -100. Bei einer Breite von und Höhe von 100 ist es dann außerhalb des sichtbaren Bereichs (sollte sein).

    b) warum wird das Rechteck immer von der Positon 100 | 100 auf dem Fenster bis zu der Position, an der ich mit der Maus klicke, gezeichnet??

    Weil die Koordinaten falsch angegeben sind. Ich habe nun nochmal für Dich in die Hilfe geschaut. Rectangle verlangt nicht Breite/Höhe, sondern absolute Koordinaten. Das sollte besser sein:

    Rectangle (ps.hdc, (int)LOWORD(lCoords), (int)HIWORD(lCoords), (int)LOWORD(lCoords) + 100, (int)HIWORD(lCoords) + 100);
    

    [ Dieser Beitrag wurde am 27.12.2002 um 21:31 Uhr von -King- editiert. ]



  • Ich würde nicht den USERDATA-Bereich nehmen, um die Koordinaten zu speichern, den könnte man woanders besser gebrauchen...
    Eine normale statische Variable tuts auch.



  • Ich würde nicht den USERDATA-Bereich nehmen,

    Warum nicht? Dafür ist er doch da. Wenn da noch mehr zukommt, kann man dort den Pointer auf eine Struktur speichern und in dieser struct wieder die Koordinaten. Das ist IMO allemal besser, als irgendwelche globalen oder statischen Variablen.



  • Hallo,
    ich binde des öfteren Fenster in Klassen ein, wobei hier die CALLBACK-Funktion statisch sein muss. Da ich aus einer statischen Funktion nicht auf Methoden/Membervariablen zugreifen kann, speichere ich im USERDATA-Bereich den this-Zeiger.
    Sicher, du hast recht, dass man das ganze in einer Struktur speichern kann, macht bei großen Projekten aber unnötig Aufwand.
    Wenn z.B. jemand anders die CALLBACK-Funktion meiner Klasse so verändert, wird er lange nach Fehlern suchen müssen, deshalb bin ich der Meinung, solche globalen Eingriffe in das Fenster zu unterbinden und seinen Code so unabhängig wie möglich zu schreiben.

    Was spricht gegen eine statische Variable? Wenn ich mir den Petzold o.ä. Code professioneller Programmierer anschaue, so wird deine Methode nicht verwendet.

    MfG



  • Was gegen statische Variablen spricht? Erzeugst Du von einer Fensterklasse mehr als ein Fenster, bekommst Du Probleme. Nach meiner Methode erhält jedes Fenster seine eigenen Daten. Du speicherst halt den this-Pointer. Das ist doch genau das gleiche.



  • WOW!
    Na dann erstmal besten dank! Ich liebe dieses Forum, man kriegt immer eine Antwort auf seine Fragen! DANKE DANKE 😃

    ///////////
    code_pilot :p
    \\\\\\\\


Anmelden zum Antworten