Why does SHParseDisplayName give an access violation if I import it myself?

I get an access violation when I try to get the pidl form in Delphi, and the returned pidl is zero. This is my code:

type
  // TParseDisplayName = function(pszPath: PChar; pbc: pointer; var pidl: PItemIDList; sfgaoIn: LongWord; var psfgaoOut: LongWord): LongInt;
  TParseDisplayName = function(pszPath: PWideChar; pbc: IBindCtx; var pidl: PItemIDList; sfgaoIn: ULong; var psfgaoOut: ULong): HResult;

var
  SHParseDisplayName: TParseDisplayName;
  SHELL32DLLHandle : THandle;

procedure test();
var
  ws : WideString;
  tmpLongWord: ULong;
  lpItemID: PItemIDList;
begin
  //ws := 'Mes documents';

  CoInitialize(nil);

  // path to test
  ws := 'C:\inetsdk\Nouveau Document WordPad.doc';

  if (SHParseDisplayName(PWideChar(ws), nil, lpItemID, 0, tmpLongWord) = S_OK) then
    if not assigned(lpItemID) then      
      s := SysErrorMessage(getLastError);

  CoUnInitialize();
end;

initialization
  SHELL32DLLHandle  := LoadLibraryW('shell32.dll');

  @SHParseDisplayName := GetProcAddress(SHELL32DLLHandle, 'SHParseDisplayName');
+5
source share
1 answer

The declaration TParseDisplayNameomits the calling convention. You must enable stdcall.

TParseDisplayName = function(pszPath: PWideChar; pbc: IBindCtx; 
  var pidl: PItemIDList; sfgaoIn: ULong; var psfgaoOut: ULong): HResult; stdcall;

If you do not specify a calling convention, the default calling convention is used. The default calling convention is register. This has different semantics for passing and clearing parameters, which leads to the type of runtime error you encountered. Almost all the functions of the Windows API are used stdcall.

+5

All Articles