views:

395

answers:

1

Why will this not compile in Delphi 2009?

unit VistaFolders;

interface

uses Windows, ShellAPI, ShlObj;

type
  KNOWNFOLDERID = TGuid;

const
  FOLDERID_ProgramData: KNOWNFOLDERID =
    '{374DE290-123F-4565-9164-39C4925E467B}'; // downloads folder

var
  SHGetKnownFolderPathFunc: function( const rfid: KNOWNFOLDERID;
    dwFlags: DWORD; hToken: THandle; var ppszPath: PWideChar ): HResult; stdcall;
  SHGetKnownFolderIDListFunc: function( const rfid: KNOWNFOLDERID;
    dwFlags: DWORD; hToken: THandle; var ppidl: PItemIDList ): HResult; stdcall;

  function GetDownloadsFolderPath: string;

implementation

uses ActiveX;

function PathFromIDList( Pidl: ShlObj.PItemIdList ): string;
var
  Path: array[ 0..MAX_PATH ] of Char;
begin
  if SHGetPathFromIDList( Pidl, Path ) then
    Result := Path
  else
    Result := '';
end;

function GetDownloadsFolderPath: string;
var
  Path: PWideChar;
  Pidl: PItemIdList;
begin
  Result := '';
  if @SHGetKnownFolderPathFunc <> nil then
  begin
    if Succeeded( SHGetKnownFolderPathFunc( FOLDERID_ProgramData, 0, 0, Path ) ) then
      begin
        try
          Result := Path;
        finally; CoTaskMemFree( Path ); end;
        Exit;
      end;
  end
  else if @SHGetKnownFolderIDListFunc <> nil then
  begin
    if Succeeded( SHGetKnownFolderIDListFunc( FOLDERID_ProgramData, 0, 0, Pidl ) ) then
      begin
        try
          Result := PathFromIDList( Pidl );
        finally; CoTaskMemFree( Pidl ); end;
        Exit;
      end;
  end;
  if Succeeded( SHGetFolderLocation( 0, CSIDL_PROFILE, 0, 0, Pidl ) ) then
    try
      Result := PathFromIDList( Pidl ) + '\Downloads';
    finally; CoTaskMemFree( Pidl ); end;
end;

procedure InitVistaFunctions;
var
  hShell32: THandle;
begin
  hShell32 := GetModuleHandle( 'SHELL32' );
  @SHGetKnownFolderPathFunc := Windows.GetProcAddress( Shell32, 'SHGetKnownFolderPath' );
  @SHGetKnownFolderIDListFunc := Windows.GetProcAddress( Shell32, 'SHGetKnownFolderIDList' );
end;

initialization
  InitVistaFunctions;

end.
+6  A: 

Because you give Shell32 instead of hShell32 in the GetProcAddress calls.

If you wonder why it fails with

There is no overloaded version of 'GetProcAddress' that can be called with these arguments

you could ctrl-click on the first parameter, and the IDE will take you to the constant that the compiler finds for Shell32.

mghie