`
v5qqcom
  • 浏览: 1285058 次
文章分类
社区版块
存档分类
最新评论

Delphi的资源文件

 
阅读更多

更多有关资源的问题参考API应用相关篇章
资源文件(*.res)通过编译指令 $R 关联, 譬如工程文件 Project1 中的 {$R *.res} 就是关联 Project1.res 资源文件, 我们直接写作 {$R Project1.res} 不会有问题(但如果工程文件改名时, 你也得随着改才行). 譬如:

program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R Project1.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

这个资源文件中至少包含着文件图标, 假如我们删除 {$R *.res} 后编译, 看前后对比图:



这时我们可以通过代码, 调用其他图标:

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.Icon.LoadFromFile('c:/temp/my.ico');
end;



这样还是不好, 如果运行程序的电脑没有这个文件呢? 最好让程序携带着它, 这就要通过资源文件. 让我们从头来过:

1、新建一个 VCL Forms Application; 并 Save All;

2、并通过菜单 Project → View Souse 打开工程源文件;

3、删除 {$R *.res}

4、如图新建一个 Text 文件



5、文件编辑如下:
MainIcon ICON "c:/temp/my.ico"

注意: 其中的 c:/temp/my.ico 可以随便定义, 但文件必须存在; 另外其中的所有大小写无关, 路径两边的双引号也可以省略.

6、把它保存为: Project1.rc ; 注意要保存在程序相同目录, 文件名和工程文件名相同, 后缀是 rc

7、如图把 Project1.rc 添加到工程组:



8、这时工程文件自动添加了一行: {$R 'Project1.res' 'Project1.rc'}

9、好了, 编译执行程序, 如图:



注释:

1、*.rc 文件算是资源文件(*.res) 的源文件, 在程序编译过程中会编译成同名的 res 文件;

2、上面的例子是个特例, 一般我们不能使用和工程同名的资源文件;

3、MainIcon ICON "c:/temp/my.ico" 中的 ICON 说明这是一个图标资源, MainIcon 是该资源的标识符, 这个标识符应该是可以自定义的, 不过在这个特例中, 只能使用 MainIcon , 因为程序要从同名的资源文件中查找标识为 MainIcon 的资源做图标.


现在要做一个携带两个图标的资源文件, 并调用的例子.

1、首先建新工程, 保存, 注意这次我们不删除 {$R *.res}

2、复制两个 ico 文件到工程目录, 譬如文件是: IcoFile_1.ico、IcoFile_2.ico

3、建立文本文件输入:
ico1 ICON IcoFile_1.ico
ico2 ICON IcoFile_2.ico

然后保存为: MyRes.rc, 并 Add 到工程中, 如图:


4、此时的工程文件会自动插入: {$R 'MyRes.res' 'MyRes.rc'}

5、添加四个按钮, 实现代码如下:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//使用资源中的第一个自定义图标
procedure TForm1.Button1Click(Sender: TObject);
begin
  Application.Icon.Handle := LoadIcon(HInstance, 'ico1');
{
  HInstance 当前程序实例的句柄, 调用资源文件一定要用到它;
  ico1 是资源文件的标识符;
  LoadIcon 是个 API 函数, 专门用于调用资源中的 ico 文件, 它返回的是指定 ico 文件的句柄.
}
end;

//使用资源中的第二个自定义图标
procedure TForm1.Button2Click(Sender: TObject);
begin
  Application.Icon.Handle := LoadIcon(HInstance, 'ico2');
end;

//使用资源中默认的程序图标
procedure TForm1.Button3Click(Sender: TObject);
begin
  Application.Icon.Handle := LoadIcon(HInstance, 'MainIcon');
end;

//不使用图标(会显示 Windows 系统的默认图标)
procedure TForm1.Button4Click(Sender: TObject);
begin
  Application.Icon := nil;
end;

end.

//效果图:



注释:

1、此时的 MyRes.rc 被编译成了 MyRes.res;

2、此时的 IcoFile_1.ico、IcoFile_2.ico 文件被编译进 MyRes.res;

3、此时的 MyRes.res 文件也被编译到 Project1.exe 中了.


首先编辑 rc 文件如下(假定图片文件放在程序目录下的 img 文件夹下):
bmp1 BITMAP img/bmpFile1.bmp
bmp2 BITMAP img/bmpFile2.bmp

或者:
bmp1,BITMAP,img/bmpFile1.bmp
bmp2,BITMAP,img/bmpFile2.bmp

然后在窗体上添加一个 Image、两个 Button, 代码如下:


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Image1.AutoSize := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Image1.Picture.Bitmap.Handle := LoadBitmap(HInstance, 'bmp1');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  image1.Picture.Bitmap.LoadFromResourceName(HInstance, 'bmp2');
end;

end.

//效果图:


首先编辑 rc 文件如下(假定图片文件放在程序目录下的 img 文件夹下):
1 BITMAP img/bmpFile1.bmp
2 BITMAP img/bmpFile2.bmp

或者:
1,BITMAP,img/bmpFile1.bmp
2,BITMAP,img/bmpFile2.bmp

这次我们是给每个资源做了编号, 没有取标识名称; 然后在窗体上添加两个 Button, 代码如下:


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  bit: TBitmap;

procedure TForm1.FormCreate(Sender: TObject);
begin
  bit := TBitmap.Create;
end;

//对只有编号的图片资源需要用 LoadFromResourceID 调用
procedure TForm1.Button1Click(Sender: TObject);
begin
  bit := TBitmap.Create;
  bit.LoadFromResourceID(HInstance, 1);
  Self.Brush.Bitmap := bit;
  Repaint;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  bit := TBitmap.Create;
  bit.LoadFromResourceID(HInstance, 2);
  Self.Brush.Bitmap := bit;
  Repaint;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  bit.Free;
end;

end.

//效果图:


//rc 文件:
cur1 CURSOR cur/kyodai.cur
cur2 CURSOR cur/static.cur

//或者
cur1,CURSOR,cur/kyodai.cur
cur2,CURSOR,cur/static.cur

//程序代码: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls; type TForm1 = class(TForm) Panel1: TPanel; Panel2: TPanel; procedure FormCreate(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin Screen.Cursors[1] := LoadCursor(HInstance, 'cur1'); Screen.Cursors[2] := LoadCursor(HInstance, 'cur2'); Panel1.Cursor := TCursor(1); //Panel1.Cursor := 1; 也可, 因为 TCursor 就是个数字类型. Panel2.Cursor := TCursor(2); end; end.
//效果图:

//rc 文件: MyMenu1 MENU begin Popup "File" begin MenuItem "&Open" MenuItem "&Save" MenuItem Separator MenuItem "E&xit" end end {严格的头可能是这样写: MyMenu1 MENU PRELOAD DISCARDABLE}


//程序代码:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, StdCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  hm: HMENU;
begin
  hm := LoadMenu(HInstance, 'MyMenu1');
  SetMenu(Handle, hm);
end;

end.

//效果图:

//rc 文件: StringTable begin 0 "AAAA" 1 "BBBB" 2 "CCCC" 3 "DDDD" end //也可以这样写: StringTable begin 0,"AAAA" 1,"BBBB" 2,"CCCC" 3,"DDDD" end //还可以这样写: StringTable { 0,"AAAA" 1,"BBBB" 2,"CCCC" 3,"DDDD" } {严格的头可能是这样写: STRINGTABLE DISCARDABLE}


//程序代码:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Memo1.Clear;
  with Memo1.Lines do
  begin
    Add(LoadStr(0));
    Add(LoadStr(1));
    Add(LoadStr(2));
    Add(LoadStr(3));   
  end;
end;

end.

//效果图:

//rc 文件:
sound1 WAVE "SoundFile1.wav"
sound2 WAVE "SoundFile2.wav"

//代码: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} uses MMSystem; {下面用到的 sndPlaySound、PlaySound 都是在此单元声明的} procedure TForm1.Button1Click(Sender: TObject); var rs: TResourceStream; begin rs := TResourceStream.Create(HInstance, 'sound1', 'WAVE'); sndPlaySound(rs.Memory, SND_ASYNC or SND_MEMORY); rs.Free; end; procedure TForm1.Button2Click(Sender: TObject); var rs: TResourceStream; begin rs := TResourceStream.Create(HInstance, 'sound2', 'WAVE'); PlaySound(rs.Memory, HInstance, SND_ASYNC or SND_MEMORY); rs.Free; end; end.
 
//下面是 Windows 支持的资源格式:
RT_CURSOR       = MakeIntResource(1);
RT_BITMAP       = MakeIntResource(2);
RT_ICON         = MakeIntResource(3);
RT_MENU         = MakeIntResource(4);
RT_DIALOG       = MakeIntResource(5);
RT_STRING       = MakeIntResource(6);
RT_FONTDIR      = MakeIntResource(7);
RT_FONT         = MakeIntResource(8);
RT_ACCELERATOR  = MakeIntResource(9);
RT_RCDATA       = Types.RT_RCDATA; //MakeIntResource(10);
RT_MESSAGETABLE = MakeIntResource(11);
   DIFFERENCE   = 11;
RT_GROUP_CURSOR = MakeIntResource(DWORD(RT_CURSOR + DIFFERENCE));
RT_GROUP_ICON   = MakeIntResource(DWORD(RT_ICON + DIFFERENCE));
RT_VERSION      = MakeIntResource(16);
RT_DLGINCLUDE   = MakeIntResource(17);
RT_PLUGPLAY     = MakeIntResource(19);
RT_VXD          = MakeIntResource(20);
RT_ANICURSOR    = MakeIntResource(21);
RT_ANIICON      = MakeIntResource(22);

//尽管 Windows 规定 RCDATA 用作自定义格式, 我们也可以自定义格式名称, 譬如本例(rc 文件): MyFile1 RCDATA "c:/Windows/system32/notepad.exe" MyFile2 MyRes "c:/Windows/System32/calc.exe" {上面把 notepad.exe 时指定为 RCDATA 格式; 把 calc.exe 就指定成了自定义的 MyRes 格式}
//本例在资源中嵌入了记事本和计算器, 然后提取并调用: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var rs: TResourceStream; begin rs := TResourceStream.Create(HInstance, 'MyFile1', RT_RCDATA); rs.SaveToFile('c:/temp/pad.exe'); WinExec('c:/temp/pad.exe', 1); rs.Free; end; procedure TForm1.Button2Click(Sender: TObject); var rs: TResourceStream; begin rs := TResourceStream.Create(HInstance, 'MyFile2', 'MyRes'); rs.SaveToFile('c:/temp/sum.exe'); WinExec('c:/temp/sum.exe', 1); rs.Free; end; end.
 


本例将把一张 bmp 图片, 以资源文件的方式嵌入 dll, 然后再调用.



第一步: 建一个 DLL 工程, 如图:


然后保存, 我这里使用的名称都是默认的.



第二步: 建一个资源原文件, 如图:


编辑内容如下(路径中的文件一定要存在):
img1 BITMAP "c:/temp/test.bmp"

然后, 取个名(后缀须是 rc, 我这里取名为 Res.rc), 保存在工程目录下.



第三步: 在 DLL 工程中添加这个资源原文件, 如图:


此时, 工程源文件中会添加一句: {$R 'Res.res' 'Res.rc'}, 我们需要的源文件这样即可:

library Project1; {$R 'Res.res' 'Res.rc'} begin end.

然后 Ctrl+F9 编译; 此时在工程目录下会生成我们需要的 Project1.dll.



第四步: 把刚才的 Project1.dll 文件复制到 c:/temp 下.
这样过会我们可以通过 c:/temp/Project1.dll 找到这个文件. 至此 DLL 制作完毕.



第五步: 重新建一个 VCL Forms Application 工程, 代码如下:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
    procedure FormPaint(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormPaint(Sender: TObject);
var
  h: THandle;
  bit: TBitmap;
begin
  h := LoadLibrary('c:/temp/Project1.dll'); {载入 DLL}

  bit := TBitmap.Create;
  bit.LoadFromResourceName(h, 'img1');      {提取资源}

  Canvas.Draw(10, 10, bit);                 {在窗体上绘制图片}

  FreeLibrary(h);                           {载卸 DLL}
  bit.Free;
end;

end.

//效果图:

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics