Delphi 如何临时加载字体?

Delphi 如何临时加载字体?,delphi,winapi,Delphi,Winapi,我需要在我的程序中临时加载一些字体。最好是来自dll资源文件。我用谷歌找到的。我已经剪切并粘贴了下面的相关代码 您需要将字体添加到资源文件中: 34 FONT "myfont.ttf" 下面的C代码将从DLL资源加载字体,并在使用完毕后将其从内存中释放 DWORD Count; HMODULE Module = LoadLibrary("mylib.dll"); HRSRC Resource = FindResource(Module,MAKEINTRESOURCE(34),RT

我需要在我的程序中临时加载一些字体。最好是来自dll资源文件。

我用谷歌找到的。我已经剪切并粘贴了下面的相关代码

您需要将字体添加到资源文件中:


34 FONT "myfont.ttf"
下面的C代码将从DLL资源加载字体,并在使用完毕后将其从内存中释放

DWORD Count; HMODULE Module = LoadLibrary("mylib.dll"); HRSRC Resource = FindResource(Module,MAKEINTRESOURCE(34),RT_FONT); DWORD Length = SizeofResource(Module,Resource); HGLOBAL Address = LoadResource(Module,Resource); HANDLE Handle = AddFontMemResourceEx(Address,Length,0,&Count); /* Use the font here... */ RemoveFontMemResourceEx(Handle); FreeLibrary(Module); 德沃德计数; HMODULE Module=LoadLibrary(“mylib.dll”); HRSRC Resource=FindResource(模块,MAKEINTRESOURCE(34),RT_字体); DWORD长度=SizeofResource(模块,资源); HGLOBAL Address=LoadResource(模块,资源); HANDLE HANDLE=AddFontMemResourceEx(地址、长度、0和计数); /*使用这里的字体*/ 移除FontMemResourceEx(手柄); 免费图书馆(模块);
下面是一些代码,可以从可执行文件中加载/使用字体(即,字体是作为资源嵌入的,而不是通常必须安装到Windows中的东西)

请注意,该字体可用于任何应用程序,直到您的程序将其删除。 我不知道你会觉得这有多有用,但我已经用过好几次了。我从未将字体放入dll(我更喜欢这种“嵌入exe”的方法),但不要认为它会改变太多东西

procedure TForm1.FormCreate(Sender: TObject); var ResStream : TResourceStream; sFileName : string; begin sFileName:=ExtractFilePath(Application.ExeName)+'SWISFONT.TTF'; ResStream:=nil; try ResStream:=TResourceStream.Create(hInstance, 'Swisfont', RT_RCDATA); try ResStream.SaveToFile(sFileName); except on E:EFCreateError Do ShowMessage(E.Message); end; finally ResStream.Free; end; AddFontResource(PChar(sFileName)); SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0); end; procedure TForm1.FormDestroy(Sender: TObject); var sFile:string; begin sFile:=ExtractFilePath(Application.ExeName)+'SWISFONT.TTF'; if FileExists(sFile) then begin RemoveFontResource(PChar(sFile)); SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0); DeleteFile(sFile); end; end; 过程TForm1.FormCreate(发送方:TObject); 变量 ResStream:TResourceStream; sFileName:string; 开始 sFileName:=ExtractFilePath(Application.ExeName)+'SWISFONT.TTF'; ResStream:=零; 尝试 ResStream:=TResourceStream.Create(hInstance,'Swisfont',RT_RCDATA); 尝试 ResStream.SaveToFile(sFileName); 除了 在E:EFCreateError Do ShowMessage(E.Message)上; 结束; 最后 免费的; 结束; AddFontResource(PChar(sFileName)); 发送消息(HWND_广播,WM_FONTCHANGE,0,0); 结束; 程序TForm1.FormDestroy(发送方:ToObject); 变量 sFile:字符串; 开始 sFile:=ExtractFilePath(Application.ExeName)+'SWISFONT.TTF'; 如果文件存在(sFile),则 开始 RemoveFontResource(PChar(sFile)); 发送消息(HWND_广播,WM_FONTCHANGE,0,0); 删除文件(sFile); 结束; 结束;
这里是Delphi版本:

procedure LoadFontFromDll(const DllName, FontName: PWideChar);
var
  DllHandle: HMODULE;
  ResHandle: HRSRC;
  ResSize, NbFontAdded: Cardinal;
  ResAddr: HGLOBAL;
begin
  DllHandle := LoadLibrary(DllName);
  if DllHandle = 0 then
    RaiseLastOSError;
  ResHandle := FindResource(DllHandle, FontName, RT_FONT);
  if ResHandle = 0 then
    RaiseLastOSError;
  ResAddr := LoadResource(DllHandle, ResHandle);
  if ResAddr = 0 then
    RaiseLastOSError;
  ResSize := SizeOfResource(DllHandle, ResHandle);
  if ResSize = 0 then
    RaiseLastOSError;
  if 0 = AddFontMemResourceEx(Pointer(ResAddr), ResSize, nil, @NbFontAdded) then
    RaiseLastOSError;
end;
要像这样使用:

var
  FontName: PChar;
  FontHandle: THandle;
...
  FontName := 'DEJAVUSANS';
  LoadFontFromDll('Project1.dll' , FontName);
  FontHandle := CreateFont(0, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET,
    OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,
    FontName);
  if FontHandle = 0 then
    RaiseLastOSError;

注意:sFileName/sFile变量用于创建本地字体文件-在本例中,在应用程序所在的目录中。SendMessage在vista上会出现问题。事实上,如果程序在\program文件中运行,那么在Vista中将字体提取到文件中也会出现问题,而不是发送消息(HWND_BROADCAST,…)。您将希望从内存加载字体资源,如bmatthew的示例所示。但我也认为您需要发送消息。为了完整起见,我想我会更新此内容-如果您只打算在自己的程序中使用字体,则不需要发送消息的内容!最好使用带有
FR\u PRIVATE
标志的函数。这是为了在您的流程中私人使用。