Windows シェルは、フォルダをユーザー操作によって選択するための機能を提供しています。これは、フォルダを選択するダイアログボックスを表示して、ユーザーに選択させるというものです。
手順は以下のようになります。
フォルダ選択ダイアログボックスの表示には、 SHBrowseForFolder 関数を使います。この関数は、ユーザーによるフォルダ選択操作ができる[フォルダの参照]ダイアログボックスを表示し、ユーザーが指定したアイテムのPIDLを返すものです。
まずは、 BROWSEINFO 構造体に必要な情報を格納します。
typedef struct _browseinfo {
HWND hwndOwner;
LPCITEMIDLIST pidlRoot;
LPTSTR pszDisplayName;
LPCTSTR lpszTitle;
UINT ulFlags;
BFFCALLBACK lpfn;
LPARAM lParam;
int iImage;
} BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO;
hwndOwner メンバには、ダイアログボックスのオーナーウィンドウのハンドルを指定します。 pidlRoot メンバには、表示するダイアログボックスの中のツリービューのルートフォルダをPIDLで指定しますが、デスクトップをルートとする場合は 0 (NULL) を指定できます。 pszDisplayName メンバには、選択されたアイテムの表示文字列を格納する文字列変数のアドレスを指定します。 lpszTitle メンバには、ツリーの上部に表示する文字列のアドレスを指定します。 ulFlags メンバには、どのようなフォルダを取得できるようにするのかを指定します。例えば、ファイルシステムディレクトリのみを取得したい場合には 0x0001 (BIF_RETURNONLYFSDIRS) を指定します。その他のメンバはここでは使用しないので、0 を格納しておきます
構造体に情報を格納できたら、SHBrowseForFolder 関数を呼び出します。
WINSHELLAPI LPITEMIDLIST WINAPI SHBrowseForFolderA(
LPBROWSEINFO lpbi
);
lpbi には BROWSEINFO 構造体のアドレスを指定します。この関数の戻り値として、選択されたアイテムのPIDLが返ります。キャンセルされた場合には、戻り値は 0 になります。
; BROWSEINFO 構造体
mref bmscr, 67 ; ウィンドウの BMSCR 構造体
binfo.0 = bmscr.13 ; オーナーウィンドウハンドル
binfo.1 = 0 ; デスクトップフォルダをルートに
sdim buf, 260
getptr binfo.2, buf
sztitle = "フォルダを選択してください。"
getptr binfo.3, sztitle ; 表示文字列
binfo.4 = 0x4008 ; BIF_RETURNFSANCESTORS | BIF_BROWSEINCLUDEFILES
binfo.5 = 0, 0, 0
; SHBrowseForFolderA 関数呼び出し
getptr pm, binfo
dllproc "SHBrowseForFolderA", pm, 1, D_SHELL
pidl = stat ; 選択アイテムのPIDL
フォルダ選択ダイアログボックスで選択されたアイテムのパス名を表示するサンプルです。
#include "llmod.as"
#include "rrmod/com/lollipop.as"
; IMalloc インターフェース取得
getptr pm, pMalloc
dllproc "SHGetMalloc", pm, 1, D_SHELL
if (stat < 0)|(pMalloc == 0){ ; 戻り値は HRESULT 型(負のときエラー)
dialog "IMalloc インターフェースを取得できませんでした", 1
end
}
; BROWSEINFO 構造体
mref bmscr, 67 ; ウィンドウの BMSCR 構造体
binfo.0 = bmscr.13 ; オーナーウィンドウハンドル
binfo.1 = 0 ; デスクトップフォルダをルートに
sdim buf, 260
getptr binfo.2, buf
sztitle = "フォルダを選択してください。"
getptr binfo.3, sztitle ; 表示文字列
binfo.4 = 0x0003 ; BIF_RETURNONLYFSDIRS| BIF_DONTGOBELOWDOMAIN
binfo.5 = 0, 0, 0
; フォルダ選択ダイアログボックス表示
; SHBrowseForFolderA 関数呼び出し
getptr pm, binfo
dllproc "SHBrowseForFolderA", pm, 1, D_SHELL
pidl = stat ; 選択アイテムのPIDL
if (pidl == 0) {
dialog "キャンセルされました"
goto *lb_free
}
; PIDLからパス名取得
sdim pathname, 260 ; パス名を格納する変数
pm.0 = pidl ; PIDL
getptr pm.1, pathname
dllproc "SHGetPathFromIDListA", pm, 2, D_SHELL
if stat == 0 { ; 戻り値は BOOL 型(0 のときエラー)
dialog "PIDL からパス名を取得できませんでした", 1
goto *lb_free
}
dialog "パス名は[" + pathname + "]です"
*lb_free
if pMalloc {
; IMalloc->Free(pidl);
pm = pidl ; PIDL
icall pMalloc, 5, pm, 1
; インターフェース解放
release pMalloc
}
end