Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Schriftart in .exe als Resource einbinden und ohne export auch benutzen. (https://www.delphipraxis.net/197957-schriftart-exe-als-resource-einbinden-und-ohne-export-auch-benutzen.html)

KodeZwerg 21. Sep 2018 12:47

Schriftart in .exe als Resource einbinden und ohne export auch benutzen.
 
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
Delphi-Quellcode:
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
Delphi-Quellcode:
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
Delphi-Quellcode:
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
Delphi-Quellcode:
implementation
fügt ihr diese Zeile ein
Delphi-Quellcode:
{$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
Delphi-Quellcode:
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
Delphi-Quellcode:
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
Delphi-Quellcode:
ParentFont = True
in deren Property stehen haben.

Der schöne Günther 21. Sep 2018 12:51

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.
 
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.

KodeZwerg 21. Sep 2018 12:52

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.
 
Superwichtig, macht Euch im VORFELD von dem Copyright & Bedingungen der Font schlau, man darf nicht alles einfach so machen!

KodeZwerg 21. Sep 2018 12:55

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

Zitat von Der schöne Günther (Beitrag 1413821)
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.

Der schöne Günther 21. Sep 2018 12:57

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.
 
Die Variable FontsCount ist überhaupt nicht initialisiert! :warn:

Zacherl 21. Sep 2018 13:00

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

Zitat von Der schöne Günther (Beitrag 1413825)
Die Variable FontsCount ist überhaupt nicht initialisiert! :warn:

Dafür
Delphi-Quellcode:
FontHandle
sogar zweimal :-D Ne glaube aber
Delphi-Quellcode:
FontsCount
ist ein reiner
Delphi-Quellcode:
out
Parameter, also muss nicht zwingend initialisiert werden.

Schokohase 21. Sep 2018 13:03

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.
 
Nun ja, man findet schon etwas

https://www.delphipraxis.net/194521-...-resource.html
https://stackoverflow.com/questions/...-resource-file

KodeZwerg 21. Sep 2018 13:10

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

Zitat von Der schöne Günther (Beitrag 1413825)
Die Variable FontsCount ist überhaupt nicht initialisiert! :warn:

Wozu auch?
Zitat:

Zitat von Zacherl (Beitrag 1413826)
Dafür
Delphi-Quellcode:
FontHandle
sogar zweimal :-D

Sorry, lösch das FontHanlde := 0 und gut ist.

Zitat:

Zitat von Schokohase (Beitrag 1413827)

Verzeihung falls doppelt. Dann los Admins, löscht das schnell wieder.

EWeiss 21. Sep 2018 13:14

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.
 
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

Der schöne Günther 21. Sep 2018 13:14

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.
 
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. :|

KodeZwerg 21. Sep 2018 13:29

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

Zitat von EWeiss (Beitrag 1413831)
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.

Na genau deswegen habe ich doch diesen Thread erstellt, um auch andere Ansichten / Möglichkeiten zu erfahren, abgesehen von Post #1.
Also Danke Dir für diese Variante!

EWeiss 21. Sep 2018 13:34

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

Ich finde es unnötig Fonts in die Resource einzubinden
Sagen wir besser es ist flexibler kommt halt auf den Verwendungszweck an welche Variante man verwenden möchte. ;)
Es gibt ja immer mehrerer Varianten.

gruss

KodeZwerg 21. Sep 2018 18:04

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.
 
Liste der Anhänge anzeigen (Anzahl: 1)
Eine weitere Möglichkeit eine Font in einer .exe abzulegen wäre so...
So kann keiner auf die schnelle die Font extrahieren da sie nun nicht mehr in Resource liegt.


Anleitung:
kopiert die Font in Euer Projekt-Root rein.
entpackt die Datei im Anhang auch dahin.
öffnet eine CMD und ruft bin2inc "Name der Font-Datei" auf.
nun solltet ihr eine "Dateiname.inc" erhalten haben.

für dieses Beispiel nehmen wir an Datei lautet MyFont.ttf die nun MyFont.inc geworden ist und in der das Array auch so heißt.
ihr könnt/müßt sogar manchmal die .inc umbennen und bearbeiten wenn original dateiname als array-bezeichner unzulässig ist.
bin2inc ist halt für generellen krams da, nicht explizit für font integration.

startet Delphi mit Eurem Projekt.
fügt unter
Delphi-Quellcode:
implementation
diese zeile ein:
Delphi-Quellcode:
{$I MyFont.inc}

nun brauchen wir auch noch eine funktion die uns die font bereit stellt, das mache ich so:
Delphi-Quellcode:
function LoadInternalFont: THandle;
var
  FontsCount : DWORD;
begin
  Result := AddFontMemResourceEx(@MyFont, Length(MyFont), nil, @FontsCount);
end;
ersetzt halt "MyFont" mit euren namen.
so hier könnte man es benutzen:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  FontHandle := LoadInternalFont;
  if FontHandle <> 0 then Label1.Font.Name := 'Name der Font?';
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  RemoveFontMemResourceEx(FontHandle);
end;

edit
ps:
nicht erschrecken, dateigröße von .inc ist idR sehr viel größer aber keine bange, im kompilat ist es wieder binär.
also größentechnisch ist da kein doller unterschied ob per resource oder intern/direkt in .exe

MicMic 28. Mär 2021 10:01

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.
 
Hallo,
ich suche gerade eine einfache Möglichkeit um Symbole zu nutzen, die in verschiedenen Größen dann auch gut aussehen. Also skalierbar sind und auch einfach in Farben geändert werden können. SVG würde ich gerne nutzen aber ich möchte einfach keine fremden Komponenten nehmen. Mir sind die meist viel zu unübersichtlich, sprich 5 PAS-Dateien oder Source-Abschnitte die ich gar nicht dann aufrufe. Und verstehen will ich das ganze dann auch immer. Da mach ich stets lieber alles selbst ;-) Also mir kam gerade die Idee wegen IconFonts, die so im Web genutzt werden. Also bin ich auf diesem Beitrag gestoßen, da es hier wichtig ist, eine TTF in der EXE einzubinden und nicht in Windows zu registrieren. Also damit einfach stets die Symbole vorhanden sind und sie in meinem Programm angezeigt werden können.

