WINDOWSXP RCDATA "XP.ico"
STRINGTABLE
BEGIN
1 "computer(電腦)"
2 "Windows XP"
END
將其保存為MyRes.rc,需要註意的是,這裏包含了兩個圖標,註意文件名及路徑(這裏是與文件同壹目錄)。在命令提示符窗口中將目錄切換到MyRes.rc所在的路徑,運行brcc32 MyRes.rc,其中brcc32.exe是Delphi附帶的資源編譯工具。如果想將資源文件生成其中擴展名的文件(如.DLL),可以增加-fo參數,如:brcc32 MyRes.rc –of MyRes.dll。
接下來是對資源的引用,引用方法有靜態與動態兩種,靜態引用就是將資源文件包含到源碼中編譯到EXE中去;動態引用則是把資源文件當成DLL動態裝載。
靜態引用資源文件在Delphi中是最簡單不過了,只要在工程文件中加入壹個編譯指令即可,如:
program Multi_Lang;
uses
Forms,
TestFormUnit in 'TestFormUnit.pas' {TestForm};
{$R MyRes.dll} // 包含自定義的資源文件
{$R *.res} // 包含默認的資源文件
begin
Application.Initialize;
Application.CreateForm(TTestForm, TestForm);
Application.Run;
end.
引用時,字符串只要LoadStr(Index)即可,而其它資源用TResourceStream讀取,只不過資源句柄就是程序本身,直接用hInstance就可以了。如:
procedure TTestForm.ReadDirect(Index: Integer);
var
Stream: TResourceStream;
Icon: TIcon;
S: String;
begin
Edit1.Text:= LoadStr(Index); // 在TEdit控件中顯示所獲取的字符串
if Index = 1 then
S:= 'COMPUTER'
else
S:= 'WINDOWSXP';
// Delphi中只支持RT_RCDATA類型讀取
Stream:= TResourceStream.Create(hInstance, S, RT_RCDATA); // 使用hInstance句柄
try
Icon:= TIcon.Create;
try
Icon.LoadFromStream(Stream);
Image1.Picture.Icon.Assign(Icon); // 是TImage控件中顯示所獲取的圖標
finally
Icon.Free;
end;
finally
Stream.Free;
end;
end;
這種引用方式在編譯就將資源與EXE文件鏈接在壹起,而編譯之後就不再需要資源文件了。
動態引用方式相對更多加靈活,編譯時不需要資源文件,而是在運行時動態地入,這樣便可以控件載入不同的資源文件,這也是實現多語言程序的壹種方法。
動態引用實際上只是將資源文件靜態包含到另壹個工程(壹般為DLL程序)中,如:
library MyResDll;
uses
SysUtils,
Classes;
{$R MyRes.dll} // 將資源文件包含到DLL工程中
ResourceString
S1 = '電腦';
S2 = '視窗';
Begin
End.
引用時像普通的DLL引用壹樣,將其裝載後得到壹個句柄,再用靜態引用的方法,使用TResourceStream來讀取。如:
procedure TTestForm.ReadDynamic(Index: Integer);
var
Hnd: THandle;
Stream: TResourceStream;
Icon: TIcon;
S: String;
Buf: PChar;
begin
Hnd:= LoadLibrary('MyResDll.dll'); // 裝載資源文件
if Hnd > 0 then
begin
GetMem(Buf, 255);
LoadString(Hnd, Index, Buf, 255); // 使用LoadString裝載指定句柄的字符串
Edit1.Text:= StrPas(Buf);
if Index = 1 then
S:= 'COMPUTER'
else
S:= 'WINDOWSXP';
Stream:= TResourceStream.Create(Hnd, S, RT_RCDATA); // 使用裝載得到的句柄
try
Icon:= TIcon.Create;
try
Icon.LoadFromStream(Stream);
Image1.Picture.Icon.Assign(Icon);
finally
Icon.Free;
end;
finally
FreeMem(Buf, 255);
Stream.Free;
end;
FreeLibrary(Hnd);
end;
end;
這種方法似乎有點復雜。^_^。
將上面的方法變壹下,將裝載字符串的函數聲明在DLL文件中,如:
library MyResDll;
uses
SysUtils,
Classes;
{$R MyRes.dll}
ResourceString
S1 = '電腦';
S2 = '視窗';
const
ResStr: array[0..1] of String = (S1, S2); // 將字符串放入數組常量
{ 聲明函數獲取字符串個數}
function GetStrCount: Integer; stdcall;
begin
Result:= Length(ResStr);
end;
{ 聲明函數獲取指定索引號的字符串 }
function GetResStr(Index: Integer): PChar; stdcall;
begin
if (Index >= Low(ResStr)) and (Index <= High(ResStr)) then
Result:= PChar(ResStr[Index])
else
Result:= '';
end;
exports
GetStrCount,
GetResStr;
begin
end.
引用的方法與壹般的函數庫引用方法壹樣。如:
type
TGetResStr = function(Index: Integer): PChar; stdcall;
procedure TTestForm.ReadSourceDef(Index: Integer);
var
Hnd: THandle;
GetResStr: TGetResStr;
begin
Hnd:= LoadLibrary('MyResDll.dll');
if Hnd > 0 then
begin
@GetResStr:= GetProcAddress(Hnd, 'GetResStr');
Edit1.Text:= GetResStr(Index);
FreeLibrary(Hnd);
end;
end;
以上代碼在Windows XP Professional + Delphi7下測試通過,如需完整的源碼請mail我:fancy105@163.com。