• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 433
  • Last Modified:

SHBrowseForFolder - Preselecting a folder

I am trying to use SHBrowseForFolder to select a folder.
The callback procedure is preselecting a specific folder.


function SelectFolder(Caption, DefPath: string): string;
var
  bi: TBrowseInfo; 
  lpBuffer: PChar; 
  pidlPrograms, pidlBrowse: PItemIDList; 

  function BrowseCallbackProc(hwnd: HWND; uMsg: UINT; lParam: Cardinal; 
    lpData: Cardinal): Integer; stdcall; 
  var 
    PathName: array[0..MAX_PATH] of Char; 
  begin 
    case uMsg of 
      BFFM_INITIALIZED: 
        SendMessage(Hwnd, BFFM_SETSELECTION, Ord(True), Integer(lpData));
      BFFM_SELCHANGED:
        begin 
          SHGetPathFromIDList(PItemIDList(lParam), @PathName); 
          SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, Longint(PChar(@PathName))); 
        end;
    end; 
    Result := 0; 
  end;
begin
  if (not SUCCEEDED(SHGetSpecialFolderLocation(GetActiveWindow, CSIDL_DRIVES, 
    pidlPrograms))) then exit; 

  GetMem(lpBuffer, MAX_PATH );

  FillChar(BI, SizeOf(BrowseInfo), 0); 
  bi.hwndOwner := GetActiveWindow; 
  bi.pidlRoot := pidlPrograms; 
  bi.pszDisplayName := lpBuffer; 
  bi.lpszTitle := PChar(Caption); 
  bi.ulFlags := BIF_RETURNONLYFSDIRS or BIF_STATUSTEXT; 
  bi.lpfn := @BrowseCallbackProc; 
  bi.lParam := Integer(PChar(DefPath)); 

  pidlBrowse := SHBrowseForFolder(bi); 
...
end;

Open in new window


This works fine with 32-bit.
If i compile with 64 bit then it does not work.
BrowseCallbackProc is called twice - but uMsg is not 1 and 2 (like in the 32 bit version) but 0 the first time and the second time it is a high value.

Can anybody tell me where the problem is?


Windows 7 64 bit, Delphi XE6 & XE7
0
Treppenmeister
Asked:
Treppenmeister
  • 4
1 Solution
 
jimyXCommented:
There is a useful page under embarcadero DocWiKi, everyone moving up to 64Bit (or down to 32) should read.

In your case, pay attention, at Winapi Issues, to:
SendMessage(..., LPARAM());

It's a good practice to enclose your code with:
  {$IFDEF WIN32}
...
  {$ENDIF}
  {$IFDEF WIN64}
...
  {$ENDIF}

Open in new window

0
 
TreppenmeisterAuthor Commented:
I don't get it.
I understand that there are can be issues with SendMessage.
But it doesn't matter what I write there - uMsg in the Callback-Routine has not the right values, so SendMessage is never called. So possible adjustments to my SendMessage calls are only a second step.

There has to be another error somewhere. And I cannot see it.
0
 
TreppenmeisterAuthor Commented:
I realised now that in the callback routine the expected values 1 & 2 (BFFM_INITIALIZED & BFFM_SELCHANGED ) for uMsg seem to be set for hwnd (64-bit):
in the 1st call hwnd is 1, in the 2nd one hwnd is 2.
0
 
TreppenmeisterAuthor Commented:
I found the reason for the Problem - i would have never guessed it:
The callback function BrowseCallbackProc lies within of SelectFolder. This worked for 32 bit but not for 64 bit.
If i move the callback routine out of SelectFolder then it works also with 64 bit_

function BrowseCallbackProc( hwnd: HWND; uMsg: UINT; lParam, lpData: LPARAM ): Integer; stdcall; 
begin
end;

function SelectFolder(Caption, DefPath: string): string;
begin
end;

Open in new window

0
 
TreppenmeisterAuthor Commented:
I found the solution after many hours - including try and error.
I am not sure whether the callback has to be there (in the 'root') or whether it is a bug of Delphi (the problem exists in XE6 and XE7 - I didn't try XE8 yet)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now