HDC global... GetDC überschreibt alles?
-
lippoliv schrieb:
Erstaunlicher weise nicht...
Da ich allerddings gelesen hatte, das es passieren sollte habe ich probiert... Es verschwindet alles wenn man das Fenster neu Skalliert(was nicht möglich ist) oder es unter die Startleiste schiebt(also aus dem Bildschirm raus)...Eben. Immer, wenn Du irgendwas mit dem Fenster machst, sendet Windows eine WM_PAINT. In der Standardbearbeitung (DefWindowProc) wird einfach das Fenster samt Hintergrund neu gezeichnet. Alles, was dann nicht in WM_PAINT gezeichnet wurde, verschwindet.
1. verstehe ich nicht, entweder ist dein Satz falsch (unverständlich) oder ich habe ein falsches WM_PAINT...
Auch in WM_PAINT muss ich ein HDC deklarieren...Unter WM_PAINT ist der hDC der Rückgabewert von BeginPaint(). Alles das muß dann mit EndPaint() abgeschlossen werden.
-
Ok dass verstehe ich.
Habe ich doch bis jetzt auch gemacht (in WM_PAINT)...Ne frage zu dem Array... Muss ich alles drin speichern oder nur den letzten schritt?
Ich meine WM_PAINT überschreibt deralles was vorher war, oder behält er dass von davor in sich?
[EDIT]
//glob.vars HPEN *aktPen; [...] COORD myPoint, mouseKoord; HDC myHdc; HWND myWnd; [...] case WM_PAINT: //zum Zeichnen anmelden myHdc = BeginPaint( myWnd, &myPaint ); { stdForm( myPaint, myRect, myWnd, myHdc ); if( myPoint.x != -1 ) { printf( "." ); backUp = SelectObject( myHdc, *aktPen ); MoveToEx( myHdc, //Zeichenfläche myPoint.x, //X-Koordinate myPoint.y, //Y-Koordinate NULL //old-Koordinate ); LineTo( myHdc,//Zeichenfläche mouseKoord.X, //X-Koordinate mouseKoord.Y //Y-Koordinate ); SelectObject( myHdc, backUp ); } } EndPaint( myWnd, &myPaint ); break; [...] case WM_MOUSEMOVE: if( myPoint.x != -1 ) { SendMessage( myAppWnd, WM_PAINT, 0, 0 );//send WM_PAINT so that the painting is just standing, if the window will be resized myPoint.x = LOWORD(lParam);//set new coordinates myPoint.y = HIWORD(lParam); } else { myPoint.x = LOWORD(lParam);//The first coordinates myPoint.y = HIWORD(lParam); } break; [...]Das funktioniert nicht... er macht punkte( Z: 16 ) aber... naja... er malt nicht.
-
Was übergibst Du denn da an BeginPaint()? Ist &myPaint der Zeiger auf die PaintStruct?
Normalerweise sollte das so aussehen:case WM_PAINT: { PAINTSTRUCT myPaint; HDC hDC; hDC = BeginPaint(hWnd, &myPaint);Dies nur, weil Du die Deklaration unterschlagen hast.

zum Spechern der Punkte solltest du eine POINT-Variable anlegen, die sind schon vordefiniert:The POINT structure defines the x- and y- coordinates of a point. typedef struct tagPOINT { // pt LONG x; LONG y; } POINT; Members x Specifies the x-coordinate of the point. y Specifies the y-coordinate of the point.COORD benutzt man eigentlich nur für Consolen-Ausgaben.
Jetzt zu Deinem Problem: Natürlich mußt Du deine gezeichneten Punkte zwischenspeichern und unter WM_PAINT ausgeben. Du hast aber nur eine Variable dafür angelegt. Wenn Du nur jeweils einen Punkt speicherst, wird auch nur der ausgegeben. Du kannst die Punkte in einem Array speichern (muß evtl. redimensioniert werden, wenn Du die Zeichnung erweiterst) und dann unter WM_PAINT zeichnen lassen.
-
Naja die idee ist:
Ich speichere den aktuellen Punkt.Wenn es schon einen Punkt gibt(zwischengespeichert), dann ziehe ich erst eine Linie zwischen den beiden Punkten und speichere den aktuellen zwischen.
got Naja die idee ist;

So brauche ich nicht ein array für das gesamte Bild oder!?
PS: myPaint ist ein PAINTSTRUCT sry... vergessen
-
Dann bräuchtest Du zwei POINT-Variablen, hast aber unter WM_MOUSEMOVE nur eine angelegt. WM_PAINT liefert keine Mauskoordinaten.
Der Effekt ist halt, wenn Du alles vorherige nicht gespeichert hast, wird das durch die WM_PAINT erstmal gelöscht. Dann zeichnet BeginPaint Deine Linie, hat aber nur den aktuellen Punkt dafür, die vorherigen nicht. Du mußt also die vorherigen Aktionen zwischenspeichern und bei WM_PAINT neu ausführen.Übrigens bewirkt man das Aktualisieren des Fensters nicht mit SendMessage(...WM_PAINT...), sondern mit InvalidateRect().
-
Ja das Tue ich doch...
LRESULT CALLBACK WndProc( HWND myWnd, UINT givenMessage, WPARAM wParam, LPARAM lParam ) /* This function recieves the Messages, wich are given from MS-Windows to the program. So the program can do message specific actions, if this message is incoming. */ { PAINTSTRUCT myPaint; //Handle für Gerätekontext(gültiger Zeichenbereich) BOOL visitMsg = FALSE; static POINT myPoint; static RECT myRect; static BOOL isPainting; static COORD mouseKoord; HANDLE backUp; if( LOWORD(lParam) != 0 || HIWORD(lParam) != 0) { mouseKoord.X = LOWORD(lParam); //took the mouse-coordinates into a COORD variable (perfomance) mouseKoord.Y = HIWORD(lParam); } switch( givenMessage ) { case WM_PAINT: //zum Zeichnen anmelden myHdc = BeginPaint( myWnd, &myPaint ); { stdForm( myPaint, myRect, myWnd, myHdc ); if( myPoint.x != -1 ) { backUp = SelectObject( myHdc, *aktPen ); MoveToEx( myHdc, //Zeichenfläche myPoint.x, //X-Koordinate myPoint.y, //Y-Koordinate NULL //old-Koordinate ); LineTo( myHdc, //Zeichenfläche mouseKoord.X, //X-Koordinate mouseKoord.Y //Y-Koordinate ); SelectObject( myHdc, backUp ); } } EndPaint( myWnd, &myPaint ); visitMsg = TRUE; break; case WM_MOUSEMOVE: myHdc = GetDC( myWnd ); //open device-context (paintplace) { if( !isPainting ) //Wenn der { if( inRect( mouseKoord, blackColor ) ) { aktPen = &blackPen; //slect black pen R = 0; G = 0; B = 0; } else if( inRect( mouseKoord, whiteColor ) ) { aktPen = &whitePen; //select white pen R = 255; G = 255; B = 255; } else if( inRect( mouseKoord, smallSize ) ) { DeleteObject( aktPen ); *aktPen = CreatePen( PS_SOLID, 1, RGB( R, G, B ) ); } else if( inRect( mouseKoord, middleSize ) ) { DeleteObject( aktPen ); *aktPen = CreatePen( PS_SOLID, 3, RGB( R, G, B ) ); } else if( inRect( mouseKoord, bigSize ) ) { DeleteObject( aktPen ); *aktPen = CreatePen( PS_SOLID, 4, RGB( R, G, B ) ); } } else { if( myPoint.x != -1 ) { SendMessage( myAppWnd, WM_PAINT, 0, 0 ); //send WM_PAINT so that the painting is just standing, if the window will be resized myPoint.x = mouseKoord.X; //set new coordinates myPoint.y = mouseKoord.Y; } else { myPoint.x = mouseKoord.X;//The first coordinates myPoint.y = mouseKoord.Y; } } } ReleaseDC( myWnd, myHdc ); visitMsg = TRUE; break; case WM_LBUTTONDOWN: isPainting = TRUE; visitMsg = TRUE; break; case WM_LBUTTONUP: isPainting = FALSE; myPoint.x = -1; myPoint.y = -1; visitMsg = TRUE; break; case WM_RBUTTONDOWN: DeleteObject( whitePen ); DeleteObject( blackPen ); setGlobalVars(); InvalidateRect( myWnd, NULL, TRUE ); visitMsg = TRUE; break; default: break; } if( visitMsg ) return 0; else return DefWindowProc( myWnd, givenMessage, wParam, lParam ); }Min invalidate rect, hackts ur wenn ich das Fenster erneuere... also beim malen zuckt mein "Form" total zusammen
-
Na endlich mal ein bißchen mehr Code... :p
Unter WM_MOUSEMOVE fragst Du keine Koordinaten ab, sondern ordnest nur MouseKoord an MyPoint zu. Das bringt nichts.
Dieser Abschnittif( LOWORD(lParam) != 0 || HIWORD(lParam) != 0) { mouseKoord.X = LOWORD(lParam); //took the mouse-coordinates into a COORD variable (perfomance) mouseKoord.Y = HIWORD(lParam); }gehört auch unter WM_MOUSEMOVE. Sonst werden die aktuellen Koordinaten nicht aus der WM_MOUSEMOVE-Message genommen.
Danach verschiebst Du die Maus und speicherst die neuen Koordinaten in myPoint. Damit hast Du zwei Punkte, die unter WM_PAINT abgefragt werden können.
-
Elektronix schrieb:
Sonst werden die aktuellen Koordinaten nicht aus der WM_MOUSEMOVE-Message genommen.
Diese Koordinaten sollen immer aktuell sein, ob mousemove oder nicht... sie werden überall wieder verwednet, damit ich nicht immer auf LO und HIWORD zurückgreife...
Ob sie da stehen oder in Mousemove... macht dass einen Unterschied?
-
lippoliv schrieb:
Elektronix schrieb:
Sonst werden die aktuellen Koordinaten nicht aus der WM_MOUSEMOVE-Message genommen.
Diese Koordinaten sollen immer aktuell sein, ob mousemove oder nicht... sie werden überall wieder verwednet, damit ich nicht immer auf LO und HIWORD zurückgreife...
Wieso, das tust Du doch ohnehin. Nur eben permanent und ohne Zusammenhang.
Ob sie da stehen oder in Mousemove... macht dass einen Unterschied?
Ja. Das Fenster wird noch mit einem Haufen anderer WM-Nachrichten bombardiert, die in lParam immer andere (oder auch gar keine) Werte enthalten. Damit kannst Du beim Zeichnen nichts anfangen. Die aktuellen Koordinaten bekommst Du nur mit den Mouse- oder Button-Nachrichten (oben aufgezählt), dazu sind die da!
-
Ja ist ja kein Problem oder?
Ich nehme ja nur welche an wo HO oder LO != 0 ist/sind.
Und fürs Zeichnen bekomme ich dann ja immer die Aktuellsten Koordinaten...Ich habe es jetzt umgebaut, und selbst da funktioniert es nicht.
1. Ich kriege keine striche,
2. es zuckt...
-
Programmier doch mal ein Textfeld, wo Du Dir die angeblichen Koordinaten anzeigen läßt. Dann wirste es ja sehen.
-
Ich soll, weil mein Form zuckt und keine Striche erscheinen, ein Textfeld Programmieren?
Ich bin -glaube ich- auf dem so ziemlich untesten Level der Fensterprogrammierung.. ein Textfeld ist da noch weit weg glaube ich.
-
Nö, ein Textfeld ist genau auf dem untersten Level

http://msdn2.microsoft.com/en-us/library/ms632679.aspx
mit EDIT als lpClassName. Ganz einfach, oder?
-
Trotzdem, was sollte mir das Helfen? Das Problem vergeht nicht, während ich ein anderes Programm schreibe.
-
Du kannst auch ein ChildWindow erstellen und darin die Koordinaten per TextOut() ausgeben.
Allerdings scheint es mir, daß Du Dich mit Deinem Malprogramm etwas übernommen hast. Du solltest vielleicht doch noch mal die Tutorials durchackern.

-
Frage: Wieso zeigt mein WM_PAINT nichts an?
Ich habe es genau so gemacht wie ihr es mir verdeutlich habt, also damit nichts verloren geht.Ich speichere die letzte, und die Aktuelle aus WM_MOUSEMOVE und ziehe von der einen zur anderen einen strich.
Wenn ich direkt nach LineTo ein printf( "." ) mache, zeigt er dass in der Konsole auch an...
Wieso malt er dann nicht?
Darauf brauche ich eine antwort, nicht wie ich ein ChildWindow erstelle, Koordinaten ausgebe oder so... << klingt scheiße und aggresiv, ist es aber nicht.
Mich wundert dieser Fehler. Wenn er ja schon in der IF bedingung ist, wieso tut er nicht seine aufgaben....
@Elektronix meintest du ich solle mir Testhalber die Koords ansehen?
myPoint | mousePointForPaint x | y ||| x | y 324 | 430 => 324 430 318 | 413 => 318 413 314 | 401 => 314 401 304 | 372 => 304 372 292 | 336 => 292 336 284 | 320 => 284 320 269 | 276 => 269 276 258 | 244 => 258 244 248 | 214 => 248 214 245 | 204 => 245 204 240 | 189 => 240 189 235 | 175 => 235 175 234 | 168 => 234 168 232 | 156 => 232 156 229 | 145 => 229 145 226 | 135 => 226 135 223 | 126 => 223 126 221 | 122 => 221 122 219 | 114 => 219 114 217 | 110 => 217 110 216 | 106 => 216 106 214 | 104 => 214 104 213 | 101 => 213 101 211 | 100 => 211 100scheint die richtigen coords zu haben
warum sind die alle gleich??
-
1. Das ist falsch:
SendMessage( myAppWnd, WM_PAINT, 0, 0 );Du musst einfach InvalidateRect verwenden.
2. Zeig mal wie Du zeichnest. Ich verstehe nicht ganz warum Du zwei Koordinaten hast. In Deinem Aray musst Du doch immer nur eine neue Mausposition hinten anstellen. Zeichnen tust Du dnan von Punkt zu Punkt.
Zeig mal wie Du WM_MOUSEMOVE und WM_PAINT gebaut hats.
-
scheint die richtigen coords zu haben
warum sind die alle gleich??
Deswegen:
else { if( myPoint.x != -1 ) { SendMessage( myAppWnd, WM_PAINT, 0, 0 ); //send WM_PAINT so that the painting is just standing, if the window will be resized myPoint.x = mouseKoord.X; //set new coordinates myPoint.y = mouseKoord.Y; } else { myPoint.x = mouseKoord.X;//The first coordinates myPoint.y = mouseKoord.Y;@Martin: Er hat den Code eine Seite vorher gepostet.
-
Der Code hat sich verändert:
PAINTSTRUCT myPaint; static POINT myPoint, mousePointForPaint; static RECT myRect; static BOOL isPainting; static COORD mouseKoord; HANDLE backUp; if( LOWORD(lParam) != 0 || HIWORD(lParam) != 0) { mouseKoord.X = LOWORD(lParam); //took the mouse-coordinates into a COORD variable (perfomance) mouseKoord.Y = HIWORD(lParam); } [...] case WM_PAINT: //zum Zeichnen anmelden myHdc = BeginPaint( myWnd, &myPaint ); { if( myPoint.x != -1 ) { backUp = SelectObject( myHdc, *aktPen ); MoveToEx( myHdc, //Zeichenfläche myPoint.x, //X-Koordinate myPoint.y, //Y-Koordinate NULL //old-Koordinate ); LineTo( myHdc, //Zeichenfläche mousePointForPaint.x, //X-Koordinate mousePointForPaint.y //Y-Koordinate ); SelectObject( myHdc, backUp ); } } EndPaint( myWnd, &myPaint ); visitMsg = TRUE; break; case WM_MOUSEMOVE: myHdc = GetDC( myWnd ); //open device-context (paintplace) { if( !isPainting ) //Wenn der { if( inRect( mouseKoord, blackColor ) ) { aktPen = &blackPen; //slect black pen R = 0; G = 0; B = 0; } else if( inRect( mouseKoord, whiteColor ) ) { aktPen = &whitePen; //select white pen R = 255; G = 255; B = 255; } else if( inRect( mouseKoord, smallSize ) ) { DeleteObject( aktPen ); *aktPen = CreatePen( PS_SOLID, 1, RGB( R, G, B ) ); } else if( inRect( mouseKoord, middleSize ) ) { DeleteObject( aktPen ); *aktPen = CreatePen( PS_SOLID, 3, RGB( R, G, B ) ); } else if( inRect( mouseKoord, bigSize ) ) { DeleteObject( aktPen ); *aktPen = CreatePen( PS_SOLID, 4, RGB( R, G, B ) ); } } else { if( myPoint.x != -1 ) { mousePointForPaint.x = mouseKoord.X; mousePointForPaint.y = mouseKoord.Y; InvalidateRect( myWnd, NULL, TRUE); //send WM_PAINT so that the painting is just standing, if the window will be resized myPoint.x = mouseKoord.X; //set new coordinates myPoint.y = mouseKoord.Y; } else { myPoint.x = mouseKoord.X;//The first coordinates myPoint.y = mouseKoord.Y; } } visitMsg = TRUE; } ReleaseDC( myWnd, myHdc ); break;
-
Wo wird isPainting gesetzt?

Die DeleteObject-Blöcke finden nur bei !isPainting statt. Da isPainting nirgends gesetzt wird, ist es vorläufig offenbar immer 0.