从文件中提取图标
下面,图老师小编带您去了解一下从文件中提取图标,生活就是不断的发现新事物,get新技能~
----大家知道,包含在可执行模块中的图标资源是以二进制数据(或称,资源)的形式存储的,因而,我们应该把这些二进制数据转换成图标文件的格式,然后再存为图标文件(*.ICO)。因为有了InpriseCorporation(原BorlandInternational)的Delphi提供的强大的类库和可视化支持,这项工作已变得相对比较轻松了。Delphi提供了TIcon类,该类中有一个名为SaveToFile的方法,它可方便地把对象所指的二进制数据直接存储成图标格式的文件。于是,要从其它可执行模块中提取图标,我们只需把其它模块中的二进制数据"拷"到一个TIcon对象中即可(在下面的程序中使用了一个TImage构件,该构件中包含了一个TIcon对象)。那么,怎样把数据拷到TIcon对象中呢?其实,你只需把一个图标的句柄赋给TIcon对象的句柄属性,其它细节都由Delphi代我们完成。我们可以通过Windows的API函数ExtractIcon来获取其它模块中图标的句柄。下面的这个程序可以让你轻松地浏览文件中所包含的所有图标,并且可以方便地保存下你喜欢的图标(如果此文件包含有图标资源的话)。此外,该程序还可以把位图文件(*.BMP)或图元文件(Metafile)缩小成图标文件。为了让大家更轻松地阅读此程序,笔者已经使程序的代码尽可能的短小,读者可在本示例的基础上进行其它的扩充。
----向Form1上加入如下构件:
----(1)从Standard页上选取3个TButton构件,并把Button1、Button2和Button3的Caption分别改为"向前浏览"、"向后浏览"和"保存图标"。把Button1和Button2的Tag属性分别改为1和-1(负1)。让Button2跟Button1共用一个OnClick事件句柄。
----(2)从Standard页上选取一个TMainMenu构件,把第一个菜单项(缺省名为N1)的Caption改为"文件",再把它下面的菜单项(N2)的Caption改为"打开文件"。
----(3)从Standard页上选取一个TLabel
----(4)从Additional页上选取一个TImage
----(5)从Dialogs页上选取一个TOpenDialog,并把它的Options属性的ofNoReadOnlyReturn子属性改为False。
----(6)将Form1的Font改成System字体。
----(7)在Unit1的Interface部分的Uses语句中加入ShellAPI单元(以便使用API函数ExtractIcon)。
unitUnit1;
interface
uses
Windows,Messages,SysUtils,Classes,
Graphics,Controls,Forms,Dialogs,
Menus,StdCtrls,ExtCtrls,ShellAPI;
type
TForm1=class(TForm)
Image1:TImage;
Button1:TButton;
Button2:TButton;
Button3:TButton;
MainMenu1:TMainMenu;
N1:TMenuItem;
N2:TMenuItem;
Label1:TLabel;
OpenDialog1:TOpenDialog;
procedureButton1Click(Sender:TObject);
procedureFormCreate(Sender:TObject);
procedureButton3Click(Sender:TObject);
procedureN2Click(Sender:TObject);
private
{Privatedeclarations}
public
{Publicdeclarations}
end;
var
Form1:TForm1;
Total,//文件中图标的总数
No:Integer;//当前图标在原文件中的序号
Path,//程序所在的路径
ModuleName:String;//从哪个文件提取图标
implementation
{$R*.DFM}
procedureTForm1.Button1Click(Sender:TObject);
//该事件句柄被Button1和Button2所共享
//Button1和Button2的Caption
分别是"向前浏览"和"向后浏览"
//Button1和Button2的Tag分别是1和-1
begin
ifTotal=0ThenExit;
No:=No (SenderasTButton).tag;
ifNoTotalthenNo:=0;
ifNo0thenNo:=Total;
Image1.Picture.Icon:=nil;
Image1.Picture.Icon.Handle:
=ExtractIcon(hInstance,PChar(ModuleName),No);
Label1.Caption:='No.' IntToStr(No) 'icon';
//Label1用于指示当前图标在原文件中的序号
end;
procedureTForm1.FormCreate(Sender:TObject);
begin
Path:=ExtractFilePath(Application.ExeName);
//下面的代码使程序有处理命令行参数的能力
ifParamCount0
Thenbegin
ModuleName:=ParamStr(1);
Total:=ExtractIcon(hInstance,PChar(ModuleName),-1);
Form1.caption:=IntToStr(Total)
'icon(s)foundin' ParamStr(1);
end;
end;
procedureTForm1.Button3Click(Sender:TObject);
//这段代码保存当前图标
begin
IfTotal=0ThenExit;
Image1.Picture.Icon.SaveToFile
(Path 'Icon' IntToStr(No) '.ico');
{把图标文件与该程序存于
同一目录,文件名为"Icon"加序号的形式}
end;
procedureTForm1.N2Click(Sender:TObject);
//这段代码从菜单中选择一个文件
begin
IfOpenDialog1.Execute
thenbegin
ModuleName:=OpenDialog1.FileName;
Total:=ExtractIcon(hInstance,PChar(ModuleName),-1);
No:=0;Label1.Caption:='';
Form1.Caption:=IntToStr(Total) 'icon(s)foundin' ModuleName;
end;
end;
end.
(调试环境:Delphi4.0,Windows95,WindowsNT4)
----说明:API函数ExtractIcon是在ShellAPI单元中声明的,所以你必须在Uses语句中加入此单元才能使用该函数。它在Delphi中的原型声明如下:
----functionExtractIcon(hInst:HINST;lpszExeFileName:PChar;nIconIndex:UINT):HICON;stdcall;
----参数说明:
----hInst:为调用该函数的实例句柄;
----lpszExeFileName:指明从哪个文件提取图标(不一定非得是EXE文件);
----nIconIndex:该参数为负1时,函数返回指定文件中包含的图标个数;否则,返回序号为nIconIndex的图标(如果存在的话)的句柄。在文件中图标的序号是从0开始的。
----如果函数调用失败则返回0.->