Wie schon erwähnt, mit fremden TTFs darf man nicht alles machen. Jetzt habe ich noch "fontello.com" gefunden. Das ist doch eine "MIT Lizenz" Oder nicht? Also darüber könnte ich doch einfach meine Symbol-TTF erstellen und mit dem Beispiel hier dies alles umsetzen, ohne irgendwelche Lizenzen zu kaufen oder zu beachten?

Wenn das so ist, wäre das wohl auch für andere eine einfache Idee für skalierbare Symbole für die eigene Anwendung. Mir fällt aber noch etwas dazu ein. In Windows gab oder gibt es noch irgendwelche Schriftartglättungs-Einstellungen. Nicht das meine Idee jetzt am Ende doch nicht so toll ist, weil der Endbenutzer in Windows evtl. eine Einstellung hat und die Symbole doch nicht so schön ausschauen.

Jedenfalls könnte man durch eine Doppelbelegung (in zwei Farben + versetzter Pixel) auch Symbole vielleicht in eine 2Farb-Technik etwas aufhübschen. So zumindest die Idee.

Ausprobiert habe ich jetzt aber noch nichts.

KodeZwerg 29. Mär 2021 22:24

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.
 
Es klingt spannend und machbar, habe ich selbst allerdings auch noch nie probiert da ich keine Ahnung habe wie man svg in eine font bekommt. svg sind doch diese megabyte grossen dateien mit nur punkt und linien angaben oder?

Berichte ruhig hier mal was Du so wie am probieren bist. *danke knopf drück*

MicMic 30. Mär 2021 13:16

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

SVGs als Icons sind nicht wirklich groß... eher nur paar Bytes/Kilobytes.
Meinte auch jetzt eher IconFonts, die man meist im WEB einsetzt. Sind auch skalierbar aber nur eine Farbe. Nur mit drüberlegen erreicht man etwas Kreativität. Ich hab es jedenfalls mal ausprobiert. Geht bei Fontello recht gut. Da kann man solche Icons sich zusammenklicken und die Webseite erstellt dann eine TTF-Datei. Mit dem Source hier von dir kann ich dann ganz einfach die Icons im Delphi zeichnen lassen. Also vereinfacht dann "Label1.Caption := '*'. Das Sternchen steht dann für das Zeichen (von Fontello kopiert und eingefügt). Also eine einfache schnelle Möglichkeit skalierbare Symbole zu zeichnen.

