AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Schriftart in .exe als Resource einbinden und ohne export auch benutzen.
Thema durchsuchen
Ansicht
Themen-Optionen

Schriftart in .exe als Resource einbinden und ohne export auch benutzen.

Ein Thema von KodeZwerg · begonnen am 21. Sep 2018 · letzter Beitrag vom 2. Apr 2021
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.685 Beiträge
 
Delphi 11 Alexandria
 
#1

Schriftart in .exe als Resource einbinden und ohne export auch benutzen.

  Alt 21. Sep 2018, 12:47
Hallo Gemeinde,

ich hoffe ich gebe mal was brauchbares wieder da ich seit mehreren Stunden, auch mit Hilfe der DP-Suche zu keinem Ziel gekommen bin.
CodeLib ist ja um Beiträge zu leisten für normal User gesperrt, also erst mal hier rein.

Hier die Ausgangs-Situation:
Man möchte eine Schriftart (in meinem Fall eine .TTF Datei) in die .exe integrieren und logischerweise auch benutzen.
Ich fand sehr viele Beispiele die diese Font irgendwo zwischenspeichern um sie dann zu Nutzen.
Meist waren diese Beispiele mit einer Globalen SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0); verbunden.

Das liegt alles weit ab von dem was ich erreichen wollte.

Hier eine mini Anleitung wie man mit Delphi eine Font einbindet und darauf zugreift ohne das die Font irgendwo extern gespeichert werden muss. Vielleicht fallen euch ja noch andere Möglichkeiten ein, da würde ich mich freuen diese Kennenzulernen!



Schritt 1:
Das erzeugen einer .RES Datei, dies ist der wichtigste Schritt, denn ohne den hat man Pustekuchen.
Mir gelingt dies am einfachsten mit einem x-Beliebigen Editor, Notepad++ ist bei mir im Einsatz.
Erzeugt also eine leere Datei mit folgenden Inhalt FONTNAME FONTS "Name der.ttf"
Dabei steht FONTNAME als Identifizierer innerhalb der Resource.
Dabei steht FONTS als Resourcenverzeichniss.
Und der Dateiname sollte so sein wie er ist, gültig.
Speichert die Datei als "MyFonts.rc" ab.
Öffnet eine CMD und gebt BRCC32 MyFonts.rc ein plus Eingabetaste.
Wenn alles gut gegangen ist hat man nun eine "MyFonts.res" Datei, yippieh!

-Schritt 1 = erledigt



Schritt 2:
Öffnet ein Projekt wo ihr die Font braucht oder fangt ein komplett neues an, beides geht.
Unter der Zeile implementation fügt ihr diese Zeile ein {$R MyFont.res}
Damit landet die Font auch in der .exe, ohne das geht nichts.

-Schritt 2 = erledigt



Schritt 3:
Jetzt muss man Windows und der Anwendung auch irgendwie mitteilen das es diese Font überhaupt gibt, ich mache es so:


Das hier wird global gebraucht, ich habs in der Class Definition drinnen:
Delphi-Quellcode:
  private
    { Private declarations }
    FontHandle: THandle;
  public
Hier der Helfer der die Font einbindet:
Delphi-Quellcode:
function LoadResourceFontByName(const ResourceName: string; ResType: PWideChar): THandle;
var
  ResStream : TResourceStream;
  FontsCount : DWORD;
begin
  ResStream := TResourceStream.Create(hInstance, ResourceName, ResType);
  try
    Result := AddFontMemResourceEx(ResStream.Memory, ResStream.Size, nil, @FontsCount);
  finally
    ResStream.Free;
  end;
end;
Im Konstruktor die Font Laden:
(als Anwendungsbeispiel habe ich ein Label genommen)
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  FontHandle := LoadResourceFontByName('FONTNAME', 'FONTS');
  if FontHandle <> 0 then Label1.Font.Name := 'Wie lautet der Name der Font?';
end;
Im Destruktor die Font freigeben:
Delphi-Quellcode:
procedure TForm1.FormDestroy(Sender: TObject);
begin
  RemoveFontMemResourceEx(FontHandle);
end;


Das wars auch schon, 3 kleine Schritte und man ist am Ziel.

Viel Spaß dabei!


Ps:
mit Label1.Font.Name := 'Wie lautet der Name der Font?'; ist weder der Dateiname noch der Resourcenname gemeint, sondern der Name der Fest in der .TTF hinterlegt ist! (am einfachsten für mich jedenfalls, mit TotalCommander auf .TTF Datei gehen und F3 drücken, da unter "Font bzw ID" schauen, je nach dem)

Hinweis:
Wenn man die geladene Font im kompletten Programm haben/nutzen möchte, sollte man if FontHandle <> 0 then Font.Name := 'Wie lautet der Name der Font?'; es so im Konstruktor anmelden und alle Komponenten die diese auch bekommen sollen, müßten ParentFont = True in deren Property stehen haben.
Gruß vom KodeZwerg

Geändert von KodeZwerg (21. Sep 2018 um 13:58 Uhr)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.110 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.

  Alt 21. Sep 2018, 12:51
Ich habe direkt eine Frage zu Schritt 1 und 2:

Kann man nicht genauso Datei -> Neu -> Textdatei -> .rc-Datei und es dort hineinschreiben? Damit gehört die Datei zum Projekt und die IDE kümmert sich bei jedem Kompilieren darum dass die .res-Datei vorliegt.
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.685 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.

  Alt 21. Sep 2018, 12:52
