DrawString() - nichts passiert - was ist falsch?
-
Hallo,
ich verusche gerade mit DrawString() aus der GDI+ einen text auf den Bildschirm zu zeichnen. Der Code kompilert fehlerfrei, nur leider passiert einfach gar nichts statt dass ein text am bilschirm erscheint. was ist an meinem Coide denn falsch?void text_zeichnen(WCHAR* text) { Graphics graphics(hdc); // 04 SolidBrush brush(Color(255, 255, 0, 0)); Font font(hdc); PointF point(100, 100); RectF rect(100, 100, 100, 100); graphics.DrawString(text,10, &font, rect, NULL, &brush); } int main() { for(;;) { system("cls"); GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); // 02 cout<<"text am bildschirm zeichnen:\n"; cout<<"geben Sie den text ein! (statt Leerstelle _ verwenden!\n"; wstring text1; wcin>>text1; text_zeichnen((&text1[0])); // ... GdiplusShutdown(gdiplusToken); // 03 getch(); } }danke schonmal,
andi01.
-
Was ist hdc und wie wird es initialisiert? Wird es überhaupt initialisiert?
&text1[0] ist übrigens keine gute Idee. Es ist weder garantiert, dass std::(w)string seinen Inhalt am Stück speichert, noch dass er automatisch nullterminiert ist. Dafür gibt es die Methode c_str.
-
zu hdc: es wurde so global initialisiert:
HDC hdc=GetWindowDC(GetDesktopWindow());&text1[0] ist übrigens keine gute Idee. Es ist weder garantiert, dass std::(w)string seinen Inhalt am Stück speichert, noch dass er automatisch nullterminiert ist. Dafür gibt es die Methode c_str.
wenn ich (&text1[0]) durch (text1.c_str()) ersetze gibt der Kompiler folgende Fehlermeldung aus:
Compiler schrieb:
error C2664: 'text_zeichnen': Konvertierung des Parameters 1 von 'const wchar_t *' in 'WCHAR *' nicht möglich
was muss ich denn dann noch verändern?
mfg,
andi01.
-
andi01 schrieb:
was muss ich denn dann noch verändern?
Wie du siehst, gibt c_str() einen const wchar_t* zurück. Auf diesen Typ müsstest du also auch den Parameter von text_zeichnen ändern. Oder soll die Funktion den String verändern?
Was dein Problem angeht: Ich glaube nicht, dass der Font so richtig angelegt wird. Falls nämlich in diesen DC gerade kein Font selektiert ist, geht das in die Hose. Und ich glaube auch nicht, dass du als StringFormat NULL angeben darfst.
So oder so solltest du den Rückgabewert von DrawString prüfen, um den Fehler einzugrenzen, dazu ist er da.
-
MFK schrieb:
Wie du siehst, gibt c_str() einen const wchar_t* zurück
was das mit dem const angeht habe ich jetzt mal einen const_cast verwendet, man weiß ja nie ob man mal was an dem string ändern muss, so lasse ich mir diese möglichkeit offen. das programm kompilert auch fehlerfrei.
MFK schrieb:
So oder so solltest du den Rückgabewert von DrawString prüfen, um den Fehler einzugrenzen, dazu ist er da.
Der Rückgabewert lautet 2, keine Ahnung was das heißt^^.
MFK schrieb:
Ich glaube nicht, dass der Font so richtig angelegt wird. Falls nämlich in diesen DC gerade kein Font selektiert ist, geht das in die Hose. Und ich glaube auch nicht, dass du als StringFormat NULL angeben darfst.
ich denke auch dass bei den parametern etwas falsch sein muss, ich auch schonmal zB nach StringFormat gegoogelt, aber leider kein brauchbares Beispiel gefunden

wie muss ich denn die 2 Parameter Font und vor allem StringFormat richtig initialisieren?
mfg,
andi01.
-
Beispiel-Code gibts z.B. in der msdn:
http://msdn.microsoft.com/en-us/library/ms533821(VS.85).aspx
-
ok, danke, ich habe jetzt meinen code schonmal soweit gebracht dass er etwas auf den Bildschirm schreib

aber wenn er nur ein wort schreiben soll kommen einige Vierecke nach dem Wort?!
hier mal ein kleiner screen: http://rapidshare.de/files/48962564/screen_drwastring.bmp.htmlund hier nochmal mein verbesserter Code(die dekleration von hdc ist gleichgeblieben):
void text_zeichnen(WCHAR* text) { Graphics graphics(hdc); // 04 SolidBrush brush(Color(255, 255, 0, 0)); PointF point(100, 100); RectF rect(100, 100, 700, 700); FontFamily fontFamily(L"Times New Roman"); Font font(&fontFamily, 24, FontStyleRegular, UnitPixel); StringFormat* format; Gdiplus::Status status; status=graphics.DrawString(text,10, &font, rect, NULL, &brush); cout<<"Status: "<<status<<endl; } int main() { for(;;) { system("cls"); GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); // 02 cout<<"text am bildschirm zeichnen:\n"; cout<<"geben Sie den text ein! (statt Leerstelle _ verwenden!\n"; wstring text1; wcin>>text1; text_zeichnen(const_cast<WCHAR*>(text1.c_str())); // ... GdiplusShutdown(gdiplusToken); // 03 getch(); } }woran liegt das mit den Rechtecken und kann man das vielleicht noch irgendwie beheben?
mfg,
andi01.
-
Kommt vermutlich von der Länge 10 die du da angegeben hast:
status=graphics.DrawString(text,[b]10[/b], &font, rect, NULL, &brush);Ich nehme mal an das .c_str() auch bei wchar's einen Null-Terminierten String liefert - Dann kannst du statt der 10 einfach -1 oder lstrlen(text) angeben...
-
geeky schrieb:
Dann kannst du statt der 10 einfach -1 oder lstrlen(text) angeben...
danke, ich habs jetzt mit lstrlen(text) gelöst
.kann man den string eigentlich auch wieder über die gdi vom bildschirm löschen? denn wenn man mehrere strings hinschreibt und muss den ganzen Desktop neu zeichnen sind ja sonst alle weg^^
mfg,
andi01.
-
Gezeichnet ist gezeichnet

Je nachdem was du da bastelst ist evtl. ein transparentes Fenster wo du reinzeichnest oder z.B. für Vista/Win7 nen Gadget besser geeignet...
-
hm dh es gibt keinen löschbefehl wie DeleteString() oder so?
kann man wenn man das Objekt Brush initialisiert bei der Farbe vielleicht einfach NULL angeben?
mfg,
andi01.
-
Ein DeviceContext (hdc, quasi die Zeichenfläche die benutzt wird) ist wie ein Stück Papier und man hat nur Permanent-Liner etc. zur Verfügung

D.h. um etwas zu löschen muss man sich gemerkt haben was vorher dort war und es genauso neu zeichnen.(Mit InvalidateRect() z.B. kann man einem Fenster mitteilen "yo, zeichne dich mal bitte neu!")
-
ja aber bei InvalidateRect() gehen alle gezeichneten strings verloren

kann man vielleicht irgendwie nur einen teil des fensters neu zeichnen?
mfg,
andi01.
-
Bei InvalidateRect() kann man als zweiten Parameter den neu zu zeichnenden Bereich angeben.
Das Fenster das sich da teilweise neuzueichnen soll kann das ignorieren (und tut das auch nicht selten)Sprich: Nein, geht nicht.
Ist halt wie ein mspaint ohne Rückgängig-Funktion