フォルダ選択ダイアログボックス
ファイルを選ぶダイアログボックスは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.
|