フォルダ選択ダイアログボックス
ファイルを選ぶダイアログボックスはOpenDialogコンポーネントなどを使って簡単に表示できますが、フォルダを選ぶダイアログボックスはDirectoryListBoxコンポーネントなどを組み合わせて作るなどをして表示させるしかありません。
ところが、Win32 APIを使うとフォルダ選択ダイアログ(下の図)を表示させることができます。ただし、けっこう面倒です。
使うAPI関数は、SHBrowseForFolderとSHGetPathFromIDListです。つまり、SHBrowseForFolderでフォルダのIDリストを取得して、SHGetPathFromIDListでフォルダ名に変換するという2段階の手順をとります。
これらのAPI関数はWindowsパッケージで宣言されていないので、プログラムの中で宣言する必要があります。次にサンプルを示します。
unit Main; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type SHITEMID = record cb: Word; abID: PByte; end; ITEMIDLIST = record mkid: SHITEMID; end; LPITEMIDLIST = ^ITEMIDLIST; BROWSEINFO = record hwndOwner: LongWord; pidlRoot: LPITEMIDLIST; pszDisplayName: PChar; lpszTitle: PChar; ulFlags: LongWord; lpfn: Pointer; lParam: LongWord; iImage: Integer; end; LPBROWSEINFO = ^BROWSEINFO; TForm1 = class(TForm) Button1: TButton; Label1: TLabel; procedure Button1Click(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.DFM} function SHBrowseForFolder(lpbi: LPBROWSEINFO): LPITEMIDLIST; stdcall; external 'Shell32.dll'; function SHGetPathFromIDList(idlist: LPITEMIDLIST; pszPath: PChar): LongWord; stdcall; external 'Shell32.dll'; procedure TForm1.Button1Click(Sender: TObject); var bi: BROWSEINFO; buff: PChar; idlist: LPITEMIDLIST; lpDir: PChar; begin buff := StrAlloc(MAX_PATH); lpDir := StrAlloc(MAX_PATH); bi.hwndOwner := Self.Handle; bi.pidlRoot := nil; bi.pszDisplayName := buff; bi.lpszTitle := 'フォルダを選んでください'; bi.iImage := 0; bi.ulFlags := 0; bi.lParam := 0; bi.lpfn := nil; idlist := SHBrowseForFolder(@bi); if idlist <> nil then begin SHGetPathFromIDList(idlist, lpDir); Label1.Caption := lpDir; end; StrDispose(buff); StrDispose(lpDir); end; end. |