Title: Using SHBrowseForFolder to locate specific file
Question: Heres an example on how to locate a folder with a specific filer, using SHBrowseForFolder and a BrowseCallBack function
Answer:
implementation
uses ShlObj, ShellApi;
function BrowseCallBack ( Hwnd : THandle; uMsg : UINT; lpParam, lpData : LPARAM): integer; stdcall;
var
Buffer : Array[0..255] of char;
Buffer2 : Array[0..255] of char;
TmpStr : String;
begin
// Initialize buffers
FillChar(Buffer,SizeOf(Buffer),#0);
FillChar(Buffer2,SizeOf(Buffer2),#0);
// Statusline text
TmpStr := 'Locate folder containing '+StrPas(PChar(lpData));
// Copy statustext to pchar
StrPCopy(Buffer2,TmpStr);
// Send message to BrowseForDlg that
// the status text has changed
SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,Integer(@Buffer2));
// If directory in BrowswForDlg has changed ?
if uMsg = BFFM_SELCHANGED then begin
// Get the new folder name
SHGetPathFromIDList(PItemIDList(lpParam),Buffer);
// And check for existens of our file.
{$IFDEF RX_D3} //RxLib - extentions
if FileExists(NormalDir(StrPas(Buffer))+StrPas(PChar(lpData)))
and (StrLen(Buffer) 0) then
{$ELSE}
if Length(StrPas(Buffer)) 0 then
if Buffer[Length(StrPas(Buffer))-1] = '\' then
Buffer[Length(StrPas(Buffer))-1] := #0;
if FileExists(StrPas(Buffer)+'\'+StrPas(PChar(lpData))) and
(StrLen(Buffer) 0) then
{$ENDIF}
// found : Send message to enable OK-button
SendMessage(hwnd,BFFM_ENABLEOK,1,1)
else
// Send message to disable OK-Button
SendMessage(Hwnd,BFFM_ENABLEOK,0,0);
end;
result := 0
end;
function BrowseforFile(Handle : THandle; Title : String; Filename : String) : String;
var
BrowseInfo : TBrowseInfo;
RetBuffer,
FName,
ResultBuffer : Array[0..255] of char;
PIDL : PItemIDList;
begin
StrPCopy(Fname,FileName);
//Initialize buffers
FillChar(BrowseInfo,SizeOf(TBrowseInfo),#0);
Fillchar(RetBuffer,SizeOf(RetBuffer),#0);
FillChar(ResultBuffer,SizeOf(ResultBuffer),#0);
BrowseInfo.hwndOwner := Handle;
BrowseInfo.pszDisplayName := @Retbuffer;
BrowseInfo.lpszTitle := @Title[1];
// we want a status-text
BrowseInfo.ulFlags := BIF_StatusText;
// Our call-back function cheching for fileexist
BrowseInfo.lpfn := @BrowseCallBack;
BrowseInfo.lParam := Integer(@FName);
// Show BrowseForDlg
PIDL := SHBrowseForFolder(BrowseInfo);
// Return fullpath to file
if SHGetPathFromIDList(PIDL,ResultBuffer) then
result := StrPas(ResultBuffer)
else
Result := '';
GlobalFreePtr(PIDL); //Clean up
end;