Delphi中资源文件使用详解(转载)
用记事本或其它文本编辑器编写一个扩展名为 “.rc” 的文件。格式如下:
AVI 无声动画
BITMAP 位图文件
CURSOR 光标文件
ICON 图标文件
WAVE 声音文件
以上所列均为标准资源类型,也可以给资源自定义一个类型,如: “mytype” 。不过两者在调用方式上有些不同(在后面示例 “ 存取资源文件中的位图 ” 中有详细描述)。
二.根据 RC 脚本文件编译成 RES 资源文件
在命令提示符中输入以下内容:
brcc32 FileName.rc // 注: brcc32.exe 在 DelphiX/Bin 目录中
三.在 Delphi 单元中加入资源文件
将生成的 RES 资源文件复制到相应程序所在的目录中,在单元文件中的 “{$R *DFM}” 后面加上 “{$R FileName.res}” ,编译后资源文件就被包含在可执行文件中了。
说明:如果嫌 2 、 3 两步麻烦,可以采用更简便的做法,即:将 RC 文件直接添加到项目中,在编译 Delphi 项目时,会自动编译该资源文件。
( 1 )存取资源文件中的位图
Image1.Picture.Bitmap.LoadFromResourceName(HInstance, 'res/test.bmp');
//RC: testBmp bmptype res/test.bmp
var
resStream: TResourceStream;
begin
resStream := TResourceStream.Create(HInstance, 'testBmp', 'bmptype');
Image1.Picture.Bitmap.LoadFromStream(resStream);
resStream.Free;
end;
将图标放在资源文件中,可以实现动态改变应用程序的图标。
Application.Icon.Handle := LoadIcon(HInstance, 'testIcon');
Animate1.ResName := 'testAvi';
Animate1.Active := True;
为了能够处理 JPEG 图像,必须在 Interface 处引用 JPEG 单元。
resStream: TResourceStream;
jpg := TJPEGImage.Create;
resStream := TResourceStream.Create(HInstance, 'testJpg', 'jpgtype');
jpg.LoadFromStream(resStream);
Image1.Picture.Assign(jpg);
jpg.Free;
resStream.Free;
end;
资源文件一般为扩展名为 res 的文件 . 在 VC 中资源文件用得非常普遍 , 但 Delphi 在其联机帮助中对资源文件没作什么介绍 , 其实利用其自带的资源编译工具 BRCC32.EXE( 一般位于 /Delphi/BIN 目录下) , 我们完全可以做出跟 VC 一样效果的文件来。
资源文件最大的好处是能将一些在必要时才调用的文件跟可执行文件一起编译 , 生成一个文件 . 这样做最大的好处就是使外部文件免遭破坏 . 例如在一条程序中你要临时调用一幅图片 , 一般作法是把图片放在某一路径下(通常是主程序所在路径) , 但如果用户路径误删你的图片文件 , 则可能使程序找不到相应文件而出错崩溃 . 另外 , 如果你想自己的程序界面美观 , 想用一些自定义光标 , 也要用到资源文件。
资源文件的使用步骤为:
一 . 编写 rc 脚本文本
用记事本或其它文本编辑器编写一个扩展名为 rc 的文件。例如:
mycur cursor move.cur // 加入光标
mypic Bitmap Water.BMP // 加入位图
mywav WAVE happy.wav // 加入声音
myAVI AVI EPOEN.AVI // 加入视频
myIco ICON CJT.ICO // 加入图标
格式分别为在资源文件中的名称 -> 类型 -> 实际文件名称,例如上面第一行定义一个名为 mycur 的光标,实际名称为加入光标 move.cur.
二 . 将 rc 文件编译成 res 资源文件
将脚本文件和实际文件拷到 Brcc32.EXE 所在目录,执行 DOS 命令。格式为: Brcc32 脚本文件 ( 回车 ) ,例如有一名为 myfirst.rc 的脚本文件,则执行 Brcc32 myfirst.rc( 回车 ) 即可。如果你是懒人,也可新建一批处理文件,内容只有一行: Brcc32 mufist.rc.( 因为 Delphi 安装后一般会在自动批处理文件中指明搜索路径的。 ) 如果编译成功,则会生成一个结尾为 res 的文件,这个文件就是我们需要的资源文件。
三 . 在 Delphi 单元中加入资源文件
将生成的 res 资源文件拷贝到你所编程序的路径下,在单元文件 {$R *DFM} 后加上一句 {$R mufirst.res} ,则将 res 文件加入去,编译后资 源文件即已包含在可执行文件中了。若你有多个资源文件,也按上法依次加入。
四 . 在 Delphi 程序中调用资源文件
资源文件在 Delphi 中的关键字为 hinstance. 下面给出具体用法 .
1. 光标的调用
首先在程序中定义一个值大于 0 的常量,因为 Delphi 本身用 0- 负 16 来索引默认的光标,所以我们制定的光标应从表面上 1 开始索引。然后在窗口的 Oncreat 事件中添加以下代码:
新建一项工程,添加一 Timage 控件,在需要显示的地方写以下代码:
mymap:=LoadBitmap(hinstance,'mypic');
Image1.picture.Bitmap.Handle:=mymap ;
end;
3.AVI 文件的调用
新建一工程,添加一 Animate 控件,在需要的地方加入:
animater1.Active:=true;
4. 调用 WAV 文件
在 uses 中加入 mmsystm 单元,以便在程序中播放 WAV 文件。播放时 Playsound(pchar('mywav'),hinstance,sndsync or snd_resource); 其中 mywav 为声音文件在资源中的名称。
5. 加入光标
加入光标比较容易,只要将 res 文件加入单元文件中即可。但需注意 , 名称最好取 "W"."WW" 等,使第一个字母尽量靠后,以免与主程序的图标顺序颠倒。这样一来,别人在使用你的程序时如果想选择其它图标就有很多选择了。
补充 :
1. 资源类型除上述类型外,还可以字体文件,字符串文件等。
2. 资源文件不但可以在标准图形界面下使用还可在控制台下使用。
下面我们来试验一下:
新建一工程,将唯一的一个 Form 删除,然后修改工程文件。增加一句 {$Apptype console}, 在 uses 子句中加入 mmsystem, 并将其它引用单元删掉。将 Begin 和 end 之间语句删掉。至此,我们就可和 Turbo PASCAL 下编程序一样,且还可以调用 windows 的 API 和资源。将资源文件 ----{$R myfist.res} 加入。在 Begin 和 end 之间写下:
readln;
playsound(pchar('mywav'),hinstance,snd_sync or snd_resource);
writeln(' 演示结束! ');
3.Delphi 本身自带了一个叫 Image Editor 的工具,同样可以编辑资源文本,但和本文的方法比较,可得出下表:
Image
|
Editor
|
Brcc32
|
BMP
|
只支持 16 位色
|
任意色
|
光标
|
黑白两色
|
任意色
|
ICO
|
只支持 16 位色
|
任意色
|
AVI
|
不支持
|
支持
|
WAV
|
不支持
|
支持
|
字符串
|
不支持
|
支持
|
例如 : myexe exefile 'ha1.exe'// 脚本文件
下面是自定义释放函数 ExtractRes ,本例中使用如下 :
var
Res: TResourceStream;
begin
try
Res := TResourceStream.Create(Hinstance, Resname, Pchar(ResType));
try
Res.SavetoFile(ResNewName);
Result := true;
finally
Res.Free;
end;
except
Result := false;
end;
end;
上面我们已经知道如何把一副 BMP 图像从资源文件里面读出来 , 但是 BMP 文件太大了 ,JPG 文件应用的相对较多 . 那么如何把 JPG 图像读出来呢 ? 用资源文件加流方式即可。具体方法如下 :
1 .MyJpg JPEG My.JPG
2 .
Stream:TStream;
MyJpg:TJpegImage;
Begin
Stream := TResourceStream.Cceat(HINSTANCE,'MyJpg','JPEG');
Try
MyJpg:=TJpegImage.Create;
Try
MyJpg.LoadfromStream(Stream);
Image1.Picture.Assignc(MyJpg);
Finally
MyJpg.Free;
end;
Finally
Stream.Free;
end;
end;
1 : 创建一个 Hicon.RES 文件 , 这里不再重复 .
2 : 新建一文本文件 Icon.dpr, 内容如下 :
{$R Icon.RES}
begin
end
3 : 实际调用方法如下 :
Private
Hinst:THANDLE;
......
Var Hicon:THANDLE;
begin
Hinst:=Loadlibrary('Icon.dll');
If Hinst=0 Then Exit ;
Hicon:=Loadicon(Hinst,Pchar(Edit1.Text));
If Hicon<>0 Then Image1.Picture.Icon.Handle:=Hicon;
FreeLibrary(Hinst);
end;
#define IDS_MainForm_Caption 1
#define IDS_BtnOpen_Caption 2
#define IDS_BtnSave_Caption 3
#define IDS_BtnBig5_Caption 4
#define IDS_BtnGb32_Caption 5
#define IDS_BtnHelp_Caption 6
#define IDS_Help_Shelp 7
Stringtable
{
IDS_MainForm_Caption," 汉字简繁体翻译器 "
IDS_BtnOpen_Caption," 打开文件 "
IDS_BtnSave_Caption," 保存文件 "
IDS_BtnBig5_Caption," 转换成 Big5"
IDS_BtnGb32_Caption," 转换成 Gb32"
IDS_BtnHelp_Caption," 帮助 "
IDS_Help_Shelp," 输入文字或打开文件后按需要点击按钮即可转换 !"
}
新建一个工程 , 放上五个 Button:BtnOpen,BtnSave,BtnBig5,BtnGb32 和 BtnHelp. 还有一个 TComboBox:CbSelect 用来选择语言种类的 .
具体代码如下 :
interface
......
private
SHelp: string;
function SearchLanguagePack: TStrings;
procedure SetActiveLanguage(LanguageName: string);
{ Private declarations }
......
implementation
procedure TForm1.CbSelectChange(Sender: TObject);
begin
SetActiveLanguage(CbSelect.Text);// 调用相应 Dll 文件读取相应字符 .
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
CbSelect.Items.AddStrings(SearchLanguagePack);// 搜索当前目录下所有的 Dll 文件名称
end;
function TForm1.SearchLanguagePack: TStrings;
var
ResultStrings: TStrings;
DosError: integer;
SearchRec: TsearchRec;
begin
ResultStrings := TStringList.Create;
DosError := FindFirst(ExtractFilePath(ParamStr(0)) + '*.dll', faAnyFile, SearchRec);
while DosError = 0 do
begin
ResultStrings.Add(ChangeFileExt(SearchRec.Name, ''));
DosError := FindNext(SearchRec);
end;
FindClose(SearchRec);
Result := ResultStrings;
end;
procedure TForm1.SetActiveLanguage(LanguageName: string);
var
Hdll: Hmodule;
MyChar: array[0..254] of char;
DllFileName: string;
begin
DllFileName := ExtractFilePath(ParamStr(0)) + LanguageName + '.dll';
if not FileExists(DllFileName) then Exit;
Hdll := loadlibrary(Pchar(DllFileName));
Loadstring(hdll, 1, MyChar, 254);
Self.Caption := MyChar;
// 读取字符资源, 1 表示资源文件中定义的 1
Loadstring(hdll, 1, MyChar, 254);
Self.Caption := MyChar;
Loadstring(hdll, 2, MyChar, 254);
BtnOpen.Caption := MyChar;
Loadstring(hdll, 3, MyChar, 254);
BtnSave.Caption := MyChar;
Loadstring(hdll, 4, MyChar, 254);
BtnBig5.Caption := MyChar;
Loadstring(hdll, 5, MyChar, 254);
BtnGb32.Caption := MyChar;
Loadstring(hdll, 6, MyChar, 254);
BtnHelp.Caption := MyChar;
Loadstring(hdll, 7, MyChar, 254);
SHelp := MyChar;
Freelibrary(hdll);
Application.Title := Self.Caption;
//------------------------
BtnOpen.Visible := True;
BtnSave.Visible := True;
BtnBig5.Visible := True;
BtnGb32.Visible := True;
BtnHelp.Visible := True;
//------------------------
end;
procedure TForm1.BtnHelpClick(Sender: TObject);
begin
Application.MessageBox(Pchar(SHelp), 'Http://lovejingtao.126.com', MB_ICONINFORMATION);
end;
end.
高级应用篇
Delphi 是个很有效率的开发工具 , 但是它有一个缺点就是生成的 EXE 文件太大 . 一个程序就算只有一个空窗口体积也有 286KB. 如果直接用 API 来写的话程序体积是小了 , 但是又太繁琐 , 无法立即看到界面效果 , 根本谈不上是可视化开发 . 其实并非 " 鱼与熊掌不可兼得 ", 利用资源文件我们就可以轻松达到这个目的 .
在开始之前 , 我们需要一个可以编辑资源文件的工具 . 这类工具很多 , 比如说 Resource WorkShop 就是非常好的一个 . 如果一时找不到 , 利用 VC 的编辑器来也是可以的 . 下面我们就以 VC 的为例示范如何创建一个窗口资源文件 . 运行 VC, 打开菜单 File-->New, 将出现一个多项选择页 . 我们选择 Files-->ResourceTemplate, 在右边的 File 填上 Demo,Location 选择保存路径 , 然后点击按钮 OK 返回 VC 开发环境 .
选择菜单 Insert-->Resource, 将出现一个资源类型选择框 . 我们把鼠标移到 Dialog 上面 . 不用展开 , 点击右边的 New 即可 , 这时候返回 VC 开发环境并出现一个只有关闭按钮和两个 Button 的窗体 . 将鼠标选定窗体 , 击右键选择最后一项 Properties, 将出现一个设置窗口 , 将 ID 改为 "MAINFORM" 。
注意 : 跟下面添加的其它控件的属性设置方法不同 , 主窗口的 ID 必须把双引号写上去 , 而且名称必须为大写 . 否则程序将找不到资源 . 程序会一运行就退出了。
Caption 改为 " 安装程序 ", 这时候可以立刻看到窗口的标题变成了 " 安装程序 ", 把 Styles 的 Minimize box 选上 ,More Styles 的 Center 勾上使程序运行时的位置居中 . 当然你也可以设置它的坐标 . 其它保留默认值即可 . 回到开发环境 , 在控件框里面分别选择一个 Static Text, 一个 Edit Box, 一个 Button 和一个 Group Box 添加到窗体上面 . 把它们按照自己的爱好排列整齐 . 然后逐个修改它们的属性 . 方法就是按照上面说的选定控件后击右键选择最后一项 Properties, 在出现的属性框里面修改 . 其中属性如下 :Group Box 的 Caption 属性清空 ,Static Text 的 Caption 属性改为 " 请选择安装目录 :",Edit Box 的 ID 改为 10001. 第一个 Button 的 ID 为 10002,Caption 属性为 " 选择 ", 第二个 Button 的 ID 为 10003,Caption 属性为 " 安装 ", 第三个 Button 的 ID 为 10004,Caption 属性为 " 退出 ". 为了使程序更加完美 , 我们为它再添加一个菜单 IDR_MENU1. 选择 Insert-->Resource-->Menu, 我们这里只简单添加一项 " 文件 --> 退出 ", 其中 " 退出 " 的 ID 为 10005. 然后在主窗口的属性 Menu 设定为 IDR_MENU1 即可。
为了使程序更加美观 , 我们再添加一个小图标 , 同时这也将是我们程序的图标 . 选择 Insert-->Resource-->Icon-->Import, 选择一个图标文件 . 并将它的 ID 设置为 "MAINICON"( 注意 : 必须把双引号写上而且字母为大写 ), 为窗口添加一个 Picture 控件并设置它的属性 Type:Icon,Image 下拉选择刚才的图标 MainIcon 即可。
如果你想为程序在鼠标添加一些信息也是可以的 . 选择 Insert-->Resource-->Version 即可。
到这里我们已经完成了一个简单的 " 安装程序 " 的窗体设计 . 实际上我们现在就可以在 Delphi 中调用它了 . 我们先把 " 劳动成果 " 保存起来 . 选择 File-->Save As, 在文件类型里选择 "32-bit Resource File(.res)" 保存为 "Demo.res", 文件大小大约为 2.65KB 。
新建一个扩展名为 dpr 的文本文件 MyDemo.Dpr, 键入如下代码 :
{$R Demo.Res}
function MainDialogProc(DlgWin:hWnd;DlgMessage:UINT;DlgWParam:WPARAM;DlgLParam:LPARAM):
begin
Result := 0;
case DlgMessage of
WM_Close:
begin
PostQuitMessage(0);
Exit;
end;
end;
end;
begin
DialogBox(hInstance, 'MAINFORM', 0, @MainDialogProc);
end
{$R Demo.Res}
function MainDialogProc: integer;
begin
Result := 0;
end;
begin
DialogBox(hInstance, 'MAINFORM', 0, @MainDialogProc);
end
uses Windows, Messages, shlobj;
const
ID_Edit = 10001;
ID_Selet = 10002;
ID_Setup = 10003;
ID_Quit = 10004;
ID_Exit = 10005;
{$R Demo.Res}
var
MainWin: HWND;
function My_Gettext: string;
var
Textlength: Integer;
Text: PChar;
s: string;
begin
TextLength := GetWindowTextLength(GetDlgItem(MainWin, ID_Edit));
GetMem(Text, TextLength + 1);
GetWindowText(GetDlgItem(MainWin, ID_Edit), Text, TextLength + 1);
s := text;
FreeMem(Text, TextLength + 1);
Result := s;
end;
function Getmyname: string;
var
i, j: integer;
begin
J := 3;
for i := 1 to length(ParamStr(0)) do
if ParamStr(0)[i] = '/' then J := I;
Result := copy(ParamStr(0), J + 1, length(ParamStr(0)) - J);
end;
function SelectDirectory(handle: hwnd; const Caption: string; const Root:WideString;outDirectory:string): Boolean;
var
lpbi: _browseinfo;
buf: array[0..MAX_PATH] of char;
id: ishellfolder;
eaten, att: cardinal;
rt: pitemidlist;
initdir: pwidechar;
begin
result := false;
lpbi.hwndOwner := handle;
lpbi.lpfn := nil;
lpbi.lpszTitle := pchar(caption);
lpbi.ulFlags := BIF_RETURNONLYFSDIRS + BIF_EDITBOX;
SHGetDesktopFolder(id);
initdir := pwchar(root);
id.ParseDisplayName(0, nil, initdir, eaten, rt, att);
lpbi.pidlRoot := rt;
getmem(lpbi.pszDisplayName, MAX_PATH);
try
result := shgetpathfromidlist(shbrowseforfolder(lpbi), buf);
except
freemem(lpbi.pszDisplayName);
end;
if result then
begin
directory := buf;
if length(directory) <> 3 then directory := directory + '/';
end;
end;
function MainDialogProc(
DlgWin: hWnd;
DlgMessage: UINT;
DlgWParam: WPARAM;
DlgLParam: LPARAM
)
: integer; stdcall;
var
MyIcon: HICON;
Sdir: string;
begin
Result := 0;
case DlgMessage of
WM_INITDIALOG:
begin
MyIcon := LoadIcon(hInstance, 'MainIcon');
SetClassLONG(DlgWin, GCL_HICON, MyIcon);
MainWin := DlgWin;
end;
WM_Close:
begin
PostQuitMessage(0);
Exit;
end;
WM_COMMAND:
case LOWORD(DlgWParam) of
ID_Selet: begin
if SelectDirectory(DlgWin, ' 请选择安装目录 ', '', Sdir)
then SendMessage(GetDlgItem(DlgWin, ID_Edit), WM_SETTEXT, 0, lParam(pChar(Sdir)));
end;
ID_Setup: begin
if My_Gettext = '' then
begin
MessageBox(DlgWin, ' 请先选择安装文件夹 !', ' 信息 ', MB_ICONINFORMATION + MB_OK);
Exit;
end;
CopyFile(pchar(ParamStr(0)), pchar(My_Gettext + Getmyname), false);
MessageBox(DlgWin, ' 安装完毕 !', ' 信息 ', MB_ICONINFORMATION + MB_OK);
PostQuitMessage(0);
Exit;
end;
ID_Quit: begin
PostQuitMessage(0);
EXIT;
end;
ID_Exit: begin
if MessageBox(DlgWin, ' 你点击了菜单 “ 退出 ” ,你确定退出程序吗 ?', ' 信息 ', MB_ICONQUESTION + MB_OKCANCEL) = IDOK then
PostQuitMessage(0);
Exit;
end;
end;
end;
end;
begin
DialogBox(hInstance, 'MAINFORM', 0, @MainDialogProc);
end
其中 SelectDirectory 函数的作用是返回一个选择的文件路径 . 然后把自己拷贝到选择的目录下 , 当然很多处理没有写 , 读者可以自行添加 . 文件编译后大小为 22KB, 如果直接用 Delphi 的 VCL 来写的话 , 将为 338KB!
Delphi中资源文件使用详解(转载)相关推荐
- Delphi中资源文件使用详解
Delphi中资源文件使用详解<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" ...
- Delphi 中资源文件使用详解
Delphi 中资源文件使用详解 第一篇文章: <Dephi5中资源文件的创建和使用> 几乎每个Windows应用程序都使用图标.图片.光标等资源.资源是程序的一部分,但是它是不可执行代码 ...
- delphi TWebBrowser组件使用详解
delphi TWebBrowser组件使用详解 该组件是一个浏览器组件,可以显示一个指定地址的网页.设置网页打开时的主页以及对网页进行相关的操作,同时也可以对HTML文件进行剪切.复制.粘贴.删除等 ...
- Delphi的单元文件详解
Delphi的单元文件详解 Delphi单元文件 1.库单元文件头:其中声明了库单元的名字. 2.Interface部分: 由保留字interface开始,结束于保留字implementation ...
- spring依赖注入原理详解(转载)
spring依赖注入原理详解----转载 所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中.当spring容器启动后,spring容器初始化,创建并管理bean对象,以及销毁它.所 ...
- Executor框架的详解(转载)
在Java中,使用线程来异步执行任务.Java线程的创建与销毁需要一定的开销,如果我们为每一个任务创建一个新线程来执行,这些线程的创建与销毁将消耗大量的计算资源.同时,为每一个任务创建一个新线程来执行 ...
- vsftpd配置文件详解[转载]
vsftpd配置文件详解 1.默认配置: 1>允许匿名用户和本地用户登陆. anonymous_enable=YES local_enable=YES 2>匿名用户使用 ...
- SqlHelper详解(转载)
SqlHelper 类实现详细信息 SqlHelper 类用于通过一组静态方法来封装数据访问功能.该类不能被继承或实例化,因此将其声明为包含专用构造函数的不可继承类. 在 SqlHelper 类中实现 ...
- HTTP详解(转载)
HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1.0的第 ...
最新文章
- Apache配置文件
- python 时间序列预测 币价_python时间序列预测股票走势
- b超可以看出什么_【b超能检查出什么】b超能看出男女吗_b超能查出什么妇科病 - 妈妈网百科...
- 【整理】Linux常用命令
- python爬取京东评论_Python如何爬取京东的评价信息
- linux shell转换时间格式,在bash中转换日期格式
- Java实现List数组的几种替代方案
- 英特尔AI如何帮助修缮残垣断壁的长城,背后的奥秘找到了
- 固定td 样式 随 内容 溢出
- Java代码优化的一些方法(总结)
- 从VBA到VSTO的一些想法
- 多目标跟踪算法SOART
- 敏捷互联网项目测试质量报告的大纲
- Elasticsearch集群规划及节点角色规划醉佳实践
- mediawiki 各种扩展整理
- 学期计算机教学工作反思,小学信息技术老师一月工作反思总结教育教学笔记
- 自动阅读项目又出新情况?一天秒封47个账号
- VC++ 操作 word
- 《绝地求生》玩家排名预测(2万5千字~大型综合实战)
- 关于微信公众平台迁移见证需要具备什么条件?