Tôi cần tải một số phông chữ tạm thời trong chương trình của mình. Tốt hơn là từ một tập tin tài nguyên dll.Tôi có thể tạm thời tải phông chữ bằng cách nào?
Trả lời
Và đây là một phiên bản 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;
sẽ được sử dụng như:
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;
Tôi đã tìm thấy this bằng Google. Tôi đã cắt & dán mã có liên quan bên dưới.
Bạn cần phải thêm font vào file nguồn của bạn:
34 FONT "myfont.ttf"
Mã C sau đây sẽ được tải font từ nguồn DLL và giải phóng nó khỏi bộ nhớ khi bạn đã kết thúc sử dụng nó.
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);
Dưới đây là một số mã đó sẽ được tải/làm cho có sẵn các phông chữ từ bên trong thực thi của bạn (ví dụ, font được nhúng như một nguồn lực, chứ không phải là một cái gì đó bạn phải cài đặt vào Windows nói chung).
Lưu ý rằng phông chữ có sẵn cho bất kỳ ứng dụng nào cho đến khi chương trình của bạn loại bỏ nó. Tôi không biết bạn sẽ thấy hữu ích như thế nào, nhưng tôi đã sử dụng nó một vài lần. Tôi đã không bao giờ đặt font vào một dll (tôi thích điều này 'nhúng vào phương pháp tiếp cận exe') nhưng không tưởng tượng nó thay đổi mọi thứ quá nhiều.
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;
NB các biến sFileName/sFile được sử dụng để tạo ra một tập tin phông chữ địa phương - trong trường hợp này, trong thư mục nơi ứng dụng được lưu trữ. – robsoft
SendMessage sẽ gặp sự cố trên vista. Thay vì SendMessage (HWND_BROADCAST, ..) bạn sẽ muốn SendMessage (Application.Handle, ..) – smo
Trên thực tế, nếu chương trình đang chạy trong \ Program Files, việc giải nén phông chữ vào một tập tin cũng sẽ có vấn đề trong Vista . Bạn sẽ muốn tải các nguồn tài nguyên font từ bộ nhớ như trong ví dụ của bmatthew .. nhưng tôi cũng nghĩ rằng bạn cần phải SendMessage. – smo