; ; ; ;字体资源附身大法
; ; ; ; ; ; ; ; ; ; ; ; ; 文/ ;王坚
; ; 有时我们需要在自己的应用程序里使用某些漂亮的字体,但是用户的计算机上没有
这种字体怎么办?
; ; 答案很简单,使用资源文件!
; ; 资源是存放在扩展名.RES的文件里的二进制数据结构。大部分的资源在通常的情况
下可以保留在磁盘当中,直到程序需要使用它们时才将其调入,可以大大的节省内存资
源,同样,资源文件也是可以共享的,即:多个程序可以共享一个资源文件,进而减少
了在应用程序之间代码重复的现象,使程序的代码得到很大的优化,因此在应用程序中
使用资源文件有独立制作、方便、随时修改而不需要对应用程序代码做任何修改的好处。
; ; 可能很多读者已经会使用资源文件来包含声音、图像、光标等资源,这在很多编程
资料中都有介绍。本文将和你探讨一下如何使用字体资源,这里以Delphi编程为例进行
简单说明。
; ; 用文本编辑器比如记事本创建一个脚本文件(*.rc)来描述字体:
MY_FONT ANYOL1 "Bauhs93.ttf"。
; ; 前两个参数你想用什么都可以,它们会用于你的程序。接下来用命令行BRCC32.EXE
(在Delphi的Bin目录下)来编译创建资源文件(*.res)。如果你的脚本文件名为
MyFont.rc,那么你应该在DOS窗口下输入“BRCC32 MyFont”后回车。
; ; BRCC32将在输入处添加.rc,然后建立一个同名的资源文件(不同扩展名)
MyFont.res。在你的程序里添加编译指令:
; ; {$R MyFont.res}
; ; 这需要加在默认的编译指令{$R *.DFM}的后面。
; ; 添加一个过程从资源中建立文件,使字体可以使用。例如:
procedure TForm1.FormCreate(Sender: TObject);
var
; Res : TResourceStream;
begin
; Res := TResourceStream.Create(hInstance, 'MY_FONT', Pchar('ANYOL1'));
; Res.SavetoFile('Bauhs93.ttf');
; Res.Free;
; AddFontResource(PChar('Bauhs93.ttf'));
; SendMessage(HWND_BROADCAST,WM_FONTCHANGE,0,0);
end;
; ; 现在你可以在你需要的地方使用资源文件里的字体了:
procedure TForm1.Button1Click(Sender: TObject);
begin
; Button1.Font.Name := 'Bauhaus 93';
end;
; ; 现在做一些解释,上面的例子可没有做任何错误监测。注意建立的文件名和原来
的字体名并不一样,这里是假定你知道文件名和字体名的关系。当然你可以通过在资
源管理器里双击文件查看字体名。
; ; 这里强烈推荐你把字体文件放在“C:/Windows/Fonts”文件夹里,这样将来你会
很容易找到。
; ; 如果新安装的字体不再使用,程序里安装的字体可以被程序删除:
procedure TForm1.FormDestroy(Sender: TObject);
begin
; RemoveFontResource(PChar("Bauhs93.ttf"))
; SendMessage(HWND_BROADCAST,WM_FONTCHANGE,0,0);
end;
; ; 需要注意的是添加字体的API函数AddFontResource,它可以在Windows系统中添加一
种字体资源,该函数只有一个表示字体名的PChar类型的参数,添加完毕后,该字体即可
由任何Windows应用程序调用。
; ; 添加了一种资源后必须调用API函数SendMessage,这样便可告诉所有Windows应用程
序字体列表已发生了变化。该函数声明为:
; ; SendMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
; ; hWnd:其窗口程序将接收消息的窗口的句柄。如果此参数为HWND_BROADCAST,则
消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。
; ; Msg:指定被发送的消息。
; ; wParam:指定附加的消息指定信息。
; ; IParam:指定附加的消息指定信息。
; ; 返回值:返回值指定消息处理的结果,依赖于所发送的消息。
; ; 同样,用API函数RemoveFontResource从Windows系统中删除一种字体资源后,也要调
用API函数SendMessage告诉所有Windows应用程序字体列表已发生了变化。如删除的字体
目前正由其它应用程序使用,则并不将其立即删除。同时还要注意的是磁盘上的字体文件
本身并不会由这个函数删除。