我如何临时加载字体?
时间:2020-03-06 14:28:49 来源:igfitidea点击:
我需要在程序中临时加载一些字体。最好是来自dll资源文件。
解决方案
我在Google上找到了这个。我已经剪切并粘贴了以下相关代码。
我们需要将字体添加到资源文件中:
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);
以下是一些代码,它们将从可执行文件内部加载/提供字体(即,字体是作为资源嵌入的,而不是通常必须安装到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;
这是一个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;