Superwichtig, macht Euch im VORFELD von dem Copyright & Bedingungen der Font schlau, man darf nicht alles einfach so machen!
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.685 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.

  Alt 21. Sep 2018, 12:55
Ich habe direkt eine Frage zu Schritt 1 und 2:

Kann man nicht genauso Datei -> Neu -> Textdatei -> .rc-Datei und es dort hineinschreiben? Damit gehört die Datei zum Projekt und die IDE kümmert sich bei jedem Kompilieren darum dass die .res-Datei vorliegt.
Probiere es doch einfach aus? ^_^
Jeder hat da so seine Vorlieben wie was womit usw, ich nannte halt die Methode die für mich Okay ist.
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.110 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.

  Alt 21. Sep 2018, 12:57
Die Variable FontsCount ist überhaupt nicht initialisiert!
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#6

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.

  Alt 21. Sep 2018, 13:00
Die Variable FontsCount ist überhaupt nicht initialisiert!
Dafür FontHandle sogar zweimal Ne glaube aber FontsCount ist ein reiner out Parameter, also muss nicht zwingend initialisiert werden.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#7

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.

  Alt 21. Sep 2018, 13:03
Nun ja, man findet schon etwas

https://www.delphipraxis.net/194521-...-resource.html
https://stackoverflow.com/questions/...-resource-file
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.685 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.

  Alt 21. Sep 2018, 13:10
Die Variable FontsCount ist überhaupt nicht initialisiert!
Wozu auch?
Dafür FontHandle sogar zweimal
Sorry, lösch das FontHanlde := 0 und gut ist.

Verzeihung falls doppelt. Dann los Admins, löscht das schnell wieder.
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#9

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.

  Alt 21. Sep 2018, 13:14
Ich finde es unnötig Fonts in die Resource einzubinden bin da lieber flexibel falls ich ihn doch mal schnell ändern möchte.
Aber wie du sagst jedem das sein.

Ich erstelle den Font indirekt ohne ihn extra zu registrieren und verwende ihn dann.
Besser wäre auch noch den Font Namen selbst zurückzugeben anstatt ihn zu übergeben.

Delphi-Quellcode:
function GDIP_PrivateFontCollection(var FontCollection: Pointer
): GPSTATUS; stdcall;
begin

  PrvFontCollection := TGPPrivateFontCollection.Create;
  FontCollection := PrvFontCollection.nativeFontCollection;
  result:= PrvFontCollection.GetLastStatus;
end;
Delphi-Quellcode:
function GDIP_PrivateAddFontFile(filename: PWideChar
): GPSTATUS; stdcall;
begin

  result := PrvFontCollection.AddFontFile(filename);
end;
Delphi-Quellcode:
function GDIP_GdipGetFontCollectionFamilyCount(var count: Integer
): GPSTATUS; stdcall;
begin

  count := PrvFontCollection.GetFamilyCount;
  result:= PrvFontCollection.GetLastStatus;
end;
Delphi-Quellcode:
function GDIP_FontFamilyCreate(Count: Integer; var pFontFamily: array of TGPFontFamily
): GPSTATUS; stdcall;
var
  numFound: Integer;
  FontFamily: array of TGPFontFamily;
begin

  SetLength(FontFamily, Count + 1);
  FontFamily[Count] := TGPFontFamily.Create;

  result:= FontFamily[Count].GetLastStatus;

  GDIP_GetFamilies(Length(FontFamily), FontFamily, numFound);
  pFontFamily[Count] := FontFamily[Count];
end;
Delphi-Quellcode:
function GDIP_GetFamilies(numSought: Integer; out gpfamilies: array of TGPFontFamily;
  out numFound: Integer
): GPSTATUS; stdcall;
begin

  result := PrvFontCollection.GetFamilies(numSought, gpfamilies, numFound);
end;
Delphi-Quellcode:
function TSkinEngine.LoadPrivateFontCollection(Path: string; var FontCollection: Pointer;
  var FontName: string
): GPSTATUS; stdcall;
var
  i: integer;
  Count: integer;
  gFontFamily: array of TGPFontFamily;
begin
  Result := GenericError;
  if FileExists(Path) then
  begin
    GDIP_PrivateFontCollection(FontCollection);
    GDIP_PrivateAddFontFile(PWideChar(Path));
    GDIP_GdipGetFontCollectionFamilyCount(Count);
    SetLength(gFontFamily, Count + 1);

    for i := 0 to Count - 1 do
      GDIP_FontFamilyCreate(i, gFontFamily);

    for i := 0 to count - 1 do
      // Get the font family name.
      gFontFamily[i].GetFamilyName(FontName);

    Result := OK;
  end;
end;
Bsp.
Delphi-Quellcode:
    if not Assigned(TTFCaption) then
      GDIP_LoadPrivateFontCollection(SpriteResPath + 'lcd.ttf', TTFCaption, FontCaption);
gruss

Geändert von EWeiss (21. Sep 2018 um 13:22 Uhr)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.110 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.

  Alt 21. Sep 2018, 13:14
Stimmt, ich habe in der Doku nicht gesehen dass der Parameter wohl wirklich ein reiner out-Parameter ist. Normalerweise steht das immer schön drin.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:27 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz