从资源文件加载字体

HP *_*ner -2 delphi delphi-xe

我有一个包含以下资源的 Delphi XE 项目:

项目1

我已经使用function LoadResourceFont并尝试了以下代码:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function LoadResourceFontByName( const ResourceName : string; ResType: PChar ) : Boolean;
var
  ResStream  : TResourceStream;
  FontsCount : DWORD;
begin
  ResStream := TResourceStream.Create(hInstance, ResourceName, ResType);
  try
    Result  := (AddFontMemResourceEx(ResStream.Memory, ResStream.Size, nil, @FontsCount) <> 0);
  finally
    ResStream.Free;
  end;
end;

function LoadResourceFontByID( ResourceID : Integer; ResType: PChar ) : Boolean;
var
  ResStream  : TResourceStream;
  FontsCount : DWORD;
begin
  ResStream := TResourceStream.CreateFromID(hInstance, ResourceID, ResType);
  try
    Result  := (AddFontMemResourceEx(ResStream.Memory, ResStream.Size, nil, @FontsCount) <> 0);
  finally
    ResStream.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  if LoadResourceFontByName('MyFont1', RT_RCDATA) then Label1.Font.Name := 'My Custom Font1';
  if LoadResourceFontByID(2, RT_FONT) then Label2.Font.Name := 'My Custom Font2';   
end.
Run Code Online (Sandbox Code Playgroud)

顺便说一句:我知道如果我需要将字体嵌入到我的 EXE 文件中,我应该拥有该字体的重新分发权。

但问题是,如果字体名称(我使用了My Custom Font1My Custom Font2)不是字体的实际名称,则字体无法正确加载并显示未知的字体字符。

我的问题是,虽然我已经ResStream.Free在函数中使用了,但我是否必须重新定义FormCloseFormDestroy事件来保护内存泄漏?

Rem*_*eau 7

您的代码有几个错误。

  1. LoadResourceFont()返回一个Boolean. 您正在尝试将该值分配给该TLabel.Font.Name属性,但您无法执行此操作,因为 aBoolean不是 a String。您还尝试将 分配BooleanTLabel.Font[2]属性,该属性甚至不是要为其分配值的有效标识符。

  2. 您的第一次调用LoadResourceFont()指定了错误的资源名称。

  3. 的第一个参数LoadResourceFont()是 a String,但您的第二次调用LoadResourceFont()是尝试将全局Hinstance变量 (an THandle)传递到String需要 a 的位置。

  4. 您尝试将第二个字体作为 RCDATA 资源加载,但实际上它是 FONT 资源。

要执行您尝试的操作,您需要LoadResourceFont()首先调用将字体加载到字体表中,然后您可以将 设置TLabel.Font.Name为所需字体的字体名称(TTF 文件中定义的名称,而不是文件名)或资源名称),例如:

function LoadResourceFontByName( const ResourceName : string; ResType: PChar ) : Boolean;
var
  ResStream : TResourceStream;
  FontsCount : DWORD;
begin
  ResStream := TResourceStream.Create(hInstance, ResourceName, ResType);
  try
    Result := (AddFontMemResourceEx(ResStream.Memory, ResStream.Size, nil, @FontsCount) <> 0);
  finally
    ResStream.Free;
  end;
end;

function LoadResourceFontByID( ResourceID : Integer; ResType: PChar ) : Boolean;
var
  ResStream : TResourceStream;
  FontsCount : DWORD;
begin
  ResStream := TResourceStream.CreateFromID(hInstance, ResourceID, ResType);
  try
    Result := (AddFontMemResourceEx(ResStream.Memory, ResStream.Size, nil, @FontsCount) <> 0);
  finally
    ResStream.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  if LoadResourceFontByName('MyFont1', RT_RCDATA) then
    Label1.Font.Name := 'My Font Name 1';

  if LoadResourceFontByID(2, RT_FONT) then
    Label2.Font.Name := 'My Font Name 2';
end;
Run Code Online (Sandbox Code Playgroud)