Problem mit GDI
-
Hi Leudde!
Könnt ihr mir mal hierbei helfen:
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; switch (message) { case WM_LBUTTONDOWN: if(hwnd == Design) { hdc = BeginPaint(hwnd, &ps); Rectangle (hdc, wParam, lParam, 100, 100); EndPaint(hwnd, &ps); UpdateWindow(hwnd); } break; case WM_PAINT: break; case WM_DESTROY: PostQuitMessage(0); break; case WM_CREATE: return 0; case WM_COMMAND: return 0; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; }
es geht um die Fensterfunktion, duie die Messages ausführt. Wenn der User in das Fenster klickt, soll ein Rechteck gezeichnet werden, das mit der linken oberen Ecke da anfängt, wo die Maus beim klick stand. Ok. Das Rechtech wird gezeichnet, aber jedesmal an der falschen Stelle und in der falschen Grösse. Meine Frage: Was mache ich Falsch? Tut mir leid, bin GDI Newbie! Ausserdem, warum wird das Rechteck nur einmal gezeichnet, wenn ich mehrmals klicke kommen keine neuen, und das sollte auch möglich sein! Würde mich sehr auf eine Antwort freuen!
Gruss, code_pilot
-
Bei Position der Maus bei den "Maus-Messages" ist nicht wParam|lParam, sondern LOWORD(lParam)|HIWORD(lParam), also:
x = LOWORD(lParam);
y = HIWORD(lParam);cu
-
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 foundich 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
\\\\\\\\