Aber TTF, wenn nicht selbst gemacht. Lizenz beachten.
Und wegen Windows-Glättungs-Funktionen muss man da nochmal schauen. Nicht das der Benutzer irgendwas für sich angepasst hat und die Schriftartglättung für die Symbole aus der TTF nicht so richtig passt und alles doof ausschaut. Müsste man mal durchtesten aber habe lange schon keine Schriftartglättungsfunktionen mehr in Windows gesehen. Gibt es aber bestimmt noch irgendwo. Das tolle bei solchen Font-Icons ist ja die einfache Farbänderung. So kann man es gut an sein Programm anpassen. Also bietet man verschiedene Designs an, sind solche Font-Icons schnell in den Farben angepasst.

Jetzt müsste es nur ein guter TTF Editor geben, wo man SVGS oder PNGS einladen kann und das Programm macht daraus passende Linien. Fonts zu erstellen ist nämlich auch nicht einfach. Da muss man ja wieder was neues lernen. Ich will nicht mehr lernen ;-)

Redeemer 31. Mär 2021 12:45

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

Zitat von MicMic (Beitrag 1486205)
Hallo,
ich suche gerade eine einfache Möglichkeit um Symbole zu nutzen, die in verschiedenen Größen dann auch gut aussehen. Also skalierbar sind und auch einfach in Farben geändert werden können. SVG würde ich gerne nutzen aber ich möchte einfach keine fremden Komponenten nehmen. Mir sind die meist viel zu unübersichtlich, sprich 5 PAS-Dateien oder Source-Abschnitte die ich gar nicht dann aufrufe.

RedeemerSVG ist sehr klein, wenn auch auf recht viele Dateien verteilt.

Zitat:

Zitat von MicMic (Beitrag 1486347)
Jetzt müsste es nur ein guter TTF Editor geben, wo man SVGS oder PNGS einladen kann und das Programm macht daraus passende Linien. Fonts zu erstellen ist nämlich auch nicht einfach. Da muss man ja wieder was neues lernen.

Icomoon.
PNG ist selbstverständlich nicht möglich, da es ein Rasterformat ist.
Dateien müssen Outlines sein, ggf. vorher Kontur erweitern im Vektoreditor benutzen.

Zitat:

Zitat von MicMic (Beitrag 1486347)
Ich will nicht mehr lernen

Dann raus hier aus dem Forum! Es ist arg gefährlich.

MicMic 31. Mär 2021 13:42

AW: Schriftart in .exe als Resource einbinden und ohne export auch benutzen.
 
Danke für deine Tipps
Zitat:

Zitat:

Zitat von MicMic (Beitrag 1486347)
Ich will nicht mehr lernen

Dann raus hier aus dem Forum! Es ist arg gefährlich.
Menno... ich bin schon fast 50. ;-)

KodeZwerg 31. Mär 2021 15:52

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

Zitat von Redeemer (Beitrag 1486383)
RedeemerSVG ist sehr klein, wenn auch auf recht viele Dateien verteilt.

Ich habe da Deinen thread gefunden und geladen, die Demo funktionierte leider nicht mit meinen .svg testdateien.
In dem Thread stand was, es geht nur mit TinySVG, gibt es da einen Konverter für?
Dann stand da noch das Du 2018 code für Demo und projekt updatest, in dem Archiv ist es noch 2017, gibt es aktuelle Dateien vielleicht?
RedeemerSVG.TSVGImage - Kleine SVG-Unit für Delphi mit GDI <- hier ist der gemeinte thread.

Was ich bis jetzt gelesen habe, könnte es klappen über den filestream was einzuspielen was in .exe abgelegt ist (resource oder array).
Ich muss erstmal zusehen wie ich überhaupt svg dateien damit darstellen lassen kann, wenn diese hürde gemeistert ist sollte es klappen.

Redeemer 2. Apr 2021 11:04

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

Zitat von KodeZwerg (Beitrag 1486395)
Zitat:

Zitat von Redeemer (Beitrag 1486383)
RedeemerSVG ist sehr klein, wenn auch auf recht viele Dateien verteilt.

Ich habe da Deinen thread gefunden und geladen, die Demo funktionierte leider nicht mit meinen .svg testdateien.
In dem Thread stand was, es geht nur mit TinySVG, gibt es da einen Konverter für?

Wichtigste Eigenschaft von SVGTiny ist, dass es kein eingebundenes CSS (CSS-Regeln) kann. CSS muss als style-Attribut deklariert werden oder man nutzt XML-Präsentations-Attribute. Beispielsweise Adobe-Programme erstellen normalerweise SVG-Dateien mit eingebundenem CSS. Ich arbeite ausschließlich mit Affinity, das erstellt keine CSS-Regeln und funktioniert somit sehr gut.
Der von SVG-Software ausgegebene Quelltext ist in aller Regel unter aller Sau.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:28 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