Benutzerdefinierter Font

fujitsufan

Erfahrenes Mitglied
Hallo,

jetzt weiß ich nicht mehr weiter.
Ich möchte auf benutzerdefinierte Fonts zugreifen.
Auf Windows Fonts zugreifen ist ja klar.

Funktion
Code:
HFONT hf = CreateFont(,,,,,,,"Arial")
aufrufen.

Wie stelle ich das an, dass ich auf eine Liste eigener Fonts zugreifen kann.
Eine Liste erstellen ist auch noch einfach.
Aber wie greife ich auf diese Liste zu? Die Fonts liegen doch außerhalb des Verzeichnisses C:\Windows\Fonts\...
Kann ich irgendwie bei der o.g. Funktion eine Pfadangabe als Übergabeparameter mit anhängen?

Letztendlich gelange ich an die Funktion ::SendMessage(this->HWindow, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)cf);
cf ist vom Typ CHARFORMAT.

Das bringt mich auch nicht weiter, da wird ja wiederum auf das Standardverzeichnis der Windows Fonts zugegriffen, oder!?

Kann mir da jemand weiterhelfen?
mfG.
fujitsufan
 
Hallo,
eine Liste der Fonts exitiert bereits in meinem Projekt. Und zwar mit:
Code:
if ( CreateScalableFontResource ( 0 , Fontdatei.fot , Dateipfad.ttf , NULL ) ) // Fontresource aus TBF Datei erzeugen
{
    {
      if ( AddFontResource ( Fontdatei.fot ) )
    }
}

Wie kann ich aus meiner Klasse GDIplus auf diese exisitierende Liste zugreifen?
Code:
graphics.DrawString(StringUtilities::toWString(textToDraw).c_str()
                                 , textToDraw.length()
                                 , &myFont
                                 , layoutRect
                                 , &format
                                 , &brush);

Der Parameter myFont ist mir nicht verständlich.

mfG.
fujitsufan
 
Dabei handelt es sich um einen Zeiger auf ein Font-Objekt. Das kannst du auf verschiedene Arten erstellen. Die einfachste ist sicher via PrivateFontCollection.
C++:
Gdiplus::PrivateFontCollection pfc;
if(pfc.AddFontFile(L"C:\\MyFont.ttf") != Gdiplus::Ok)
   ; // error handling

if(pfc.GetFamilyCount() == 0)
   ; // error handling

Gdiplus::FontFamily fontFam;
int nFound = 0;
if(pfc.GetFamilies(&fontFam, 1, &nFound) != Gdiplus::Ok || nFound != 1)
   ; // error handling

Gdiplus::Font myFont(&fontFam, 16);
...
 
Hallo,
noch ´ne Frage.

Wenn ich aber die Fonts wie beschrieben zur System-Schrift-Tabelle hinzugefügt habe, müsste ich doch anschließend von jeder Anwendung drauf zugreifen können.
So ist es mal in der Windows Hilfe unter unter "AddFontResource" beschrieben.

Mit der GDIplus Klasse finde ich diesen Font aber nicht.

Code:
Font myFont(StringUtilities::toWString(Name).c_str(), fontSize);

