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::Handle

    Beschreibung

    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!


Anmelden zum Antworten