Text auf Canvas ausgeben
-
Ich habe hier ein DirectX Programm, wo ich Text so ausgebe:
HDC hDC; HFONT font; // DC für die Oberfläche anfordern if(FAILED(lpDDSurf->GetDC(&hDC))) { Error("DC(Text) ist nicht verfügbar"); return ; } // Texthintergrund = TRANSPARENT SetBkMode(hDC, TRANSPARENT); // Textfarbe SetTextColor(hDC, TextColor); // Text linksbündig ausrichten SetTextAlign(hDC, TA_LEFT); LOGFONT lgf; lgf.lfHeight=-MulDiv(Height, GetDeviceCaps(hDC, LOGPIXELSY), 72); lgf.lfWidth=Width; // lgf.lfWidth=-MulDiv(Width, GetDeviceCaps(hDC, LOGPIXELSX), 72); lgf.lfEscapement=Winkel*10; lgf.lfOrientation=0; lgf.lfWeight=FW_NORMAL; lgf.lfItalic=Italic; lgf.lfUnderline=Underline; lgf.lfStrikeOut=FALSE; if (CharSet==0) lgf.lfCharSet=ANSI_CHARSET; else if (CharSet==1) lgf.lfCharSet=SYMBOL_CHARSET; lgf.lfOutPrecision=OUT_TT_ONLY_PRECIS; lgf.lfClipPrecision=CLIP_MASK; lgf.lfQuality=PROOF_QUALITY; lgf.lfPitchAndFamily=DEFAULT_PITCH; strcpy(lgf.lfFaceName,FontName); font=CreateFontIndirect(&lgf); SelectObject(hDC,font); // Text ausgeben TextOut(hDC,+ax, ay, string, strlen(string)); // Oberfläche wieder freigeben lpDDSurf->ReleaseDC(hDC); DeleteObject(font);Jetzt wollte ich im CBuilder auch eine solche Funktion schaffen:
Canvas->Font->Name = FontName; Canvas->Font->Size = Height; Canvas->Font->Color = TColor(TextColor); Canvas->Brush->Style = bsClear; if (CharSet==0) Canvas->Font->Charset = ANSI_CHARSET; else if (CharSet==1) Canvas->Font->Charset = SYMBOL_CHARSET; Canvas->TextOut(ax, ay, Text);Mein Problem ist jetzt das ich hier im CBuilder nicht die "Weite/Width" der Schrift setzen kann (zumindest nicht gefunden). Damit die Schrift etwas gepresster ist und in eine Ausgabe passt.
Also versuchte ich den obigen WIN32 Code anzupassen für CBuilder.
HDC hDC = GetDC(Canvas->Handle); HFONT font; // Texthintergrund = TRANSPARENT SetBkMode(hDC, TRANSPARENT); // Textfarbe SetTextColor(hDC, TextColor); // Text linksbündig ausrichten SetTextAlign(hDC, TA_LEFT); LOGFONT lgf; lgf.lfHeight=-MulDiv(Height, GetDeviceCaps(hDC, LOGPIXELSY), 72); lgf.lfWidth=Width; // lgf.lfWidth=-MulDiv(Width, GetDeviceCaps(hDC, LOGPIXELSX), 72); lgf.lfEscapement=Winkel*10; lgf.lfOrientation=0; lgf.lfWeight=FW_NORMAL; lgf.lfItalic=Italic; lgf.lfUnderline=Underline; lgf.lfStrikeOut=FALSE; if (CharSet==0) lgf.lfCharSet=ANSI_CHARSET; else if (CharSet==1) lgf.lfCharSet=SYMBOL_CHARSET; lgf.lfOutPrecision=OUT_TT_ONLY_PRECIS; lgf.lfClipPrecision=CLIP_MASK; lgf.lfQuality=PROOF_QUALITY; lgf.lfPitchAndFamily=DEFAULT_PITCH; strcpy(lgf.lfFaceName,FontName); font=CreateFontIndirect(&lgf); SelectObject(hDC,font); // Text ausgeben TextOut(hDC, ax, ay, Text.c_str(), Text.Length()); // Oberfläche wieder freigeben ReleaseDC(0,hDC); DeleteObject(font);Aber hier gibt er lieder garkeine Schrift aus..
Kann mir jemand vielleicht helfen im 2. ein Width einzufügen bzw im 3. Quelltext laufend zu bekommen?
-
Hallo
Mein Problem ist jetzt das ich hier im CBuilder nicht die "Weite/Width" der Schrift setzen kann (zumindest nicht gefunden). Damit die Schrift etwas gepresster ist und in eine Ausgabe passt.
Die Breite eines Textes im aktuellen Convas-Font kannst du mit TCanvas::TextWidth herausfinden. Du könntest dann den Rückgabewert mit dem verfügbaren Platz vergleichen und entweder einen kleineren Font wählen, oder den Text erstmal in einen Buffer-Bitmap zeichen und dieses Bitmap dann nötigenfalls gestaucht in das eigentliche Zielcanvas übertragen.
Allerdings ist beides aus Sicht der Performance schlecht. Normalerweise wird bei solchem Design darauf geachtet, das der Text immer in den Platz past. Das führt bei unüberlegten Design auch zu den seltsamen Abkürzungen bei (deutschen) Übersetzungen, weil im englischen meist weniger Platz für den gleichen Text gebraucht wird.
bis bald
akari
-
In diesem Fall geht es um einen neutralen Text, sprich feste Begriffe. Der Text soll aber eine feste Höhe haben und lediglich wie momentan im DirectX Programm reinpassen. Der Font den ich dafür nutze passt perfekt, jetzt einen Font suchen zu müssen der hoch ist, aber nicht zu breit und passend zum Programm, wäre jetzt bissle happig und wohl eine Aufgabe von Tagen.
Schade, ich dachte es gebe eine einfachere Lösung.
Kann mir jemand bitte sagen warum das WIN32 Beispiel mit dem Canvas nicht funktioniert? Irgendwie will er keinen Text ausspucken.