Code:
Font::Font(
     IN const WCHAR *          familyName,
     IN REAL                   emSize,
     IN INT                    style,
     IN Unit                   unit,
     IN const FontCollection * fontCollection
)
{
    nativeFont = NULL;

    FontFamily family(familyName, fontCollection);
    GpFontFamily *nativeFamily = family.nativeFamily;

    lastResult = family.GetLastStatus();

Habe ich da noch irgend etwas vergessen oder übersehen?
Muss ich den fehlenden Font noch in das Verzeichnis C:\Windows\Fonts\... kopieren?

mfG.
fujitsufan
 
Eigentlich musst du das nicht, dieFont wird über AddFontResource eingetragen. Alles was man noch tun sollte damit es auch sauber geupdatet ist wäre WM_FONTCHANGED an alle top-level Fenster zu senden (HWND_BROADCAST).

Ausserdem ist es bei deinem Code jetzt etwas schwer ersichtlich was jetzt wozu gehört da du keine Namespaces verwendest. Der angegebene Konstruktor passt ausserdem nicht mit dem überein, den du gepostet hast. Gibt es da noch Default-Parameter?

Ist der familyName korrekt? Hast du das schon geprüft?
 
Hallo,
nochmals vielen Dank für die Tipps. Das mit C++ mache ich erst seit diesem Jahr.
Mir fehlt gerade noch der Überblick.

Muss die Bekanntgabe der Fonts in der System-Schrift Tabelle in der gleichen Klasse erfolgen wie der anschließende Zugriff?

Nach Bekanntgabe der Fonts in der System-Schrift Tabelle habe ich die Meldung erstellt.
Code:
SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
In der Klasse "GdiPlusBitmap" möchte ich einen Text mit einem bestimmten Font ausgeben.
Ich hatte an die Funktion gedacht:
Code:
Status status = graphics.DrawString(
            StringUtilities::toWString(textToDraw).c_str(), textToDraw.length(), &myFont,
            layoutRect, &format, &brush);
Entschuldige die blöde Frage, aber wie kommen ich an den Font "myFont" ran.
Kann ich die System-Schrift Tabelle prüfen bzw. anzeigen?
Ich habe versucht ein Fontobjekt vom Typ HFONT zu erstellen und dieses in GDI+ Font zu konvertieren.
Leider ohne Erfolg.

Code:
string Font = "Times New Roman";
HFONT hFont;
hFont=CreateFont(-ih,0,rot,0,FW_NORMAL,0,0,0,0,0,16,0,0,Font);

Gdiplus::Font myFont(graphics.GetHDC(), hFont);
"hFont" gibt zwar eine Adresse zurück zeigt aber im Debugger Kontext "unused" an.


mfG.
fujitsufan
 
Das "unused" ist schon korrekt, HFONT ist ein opaker Zeiger. Du musst aber nicht den Umweg über ein HFONT-Objekt gehen:
C++:
Gdiplus::Font myFont(L"Times New Roman", 16, Gdiplus::FontStyleRegular, Gdiplus::UnitPoint, NULL);
 
Hallo,
bleiben die Fonts in der System-Schrift Tabelle erhalten wenn ich mein Programm beende, bzw. meinen Rechner neu starte?

Wenn ich mein Programm neu starte und bewusst die Einträge in der System-Schrift Tabelle unterlasse, dann findet meine Anwendung die Fonts ebenfalls.
Allerdings mit folgendem Code:
Code:
BOOL IsFontEmbedded(HDC DC,char *FontName)
{
  FONTENUMPROC lpEnumFontsCallBack;
  BOOL Embedded;

  Embedded=TRUE;
  lpEnumFontsCallBack=(FONTENUMPROC)MakeProcInstance((FARPROC)EnumFontsCallBack,hInstance);

  // MP: (char *)&Em.. --> (LPARAM)&Emb..
#ifdef WIN32
#ifndef __GNUG__
  EnumFonts(DC, FontName, lpEnumFontsCallBack, (LPARAM)&Embedded);
#endif
#else
  EnumFonts(DC, FontName, lpEnumFontsCallBack, (char *)&Embedded);
#endif


  FreeProcInstance((FARPROC) lpEnumFontsCallBack);

  return Embedded;
}

int CALLBACK EnumFontsCallBack(LOGFONT FAR* lplf,NEWTEXTMETRIC FAR* lpntm,int FontType,LPARAM lpData)
{
  *((BOOL*)lpData)=FALSE; // Gefunden, dann NICHT embedded
  return 0;
}

Momentan bin ich auf Stufe 4.
Es geht nichts und ich weiss nicht warum.

mfG.
fujitsufan
 
Zurück