Сколько себя помню у Delphi никогда не было своего компонента выбора папки типа TOpenDialog и каждый раз когда нужно было выбирать именно папку искал как это делается.
Вот теперь решил записать то что я нашел и немного переделал для себя.
Это пока функция, возможно когда-то сделаю компонент типа TOpenFolder.
И так всё эавязано на функции ShBrowseForFolder из модуля ShlObj или по новому Winapi.ShlObj.
Но множество примеров, которые я видел были без кнопки Create New Folder и без возможности установки пути по умолчанию.
И так код:
Вот теперь решил записать то что я нашел и немного переделал для себя.
Это пока функция, возможно когда-то сделаю компонент типа TOpenFolder.
И так всё эавязано на функции ShBrowseForFolder из модуля ShlObj или по новому Winapi.ShlObj.
Но множество примеров, которые я видел были без кнопки Create New Folder и без возможности установки пути по умолчанию.
И так код:
...
function SelectFolder(hWnd: HWND; const Caption: WideString; var Folder: WideString): boolean;
...
implementation
uses ShlObj, ActiveX, Forms;
var
DefaultPath: widestring = '';
...
//Эта функция нужна для установки пути по умолчанию
function BrowseCallbackProc(hwnd: HWND; uMsg: UINT; lParam: LPARAM; lpData: LPARAM): integer; stdcall;
begin
Result := 0;
if uMsg = BFFM_INITIALIZED then
SendMessage(hwnd, BFFM_SETSELECTION, 1, LongInt(PWideChar(DefaultPath)));
end;
function SelectFolder(hWnd: HWND; const Caption: WideString; var Folder: WideString): boolean;
var
WindowList: Pointer;
BrowseInfo : TBrowseInfo;
Buffer: PChar;
RootItemIDList, ItemIDList: PItemIDList;
ShellMalloc: IMalloc;
IDesktopFolder: IShellFolder;
Eaten, Flags: LongWord;
begin
FillChar(BrowseInfo, SizeOf(BrowseInfo), 0);
if (ShGetMalloc(ShellMalloc) = S_OK) and (ShellMalloc <> nil) then
begin
Buffer := ShellMalloc.Alloc(MAX_PATH);
try
DefaultPath := Folder;
RootItemIDList := nil;
with BrowseInfo do
begin
hwndOwner := hWnd;
pidlRoot := RootItemIDList;
pszDisplayName := Buffer;
lpfn := @BrowseCallbackProc;
lpszTitle := PWideChar(Caption);
ulFlags := BIF_RETURNONLYFSDIRS or $0040 or BIF_EDITBOX or BIF_STATUSTEXT;
end;
WindowList := DisableTaskWindows(0);
try
ItemIDList := ShBrowseForFolder(BrowseInfo);
finally
EnableTaskWindows(WindowList);
end;
Result := ItemIDList <> nil;
if Result then
begin
ShGetPathFromIDList(ItemIDList, Buffer);
ShellMalloc.Free(ItemIDList);
Folder := Buffer
end;
finally
ShellMalloc.Free(Buffer);
DefaultPath := '';
end;
end;
end;
Теперь пример использования:
procedure TframeGeneralSettings.Button1Click(Sender: TObject);
var
Value: WideString;
begin
Value := edtImagesFolder.Text;
if SelectFolder(Handle, 'Select ' + lblImagesFolder.Caption, Value) and (Value <> edtImagesFolder.Text) then
edtImagesFolder.Text := Value;
end;
Комментариев нет:
Отправить комментарий