如何正确调用SHGetImageList?有可能用它检索HIMAGELIST吗?

时间:2016-06-04 15:09:20

标签: delphi winapi imagelist

我试图检查shell的共享图片列表,看似简单明了(但实际上不是很清楚)PSDK documentation包括我可以在{{{{{{{{{ 1}}和HIMAGELIST类型(我后来发现可疑的第一件事)。所以,我写了下面的代码:

IImageList

但它工作得非常糟糕:API调用返回procedure TForm1.FormCreate(Sender: TObject); const IID_IImageList: TGUID = '{46EB5926-582E-4017-9FDF-E8998DAA0950}'; IID_IImageList2: TGUID = '{192B9D83-50FC-457B-90A0-2B82A8B5DAE1}'; var himl: HIMAGELIST; begin CoInitialize(nil); OleCheck(SHGetImageList(SHIL_LARGE, IID_IImageList, Pointer(himl))); ImageList1.Handle := himl; end; ,然后崩溃时出现多次访问冲突,这表明应用程序和库之间存在一些二进制不一致。但是,使用的函数I的Delphi导入看起来是正确的:

HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER)

第二个我在文档中发现令人困惑的是function SHGetImageList(iImageList: Integer; const riid: TGUID; var ppvObj: Pointer): HResult; function SHGetImageList; external shell32 name 'SHGetImageList' delayed; 参数描述只列出了一个可能的值 - riid,这可能与我检索句柄类型的意图不符。

那么,我该如何正确调用SHGetImageList? 是否可以用它来检索IID_IImageList

2 个答案:

答案 0 :(得分:8)

问题在于ShellAPI单位的德尔福股票声明。它缺少stdcall调用约定。要解决此问题,您可以在自己的代码中手动声明该函数:

function SHGetImageList(iImageList: Integer; const riid: TGUID;
  var ppvObj: Pointer): HResult; stdcall; external shell32;

procedure TTestForm.Button1Click(Sender: TObject);
const
  IID_IImageList: TGUID = '{46EB5926-582E-4017-9FDF-E8998DAA0950}';
var
  himl: HIMAGELIST;
begin
  //CoInitialize(nil);
  OleCheck(SHGetImageList(SHIL_LARGE, IID_IImageList, Pointer(himl)));
  ImageList1.Handle := himl;
end;

注意:如果您未删除项目源中的CoInitialize调用,则VCL应用程序已调用Application.Initialize

答案 1 :(得分:1)

  

那么,我该如何正确调用SHGetImageList?

函数输出是一个接口,因此您需要声明一个接口变量:

procedure TForm1.FormCreate(Sender: TObject);
var
  iml: IImageList;
begin
  CoInitialize(nil);
  OleCheck(SHGetImageList(SHIL_LARGE, IImageList, Pointer(iml)));
end;
  

是否有可能用它检索HIMAGELIST?

根据documentation

  

IImageList指针类型,例如ppv参数中返回的指针类型,可以根据需要转换为HIMAGELIST;例如,用于列表视图。相反,HIMAGELIST可以作为指向IImageList的指针。

procedure TForm1.FormCreate(Sender: TObject);
var
  iml: IImageList;
begin
  CoInitialize(nil);
  OleCheck(SHGetImageList(SHIL_LARGE, IImageList, Pointer(iml)));
  ImageList1.Handle := HIMAGELIST(iml); // or HIMAGELIST(Pointer(iml));
end;