需要从文件路径获取外壳文件路径。
查询MSDN,找到SHParseDisplayName这个函数。函数说明如下:
SyntaxHRESULT SHParseDisplayName(          LPCWSTR pszName,
    IBindCtx *pbc,
    PIDLIST_ABSOLUTE *ppidl,
    SFGAOF sfgaoIn,
    SFGAOF *psfgaoOut
);
ParameterspszName
[in] Pointer to a zero-terminated wide string that contains the display name to parse.
pbc
[in] A bind context that controls the parsing operation. This parameter is normally set to NULL.
ppidl
[out] Address of a pointer to a variable of type ITEMIDLIST that receives the item identifier list for the object. If an error occurs, then this parameter is set to NULL.
sfgaoIn
[in] A ULONG value that specifies the attributes to query. To query for one or more attributes, initialize this parameter with the flags that represent the attributes of interest. For a list of available SFGAO flags, see IShellFolder::GetAttributesOf.
psfgaoOut
[out] Pointer to a ULONG. On return, those attributes that are true for the object and were requested in sfgaoIn are set. An object's attribute flags can be zero or a combination of SFGAO flags. For a list of available SFGAO flags, see IShellFolder::GetAttributesOf.
Return ValueReturns S_OK if successful, or an error value otherwise.我的调用过程是这个procedure TForm1.Button1Click(Sender: TObject);
var
  ir: integer;
  wPath: WideString;
  pbc: IBindCtx;
  ppidl: PItemIDList;
  sfgaoIn, psfgaoOut: Cardinal;
begin
  wPath := Edit1.Text;
  sfgaoin := 0;
  new(ppidl);
  pbc := nil;
  ir := SHParseDisplayName(@wPath[1], pbc, ppidl, SFGAO_CANCOPY, psfgaoOut);
  if S_OK = ir then
  begin
    if SHGetPathFromIDList(ppidl, @wPath[1]) then
      Form1.Caption := wPath;
  end;
  dispose(ppidl);
end;运行中,发现在ir := SHParseDisplayName(@wPath[1], pbc, ppidl, SFGAO_CANCOPY, psfgaoOut);这句总会出现Access error。
请问各位高人原因大概在什么地方,或者大家有没有使用范例?

解决方案 »

  1.   

    function SHParseDisplayName(pszPath: PChar; pbc: pointer; var pidl: PItemIDList; sfgaoIn: LongWord; var psfgaoOut: LongWord): LongInt; stdcall; external 'shell32.dll' name 'SHParseDisplayName';
      

  2.   

    谢谢楼上关注。我用的D2010,引用的ShlObj已经定义了导出函数详细信息。问题应该不是出在这里。另,详细出错信息是' Access violation at address 7D5BE20A in module 'shell32.dll'. Read of address 00000028'。希望有参考意义
      

  3.   

    一直没办法正常调用 SHParseDisplayName,不过找到了从地址得到pidl的其它函数SHILCreateFromPath。说明如下:SHILCreateFromPath Function--------------------------------------------------------------------------------Creates a pointer to an item identifier list (PIDL) from a path.SyntaxHRESULT SHILCreateFromPath(          LPCWSTR pszPath,
        PIDLIST_ABSOLUTE *ppidl,
        DWORD *rgflnOut
    );
    ParameterspszPath
    [in] Pointer to a null-terminated string of maximum length MAX_PATH containing the path to be converted.
    ppidl
    [out] The path in pszPath expressed as a PIDL.
    rgflnOut
    [in, out] Pointer to a DWORD value that, on entry, indicates any attributes of the folder named in pszPath that the caller would like to retrieve along with the PIDL. On exit, this value contains those requested attributes. For a list of possible attribute flags for this parameter, see IShellFolder::GetAttributesOf.执行例程如下:
    procedure TForm1.Button1Click(Sender: TObject);
    var
      ir: integer;
      wPath: WideString;
      ppidl: PItemIDList;
      sfgao: Cardinal;
    begin
      wPath := Edit1.Text;
      sfgao := 0;
      ir := SHILCreateFromPath(@wPath[1], ppidl, sfgao);
      if S_OK = ir then
      begin
        if SHGetPathFromIDList(ppidl, @wPath[1]) then
          Form1.Caption := wPath;
      end;
    end;感谢楼上关注。依然期待SHParseDisplayName 函数正确调用方法