2008-09-20 22 views

Trả lời

10

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; 
2

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); 
1

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; 
+0

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

+0

SendMessage sẽ gặp sự cố trên vista. Thay vì SendMessage (HWND_BROADCAST, ..) bạn sẽ muốn SendMessage (Application.Handle, ..) – smo

+0

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

Các vấn đề liên quan