微信公众号 
图码生活

每天发布有五花八门的文章,各种有趣的知识等,期待您的订阅与参与
电脑报 1992-2001 十年文章全集
电脑报 1992-2001 十年文章全集
包含从 1992 年 - 2001 年间,两万余篇期刊文章,查询最少输入两个字符
随便看看
读取中
读取中
标题用C++ Builder编程提取图标资源
栏目软件世界
作者骆名群
发布2000年第41期
  有时我们看到某个文件的图标很新颖,想把它保存下来,但却找不到合适的工具,能不能自己编个程序提取文件的图标呢?经过摸索,终于成功。下面以C++ Builder为例,介绍文件图标的提取过程。
  Windows提供了一个API函数ExtractIcon,它能从指定的exe、dll、icon及其它含有图标的文件中提取图标,其原型如下:
  HICON ExtractIcon(
  HINSTANCE hInst,
  LPCTSTR lpszExeFileName,
  UINT nIconIndex
   );
  其参数意义如下:
  hInst:进程句柄
  lpszExeFileName:含有图标的文件名
  nIconIndex:要提取的图标索引值,若nIconIndex=-1,则函数返回此文件所含的图标数目。
  运行C++ Builder,新建一工程,将此工程文件保存为icon.bpr,主窗口文件保存为main.cpp,向主窗口添加控件,主要控件有:快捷按钮SB_Open、图像控件Image1、编辑框Edit1、打开文件对话框OpenDialog1、保存图像对话框SavePictureDialog1、刻度条TrackBar1、状态条StatusBar1,如

所示。
  编辑框是用来显示需提取图标的文件名,在SB_OpenClick的OnClick事件中写入如下代码:
  void __fastcall TForm1::SB_OpenClick(TObject *Sender)
  {
  if(OpenDialog1->Execute())
  { //获得打开的文件名
   FileName=OpenDialog1->FileName;
   //分解文件名并显示在Edit1框中
   Edit1->Text=ExtractFileName(FileName);
   TrackBar1->Min=0;
   //得到此文件所含的图标数目,并赋给TrackBar1->Max
   TrackBar1->Max=(int)ExtractIcon(HInstance,FileName.c_str(),-1);
   TrackBar1->Position=0;
   //在状态条上显示图标数目
   StatusBar1->SimpleText="此文件共含有图标"+IntToStr(TrackBar1->Max)+"个";
   //index是一个全局变量,指示当前提取的图标索引值
   index=TrackBar1->Min;
   //根据index值,得到当前的图标,将索引图标的句柄赋给Image1
  //从而可以在Image1框中显示此icon
   Image1->Picture->Icon->Handle =ExtractIcon(HInstance,FileName.c_str(),index); }
  }
  在刻度条TrackBar1的OnChange事件中写入如下代码:
  void __fastcall TForm1::TrackBar1Change(TObject *Sender)
  { //将刻度条的变化赋给全局变量index,并显示变化后的图标
  index=TrackBar1->Position;
  Image1->Picture->Icon->Handle =ExtractIcon(HInstance,FileName.c_str(),index);
  }
  若要保存指定的icon,其代码如下:
  void __fastcall TForm1::TB_SaveClick(TObject *Sender)
  { if(SavePictureDialog1->Execute())
  { Image1->Picture->SaveToFile(SavePictureDialog1->FileName);}
  }
  若要保存此文件含有的所有图标,其代码如下:
  void __fastcall TForm1::TB_SaveAllClick(TObject *Sender)
  {
   AnsiString path,FileExt;
   SavePictureDialog1->FileName="请选择保存路径";
   if(SavePictureDialog1->Execute())
   {
   path=ExtractFilePath(SavePictureDialog1->FileName)+"\\";
   FileExt=ExtractFileExt(SavePictureDialog1->FileName);
  //循环保存每个图标,每个图标的索引值即为它的文件名
   for(int i=0;i<TrackBar1->Max;i++)
   {
  Image1->Picture->Icon->Handle=ExtractIcon(HInstance,FileName.c_str(),i);
  Image1->Picture->SaveToFile(path+IntToStr(i)+FileExt);
   }
   }}
  至于查看当前图标的上一个或下一个图标,其代码就很简单了:
  //查看上一个图标
  void __fastcall TForm1::TB_PriorClick(TObject *Sender)
  {   index--;
  TrackBar1->Position--;
  Image1->Picture->Icon->Handle =ExtractIcon(HInstance,FileName.c_str(),index);
  }
  //查看下一个图标
  void __fastcall TForm1::TB_NextClick(TObject *Sender)
  {
   index++;
   TrackBar1->Position++;
   Image1->Picture->Icon->Handle =ExtractIcon(HInstance,FileName.c_str(),index);
  }
  编译此工程文件并运行,一个版权属于你的图标提取器诞生了,欢迎与我探讨( lmq@4y.com.cn )。本程序在Win98,C++ Builder5下运行通过。