2008-09-20 21 views

Respuesta

10

Y aquí una versión de 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; 

para ser utilizado como:

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

me encontré con this Google. He cortado & pegado el código relevante a continuación.

es necesario agregar la fuente a su archivo de recursos:


34 FONT "myfont.ttf" 

El siguiente código C se carga la fuente de la DLL de recursos y liberarlo de la memoria cuando haya terminado de usarlo.

 
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

Aquí hay algo de código que se carga/poner a disposición de la fuente desde el interior de su ejecutable (es decir, la fuente fue incorporado como un recurso, en lugar de algo que era necesario instalar a Windows en general).

Tenga en cuenta que la fuente está disponible para cualquier aplicación hasta que su programa se deshaga de ella. No sé lo útil se encuentra esta, pero yo he usado un par de veces. Nunca puse la fuente en un dll (prefiero este enfoque de 'incrustar en el exe') pero no creo que cambie demasiado las cosas.

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 las variables sFileName/sFile se utilizan para crear un archivo de fuentes locales - en este caso, en el directorio donde está alojada la aplicación. – robsoft

+0

SendMessage tendrá problemas en vista. En lugar de SendMessage (HWND_BROADCAST, ..) que le conviene a SendMessage (Application.Handle, ..) – smo

+0

De hecho, si el programa se ejecuta en \ Archivos de programa, la extracción de la fuente a un archivo también va a ser problemático en Vista . Querrá cargar el recurso fuente desde la memoria como en el ejemplo de bmatthew ... pero también creo que necesita SendMessage. – smo

Cuestiones relacionadas