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