获取程序大图标方案

获取文件的图标

在win7的文件状态栏中能显示最大256x256的程序应用图标。

在XP下测试无法正常获取256的巨型图标

Shell提供了一个函数 SHGetFileInfo 可以获取文件信息,在使用此函数有需要处理Icon句柄的释放(DestroyIcon),否则每次会有3个GDI句柄泄漏问题。

使用此函数后会一次性产生47个GDI句柄,只要Icon句柄释放,就不会再增长。现在还未找到处理多处理啊的调用所产生的这些GDI句柄。

 

注意:

  GHGetFileInfo 和 DestoryIcon 成对调用。

 

测试环境

   Win7 and XE2

 

 

View Code
unit Unit4;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm4 = class(TForm)
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form4: TForm4;

implementation

uses
  ShellApi, Commctrl, ShlObj;

{$R *.dfm}


const
  SHIL_LARGE     = $00;  //The image size is normally 32x32 pixels. However, if the Use large icons option is selected from the Effects section of the Appearance tab in Display Properties, the image is 48x48 pixels.
  SHIL_SMALL     = $01;  //These images are the Shell standard small icon size of 16x16, but the size can be customized by the user.
  SHIL_EXTRALARGE= $02;  //These images are the Shell standard extra-large icon size. This is typically 48x48, but the size can be customized by the user.
  SHIL_SYSSMALL  = $03;  //These images are the size specified by GetSystemMetrics called with SM_CXSMICON and GetSystemMetrics called with SM_CYSMICON.
  SHIL_JUMBO     = $04;  //Windows Vista and later. The image is normally 256x256 pixels.
  IID_IImageList: TGUID= '{46EB5926-582E-4017-9FDF-E8998DAA0950}';

function GetImageListSH(SHIL_FLAG:Cardinal): HIMAGELIST;
type
  _SHGetImageList = function (iImageList: integer; const riid: TGUID; var ppv: Pointer): hResult; stdcall;
var
  Handle        : THandle;
  SHGetImageList: _SHGetImageList;
begin
  Result:= 0;
  Handle:= LoadLibrary('Shell32.dll');
  if Handle<> S_OK then
  try
    SHGetImageList:= GetProcAddress(Handle, PChar(727));
    if Assigned(SHGetImageList) and (Win32Platform = VER_PLATFORM_WIN32_NT) then
      SHGetImageList(SHIL_FLAG, IID_IImageList, Pointer(Result));
  finally
    FreeLibrary(Handle);
  end;
end;


procedure GetIconFromFile(aFile:String; var aIcon : TIcon;SHIL_FLAG:Cardinal);
var
  aImgList    : HIMAGELIST;
  SFI         : TSHFileInfo;
Begin
    //Get the index of the imagelist
    SHGetFileInfo(PChar(aFile), FILE_ATTRIBUTE_NORMAL, SFI,
                 SizeOf( TSHFileInfo ), SHGFI_ICON or SHGFI_LARGEICON or SHGFI_SHELLICONSIZE or
                 SHGFI_SYSICONINDEX or SHGFI_TYPENAME or SHGFI_DISPLAYNAME );

    if not Assigned(aIcon) then
    aIcon:= TIcon.Create;
    //get the imagelist
    aImgList:= GetImageListSH(SHIL_FLAG);
    //extract the icon handle
    aIcon.Handle:= ImageList_GetIcon(aImgList, Pred(ImageList_GetImageCount(aImgList)), ILD_NORMAL);

    DestroyIcon(SFI.hIcon);
    ImageList_Destroy(aImgList);
end;

procedure TForm4.btn1Click(Sender: TObject);
var
  icon:TIcon;
begin
  icon := TIcon.Create;
  try
    GetIconFromFile(ParamStr(0), icon, SHIL_JUMBO);
    canvas.Draw(10, 100, icon);
    Canvas.TextOut(10, 80, inttostr(icon.Handle));

    GetIconFromFile(ParamStr(0), icon, SHIL_SYSSMALL);
    canvas.Draw(10+ 280 , 100, icon);
    Canvas.TextOut(10 + 280, 80, inttostr(icon.Handle));

    GetIconFromFile(ParamStr(0), icon, SHIL_EXTRALARGE);
    canvas.Draw(10+ 280 + 150 , 100, icon);
    Canvas.TextOut(10+ 280 + 150, 80, inttostr(icon.Handle));

    GetIconFromFile(ParamStr(0), icon, SHIL_LARGE);
    canvas.Draw(10+ 280 + 150 +50 , 100, icon);
    Canvas.TextOut(10+ 280 + 150 +50, 80, inttostr(icon.Handle));

    GetIconFromFile(ParamStr(0), icon, SHIL_SMALL);
    canvas.Draw(10+ 280 + 150 +50 +40, 100, icon);
    Canvas.TextOut(10+ 280 + 150 +50 +40, 80, inttostr(icon.Handle));
  finally
    icon.Free;
  end;

end;

end.

 

详细内容可以看

http://www.codeproject.com/Articles/2532/Obtaining-and-managing-file-and-folder-icons-using

有比较详细的使用说明

posted @ 2012-11-21 11:45  cmacro  阅读(3625)  评论(5编辑  收藏  举报