-
Um mal den Code zu vereinfachen

HDC hDC = GetDC(Image1->Canvas->Handle); TextOut(hDC, 10, 10, "xxx", 3);Auf dem Image1 ist aber nichts zu sehen. Funktioniert hier GetDC nicht? Auch Handle über Image1->Picture->Bitmap->Handle brachte keinen Erfolg. Das muss doch aber irgendwie gehen

-
Wozu nimmst du hier GetDC? Probiers mal so.
TextOut(Image1->Canvas->Handle, 10, 10, "xxx", 3);
-
HANDLE hDC = Canvas->Handle;Ah, vielen Dank! Klappt Super.
Aber wieso kann ich mit GetDC(Canvas) das Handle nicht ermitteln?
-
Soweit ich weiß ermittelt GetDC den DeviceContext zu einem gegebenen Windowshandle. Nun ist TCanvas::Handle ja schon ein DeviceContext. Desweiteren ist TCanvas ja kein Window (bzw. von einer solchen Klasse abgeleitet).
Das ganze Problem rührt hier daher, dass bei der VCL alles Handle genannt wird wobei aber unterschiedliche Sachen dahinterstehen können. Du mußt halt immer mal wieder in die Hilfe zu Handle der jeweiligen Klasse schauen um zu sehen was dahinter steht.
Hier ein Auszug aus der Hilfe zu TCanvas::HandleBeschreibung
Die Eigenschaft Handle gibt das Windows-GDI-Handle des Gerätekontextes für diese Zeichenfläche an.
und hier TWinControl::Handle
Description
Use the Handle when making Windows API function calls that requires a window handle.
Wie du siehst zwei verschiedenen Dinge mit dem gleichen Namen.
Ciao
-
Ahaa
Danke!