・シェル名前空間(Shell's Namespace) シェル名前空間は、フォルダとファイルオブジェクトの集合である。フォルダは、複数の サブフォルダやファイルオブジェクトを含むコンテナオブジェクトである。シェル名前空 間上のフォルダの例としては、ディレクトリやコントロールパネルが挙げられる。ファイ ルオブジェクトの例としては、ファイルや、「ユーザ補助」「日付と時刻」などのコント ロールパネル中に含まれるオブジェクトが挙げられる。これらのシェル名前空間上のフォ ルダやファイルオブジェクトは、エクスプローラで閲覧・操作を行うことができる。 ・シェル名前空間のメモリ管理 シェル名前空間が使用するメモリは、一般的にはシェルアロケータ(Shell's Allocator) と呼ばれるIMallocインターフェースで確保・開放が行われる。シェルアロケータを取得 するには、SHGetMallocを使用する。 ----------------------------------------------------------------------------- ○SHGetMalloc シェルのアロケータを取得 宣言: HRESULT SHGetMalloc(LPMALLOC *Malloc); 説明: シェルのIMallocインターフェースを取得する。 引数の意味は以下の通り。 Malloc (OUT) 取得結果のIMallocインターフェース。 Cのサンプル: sample_sn04_c.txt ----------------------------------------------------------------------------- ・アイテム識別子(Item Identifier)とアイテム識別子リスト(Item Identifier List) シェル名前空間上のオブジェクトには、アイテム識別子およびアイテム識別子リストが関 連付けられている。あるフォルダに含まれるオブジェクトは、そのフォルダ内でユニーク なアイテム識別子をもつ。アイテム識別子はSHITEMID構造体で表される。 アイテム識別子リストは、デスクトップフォルダから特定のオブジェクトにたどり着くま でにたどるオブジェクトのアイテム識別子を列挙したリストである。従って、アイテム識 別子リストは、シェル名前空間全体でユニークとなる。 アイテム識別子リストは、ITEMIDLIST構造体で表される。ITEMIDLIST構造体に含まれるア イテム識別子を列挙するには、構造体に含まれるSHITEMIDの配列を初めから順にたどって いき、サイズが0のSHITEMIDがあった時点で列挙を終了するようにする。 アイテム識別子リストのポインタは、PIDLと呼ばれる。あるPIDLがファイルシステム上の オブジェクトを示すものであるならば、SHGetPathFromIDListを使用することにより、PID Lをパス名に変換することができる。 ----------------------------------------------------------------------------- ○SHGetPathFromIDList PIDLをパス名に変換 Cの宣言: WINSHELLAPI BOOL WINAPI SHGetPathFromIDList( LPCITEMIDLIST pidl, LPSTR Path); 説明: pidlで与えられたPIDLをパスに変換し、結果をPathに返す。 引数の意味は以下の通り。 pidl (IN) 変換元のPIDL LPSTR Path (OUT) 変換結果のパス。少なくともMAX_PATH以上のサイズを用意しなければ ならない。 Cのサンプル: sample_sn04_c.txt ----------------------------------------------------------------------------- あるフォルダに含まれる二つのPIDLが等しいかどうかを判定するには、後述のISHellFold erインターフェースのメンバ関数であるIShellFolder::CompareIDsを使用する。 ----------------------------------------------------------------------------- ○IShellFolder::CompareIDs PIDLの比較 0 Cの宣言: HRESULT CompareIDs( LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2); 説明: pidl1とpidl2を比較し結果を返す。 引数の意味は以下の通り。 lParam 0でなければならない。 pidl1 比較元のPIDL pidl2 比較先のPIDL 比較結果はHRESULT中のSCODEが負、0、正のいずれかで返す。 ----------------------------------------------------------------------------- ・フォルダ フォルダは、IShellFolderを実装するCOMオブジェクトである。 あるフォルダのIShellFolderインターフェースを得ているとき、そのフォルダに含まれる オブジェクトの一覧を、IShellFolder::EnumObjectsで列挙することができる。ISHellFol der::EnumObjectsを実行すると、列挙用COMオブジェクトが作成され、そのオブジェクト に対するIEnumIDListインターフェースと呼ばれる列挙インターフェースが返される。呼 び出し元アプリケーションは、IEnumIDListを使用して、フォルダに含まれるオブジェク トを列挙することができる。 ----------------------------------------------------------------------------- ○IShellFolder::EnumObjects フォルダに含まれるオブジェクトの列挙オブジェクトを作 成 Cの宣言: HRESULT EnumObjects( HWND hOwnerWindow, DWORD Flags, LPENUMIDLIST *EnumIDList); 説明: フォルダに含まれるオブジェクトの列挙オブジェクトを作成し、作成したオブジェクトの IEnumIDListインターフェースを返す。 引数の意味は以下の通り。 hOwnerWindow (IN) メッセージボックスなどの表示の際に使用される親ウィンドウ。 Flags (IN) どのようなオブジェクトを列挙するかを指定するフラグ。後述の表を参照。 EnumIDList (OUT) 作成した列挙オブジェクトのIEnumIDListインターフェース。 Flagsに指定可能なフラグはSHCONTF列挙型である以下の値の組み合わせである。 SHCONTF_FOLDERS フォルダを列挙する SHCONTF_NONFOLDERS ファイルオブジェクトを列挙する SHCONTF_INCLUDEHIDDEN 隠しオブジェクトとシステムオブジェクトを列挙する Cのサンプル: sample_sn03_c.txt ----------------------------------------------------------------------------- また、サブフォルダのIShellFolderインターフェースを取得するには、IShellFolder::Bi ndToObjectを使用する。 ----------------------------------------------------------------------------- ○IShellFolder::BindToObject サブフォルダのIShellFolderを取得 Cの宣言: HRESULT BindToObject( LPCITEMIDLIST pidl, LPBC Reserved, REFIID RefIID, LPVOID *ShellFolder); 説明: pidlで指定したサブフォルダのIShellFolderインターフェースを取得し、結果をShellFod erに返す。 引数の意味は以下の通り。 pidl (IN) 取得するサブフォルダのPIDL Reserved (IN) NULLでなければならない。 RefIID (IN) IID_ShellFolderでなければならない。 ShellFolder (OUT) 取得結果のIShellFolderインターフェース。 Cのサンプル: sample_sn03_c.txt ----------------------------------------------------------------------------- ユーザにシェル名前空間上のフォルダを選択させるには、SHBrowseForFolderを使用する 。SHBlowseForFolderは、選択されたフォルダのPIDLを返す。 ----------------------------------------------------------------------------- ○SHBrowseForFolder フォルダ選択ダイアログボックスの表示 Cの宣言: WINSHELLAPI LPITEMIDLIST WINAPI SHBrowseForFolder(LPBROWSEINFO BrowseInfo); 説明: BrowseInfoで指定した情報を元に、フォルダ選択ダイアログボックスを表示する。 引数の意味は以下の通り。 BrowseInfo (IN/OUT) 表示するダイアログボックスの初期状態を指定する情報。 戻り値は、選択されたフォルダのPIDLである。選択されなかった場合、NULLが返される。 コールバック関数を利用したCのサンプル: sample_sn01_c.txt コールバック関数を使用しないCのサンプル: sample_sn04_c.txt ----------------------------------------------------------------------------- あるフォルダのIShellFolderインターフェースのメンバ関数にPIDLや表示名などを渡す場 面がある場合、このPIDLや表示名はそのフォルダに含まれるオブジェクトを示していなけ ればならないことに注意。 ・デスクトップフォルダ フォルダは、サブフォルダを含むコンテナなので、木構造をなす。木構造のルートフォル ダは、常にデスクトップフォルダと呼ばれる特別なフォルダである。 デスクトップフォルダのIShellFolderインターフェースを取得するには、SHGetDesktopFo lderを使用する。 ----------------------------------------------------------------------------- ○SHGetDesktopFolder デスクトップフォルダの取得 Cの宣言: WINSHELLAPI HRESULT WINAPI SHGetDesktopFolder(LPSHELLFOLDER *ShellFolder); デスクトップフォルダのIShellFolderインターフェースを取得する。 引数の意味は以下の通り。 ShellFolder (OUT) 取得結果のIShellFolderインターフェースへのポインタを格納するバ ッファ。 Cのサンプル: sample_sn02_c.txt ----------------------------------------------------------------------------- ・仮想フォルダ デスクトップ、マイコンピュータ、ネットワークコンピュータなどの、実際のオブジェク トが存在しないフォルダを仮想フォルダと呼ぶ。 ・特別なフォルダ シェル名前空間上には、いくつかの特別なフォルダが存在する。これらの特別なフォルダ のPIDLを、SHGetSpecialFolderLocationで取得することができる。 ----------------------------------------------------------------------------- ○SHGetSpecialFolderLocation 特別なフォルダのPIDLを取得 Cの宣言: WINSHELLAPI HRESULT WINAPI SHGetSpecialFolderLocation( HWND hOwnerWindow, int FolderType, LPITEMIDLIST *pidl); 説明: デスクトップやマイコンピュータなどの特別なフォルダのPIDLを取得する。 引数の意味は以下の通り。 hOwnerWindow メッセージボックスなどを表示する際の親ウィンドウのハンドル。 FolderType 取得するフォルダのタイプ。後述の表を参照。 pidl 取得結果のPIDL。 FolderTypeに指定可能なフラグは以下のいずれかの値である。 CSIDL_BITBUCKET ごみ箱 CSIDL_CONTROLS コントロールパネル CSIDL_DESKTOP デスクトップ CSIDL_DESKTOPDIRECTORY デスクトップ上に含まれているオブジェクトの実際の格納場所 であるディレクトリ CSIDL_DRIVES マイコンピュータ CSIDL_FONTS フォント CSIDL_NETHOOD CSIDL_NETWORK CSIDL_PERSONAL ユーザごとの情報が格納されるディレクトリ CSIDL_PRINTERS プリンタ CSIDL_PROGRAMS プログラム CSIDL_RECENT 最近使ったファイル CSIDL_SENDTO 「送る」メニューのアイテムが格納されているディレクトリ。 CSIDL_STARTMENU スタートメニュー CSIDL_STARTUP スタートアップ CSIDL_TEMPLATES ドキュメントテンプレート Cのサンプル: sample_sn01_c.txt ----------------------------------------------------------------------------- ・表示名(Display Name) シェル名前空間上のオブジェクトは、表示名と呼ばれる文字列を持つ。オブジェクトがが ファイルシステム上のディレクトリやファイルのときは、表示名はそのディレクトリのパ ス名に一致する。あるフォルダに含まれるオブジェクトの表示名を取得するには、IShell Folder::GetDisplayNameOfを使用し、表示名を設定するにはIShellFolder::SetNameOfを 使用する。SetNameOfを実行すると、そのオブジェクトに対するアイテム識別子も変更さ れる。ファイルシステム上のディレクトリやファイルに対してSetNameOfを実行すると、 ディレクトリやファイルのリネームが行われる。 ----------------------------------------------------------------------------- ○IShellFolder::GetDisplayNameOf 表示名の取得 Cの宣言: HRESULT GetDisplayNameOf( LPCITEMIDLIST pidl, DWORD Flags, LPSTRRET DisplayName); 説明: pidlで指定されるオブジェクトの表示名を取得する。 引数の意味は以下の通り。 pidl 表示名の取得元のオブジェクトのPIDL Flags 取得する表示名の形式。後述の表を参照。 DisplayName 取得結果の表示名。 Flagsに指定可能な値は以下のようなSHGNO列挙型の値である。 SHGDN_NORMAL SHGDN_INFOLDER SHGDN_FORPARSING Cのサンプル: sample_sn03_c.txt ○IShellFolder::SetNameOf 表示名の設定 Cの宣言: HRESULT SetNameOf( HWND hOwnerWindow, LPCITEMIDLIST pidl, LPCOLESTR DisplayName, DWORD Flags, LPITEMIDLIST *NewPidl); 説明: pidlで指定したオブジェクトの新しい表示名を設定する。 引数の意味は以下の通り。 hOwnerWindow メッセージボックスなどの表示の際に使用される親ウィンドウのハンドル 。 pidl 設定するオブジェクトのPIDL DisplayName 設定する表示名 Flags 表示名のタイプを指定するSHCONTF列挙型の値。詳細はEnumObjectsを参照。 NewPidl 新規表示名を設定後のオブジェクトの新しいPIDL。 ----------------------------------------------------------------------------- あるフォルダに含まれるオブジェクトの表示名を元にPIDLを取得するには、IShellFolder ::ParseDisplayNameを使用する。 ----------------------------------------------------------------------------- ○IShellFolder::ParseDisplayName 表示名をアイテム識別子に変換 Cの宣言: HRESULT ParseDisplayName( HWND hOwnerWindow, LPBC Reserved, LPOLESTR DisplayName, ULONG *ParseNum, LPITEMIDLIST *pidl, ULONG *Attribute); 説明: オブジェクトの表示名を元に、アイテム識別子を取得する。 オブジェクトは、IShellFolderインターフェースの取得元のフォルダに含まれていなけれ ばならない。 引数の意味は以下の通り。 hOnwerWindow (IN) ダイアログボックスを表示する際の親ウィンドウのハンドル Reserved (IN) NULLでなければならない。 DisplayName (IN) 変換元の表示名。SHGDN_FORPARSINGの形式でなければならない。 ParseNum (OUT) 変換した表示名の文字数。 pidl (OUT) 変換結果のPIDL Attribute (OUT) 表示名が示すファイルオブジェクトの属性。NULLを指定可能。 Cのサンプル: sample_sn02_c.txt ----------------------------------------------------------------------------- ・オブジェクトの属性(Attribute) シェル名前空間上のオブジェクトは、属性を持つ。あるフォルダに含まれるオブジェクト の属性を取得するには、IShellFolder::GetAttributesOfを使用する。 ----------------------------------------------------------------------------- ○IShellFolder::GetAttributesOf 属性の取得 Cの宣言: HRESULT GetAttributesOf( UINT cidl, LPCITEMIDLIST *pidls, ULONG *Attribute); サブオブジェクトの属性を取得する。 関数を呼ぶ際には、Attributeに、取得したい属性のビットマスクを指定する。関数の実 行後、Attributeに、有効な属性がビットマスクの形で返される。 引数の意味は以下の通り。 cidl (IN) pidlsの要素の数。 pidls (IN) 取得元のオブジェクトのPIDLの配列。 Attribute (IN/OUT) 取得したい属性を指定するビットマスク。関数の実行後、取得した 属性が返される。指定可能な値についてはサンプルを参照。 Cのサンプル: sample_sn02_c.txt ----------------------------------------------------------------------------- ・オブジェクトのインターフェースの取得 シェル名前空間上のオブジェクトのIShellFolderインターフェースを取得しているとき、 そのフォルダに含まれるオブジェクトの、他のインターフェースを、IShellFolder::GetU IObjectOfで取得することができる。 ----------------------------------------------------------------------------- ○IShellFolder::GetUIObjectOf 他のインターフェースの取得 Cの宣言: HRESULT GetUIObjectOf( HWND hOwnerWindow, UINT cidl, LPCITEMIDLIST *pidls, REFIID riid, UINT *prgfInOut, LPVOID *Result); 説明: pidlsで指定したPIDLの配列から、各々のPIDLに対応するオブジェクトのriidで指定され るインターフェースを取得し、結果をResultに返す。 引数の意味は以下の通り。 hOwnerWindow メッセージボックスなどの表示の際に使用される親ウィンドウ。 cidl pidlsの数 pidls 取得元のオブジェクトのPIDLの配列。 riid 取得するインターフェース。後述の表を参照。 prgfInOut NULLでなければならない。 Result 取得結果のインターフェースのポインタが格納されるバッファ。 riidには以下のIIDが指定可能。 IID_IExtractIcon IID_IContextMenu IID_IDataObject IID_IDropTarget Cのサンプル: sample_sn07_c.txt ----------------------------------------------------------------------------- ・ビュー ビューオブジェクトを作成するには、IShellFolder::CreateViewObjectを使用する。Crea teViewObjectは、ビューオブジェクトを作成し、作成したビューオブジェクトのIShellVi ewインターフェースを返す。 ・その他の機能 「最近使ったファイル」にオブジェクトを追加するには、SHAddToRecentDocsを使用する 。 アプリケーションが行ったシェル名前空間上の操作をシステムに通知する場合、SHChange Notifyを使用する。 ファイルの複製や削除などを行うには、SHFileOperationを使用する。 SHFileOperationで取得したファイル名マッピングオブジェクトを開放するには、SHFreeN ameMappingを使用する。 ファイルシステム上のオブジェクトの情報を取得するには、SHGetFileInfoを使用する。 エクスプローラのIUnknwonインターフェースを取得するには、SHGetInstanceExplorerを 使用する。 ----------------------------------------------------------------------------- ○SHAddToRecentDocs 「最近使ったファイル」にオブジェクトを追加 Cの宣言: WINSHELLAPI void WINAPI SHAddToRecentDocs( UINT Flags, LPCVOID ObjectToBeAdded); 説明: ObjectToBeAddedで指定したオブジェクトを、「最近使ったファイル」に追加する。Objec tToBeAddedがNULLの場合、「最近使ったファイル」を初期化する。 引数の意味は以下の通り。 Flags ObjectToBeAddedの解釈の仕方を表すフラグ。後述の表を参照。 ObjectToBeAdded 追加するオブジェクトのパス名またはPIDL。 Flagsには以下のフラグのいずれかを指定する。 SHARD_PATH ObjectToBeAddedはパス名。 SHARD_PIDL ObjectToBeAddedはPIDL。 「最近使ったファイル」を初期化するCのサンプル: sample_sn05_c.txt 「最近使ったファイル」に追加するCのサンプル: sample_sn06_c.txt ○SHChangeNotify イベントのシステムへの通知 Cの宣言: WINSHELLAPI void WINAPI SHChangeNotify( LONG EventId, UINT Flags, LPCVOID Item1, LPCVOID Item2); 説明: アプリケーションがシェルに影響のある操作を行ったとき、行った操作をシステムに通知 する。 引数の意味は以下の通り。 EventId 行った操作を示すフラグ。後述の表を参照。 Flags Item1及びItem2をどのように解釈するかを指定するフラグ。後述の表を参照。 Item1 Item2 ○SHFileOperation ファイルの操作 Cの宣言: WINSHELLAPI int WINAPI SHFileOperation(LPSHFILEOPSTRUCT FileOp); 説明: FileOpで指定された、ファイルに対する操作を行う。 引数の意味は以下の通り。 FileOp (IN/OUT) 行う操作。 ○SHFreeNameMappings ファイル名マッピングオブジェクトの開放 Cの宣言: WINSHELLAPI void WINAPI SHFreeNameMappings(HANDLE hNameMapping); 説明: SHFileOperationで取得したファイル名マッピングオブジェクトを開放する。 引数の意味は以下の通り。 hNameMapping 開放するファイル名マッピングオブジェクトのハンドル。 ○SHGetFileInfo ファイルシステム上のオブジェクトの情報を取得 Cの宣言: WINSHELLAPI DWORD WINAPI SHGetFileInfo( LPCTSTR SrcObject, DWORD Attribute, SHFILEINFO FAR *FileInfo, UINT FileInfoSize, UINT Flags); 説明: SrcObjectで指定したディレクトリやファイルの情報を取得する。 引数の意味は以下の通り。 SrcObject (IN) 情報の取得元のオブジェクトのパス名またはPIDL。 Attribute (IN) FlagsにSHGFI_USEFILEATTRIBUTESを指定した場合のファイルの属性。 FileInfo (OUT) 取得結果の情報。 FileInfoSize (IN) FileInfoのサイズ。 Flags (IN) どのような情報を取得するかを指定するフラグ。後述の表を参照。 Flagsに指定可能なフラグは、以下の値の組み合わせである。 SHGFI_ATTRIBUTES ファイルの属性を取得する。 SHGFI_DISPLAYNAME ファイルの表示名を取得する。 SHGFI_EXETYPE 実行可能ファイルのタイプを取得する。 SHGFI_ICON アイコンを取得する。 SHGFI_ICONLOCATION アイコンが含まれるファイル名を取得する。 SHGFI_LARGEICON 大きいアイコンを取得する。 SHGFI_LINKOVERLAY 取得したアイコンにリンクを示す絵を加える。 SHGFI_OPENICON オブジェクトが開いた状態の時のアイコンを取得する SHGFI_PIDL SrcObjectがPIDLであることを示す。 SHGFI_SELECTED 選択された状態のアイコンを取得する。 SHGFI_SHELLICONSIZE シェルが決めるサイズに基づくアイコンを取得する。 SHGFI_SMALLICON 小さいアイコンを取得する。 SHGFI_SYSICONINDEX アイコンのシステムのイメージリスト中でのインデックスを取得す る。 SHGFI_TYPENAME ファイルタイプを表す文字列を取得する。 SHGFI_USEFILEATTRIBUTES Attributeを有効にする。 ○SHGetInstanceExplorer エクスプローラのIUnknownインターフェースを取得 Cの宣言: WINSHELLAPI HRESULT WINAPI SHGetInstanceExplorer(IUnknown *Unkown); 説明: エクスプローラのIUnknownインターフェースを取得する。 引数の意味は以下の通り。 Unknown (OUT) 取得結果のIUnknownインターフェースへのポインタを格納するバッファ。 ----------------------------------------------------------------------------- sample_sn01_c.txt ○コールバックルーチンを使用したフォルダ選択ダイアログボックスの表示(C言語) 説明: 「マイコンピュータ」下のフォルダを選択するダイアログボックスを表示する。ダイアロ グボックスが初めに表示された際には、Windowsディレクトリが選択されている。ユーザ がダイアログボックス上に表示されているフォルダを選択するたびに、ステータスバーに 、選択したフォルダの表示名を表示する。また、同時に、もし選択したフォルダがコント ロールパネルならば、OKボタンを無効化する。 キーワード: SHBrowseForFolder サンプルコード: /* フォルダ選択ダイアログボックスに渡すデータ */ typedef struct { LPMALLOC Malloc; /* アロケータのインターフェース */ LPSHELLFOLDER DesktopFolder; /* デスクトップフォルダのIShellFolderインターフェ ース */ } DLGDATA; /* フォルダ選択ダイアログボックス表示用コールバック関数 */ int CALLBACK DialogCallback( HWND hWnd, /* ダイアログボックスのハンドル */ UINT uMsg, /* 呼ばれた理由 */ LPARAM lParam, /* 選択されたフォルダのPIDL*/ LPARAM lpData /* BWOSEINFOのlParamに渡したコールバックへの引数 */) { LPITEMIDLIST pidl; LPITEMIDLIST pidlWindows; LPITEMIDLIST pidlControlPanel; STRRET StrRet; DLGDATA *DlgData; char buf[1000]; DlgData = (DLGDATA *)lpData; switch(uMsg) { /* 呼ばれた理由の判定 */ case BFFM_INITIALIZED: /* ダイアログボックスの初期化が終わった */ /* 表示名からPIDLを取得 */ DlgData->DesktopFolder->ParseDisplayName( NULL, NULL, OLESTR("d:\\winnt"), NULL, &pidlWindows, NULL); SendMessage(hWnd, BFFM_SETSELECTION, (WPARAM)FALSE, (LPARAM)pidlWindows); /* pidlの開放 */ DlgData->Malloc->Free(pidlWindows); // 上述の処理のように、PIDLを取得せずとも、以下の一行のようにパス名を渡すのみ でも同様の動作が可能 // SendMessage(hWnd, BFFM_SETSELECTION, (WPARAM)TRUE, (LPARAM)"a:\\windows"); break; case BFFM_SELCHANGED: /* フォルダが選択された */ /* PIDLから表示名を取得 */ pidl = (LPITEMIDLIST)lParam; DlgData->DesktopFolder->GetDisplayNameOf( pidl, SHGDN_FORPARSING, &StrRet); /* ステータスバーに選択したフォルダの表示名を表示 */ switch(StrRet.uType) { case STRRET_CSTR: SendMessage(hWnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)StrRet.cStr); break; case STRRET_OFFSET: SendMessage(hWnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)(((BYTE *)pidl)+StrRet.uOffs et)); break; case STRRET_WSTR: WideCharToMultiByte(CP_ACP, 0, StrRet.pOleStr, -1, buf, 1000, NULL, NULL); SendMessage(hWnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)buf); break; default: printf("error\n"); } /* 表示名の開放 */ if(StrRet.uType == STRRET_WSTR) DlgData->Malloc->Free(StrRet.pOleStr); /* 選択されたフォルダがコントロールパネルならば、OKボタンを無効化 */ SHGetSpecialFolderLocation(NULL, CSIDL_CONTROLS, &pidlControlPanel); if(DlgData->DesktopFolder->CompareIDs(0, pidl, pidlControlPanel) == 0) { SendMessage(hWnd, BFFM_ENABLEOK, (WPARAM)0, 0); } else { SendMessage(hWnd, BFFM_ENABLEOK, (WPARAM)0, 1); } DlgData->Malloc->Free(pidlControlPanel); break; } return 0; } /* フォルダ選択ダイアログボックスの表示 * 表示されるファイル選択ダイアログボックスは、最初はWindowsディレクトリが選択さ れている * フォルダを選択するたびに、ステータスバーに選択したフォルダの表示名を表示する * サブフォルダを持つフォルダを選択した場合、OKボタンが無効化される */ void DispFolderSelectDialog() { BROWSEINFO bi; LPITEMIDLIST pidl; LPITEMIDLIST RootPidl; char DisplayName[MAX_PATH]; DLGDATA DlgData; LPMALLOC Malloc; CoInitialize(NULL); /* シェルのタスクアロケータの取得 */ SHGetMalloc(&Malloc); /* 「マイコンピュータ」フォルダのPIDLを取得 */ SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &RootPidl); /* コールバック関数に渡す情報を設定 */ DlgData.Malloc = Malloc; SHGetDesktopFolder(&DlgData.DesktopFolder); /* フォルダ選択ダイアログボックスの初期状態を設定 */ bi.hwndOwner = NULL; /* オーナーウィンドウは無し */ bi.pidlRoot = RootPidl; /* 「マイコンピュータ」配下を選択可 */ bi.pszDisplayName = DisplayName; /* 表示名を受け取るバッファはDisplayName */ bi.lpszTitle = "Choose Folder"; /* ダイアログボックスのタイトル */ bi.ulFlags = BIF_STATUSTEXT; /* 全てのフォルダを選択可能・ステータスを表示 */ bi.lpfn = DialogCallback; bi.lParam = (LPARAM)&DlgData; /* フォルダ選択ダイアログボックスの表示 */ pidl = SHBrowseForFolder(&bi); /* DlgDataの開放 */ DlgData.DesktopFolder->Release(); if(pidl == NULL) { printf("no folder selected.\n"); goto Exit; } printf("選択されたフォルダの表示名:%s\n", DisplayName); printf("選択されたフォルダのイメージのインデックス: %d\n", bi.iImage); Exit: if(pidl != NULL) Malloc->Free(pidl); Malloc->Free(RootPidl); Malloc->Release(); CoUninitialize(); } sample_sn02_c.txt /* c:\tempの属性を表示 */ void DispAttribute() { LPSHELLFOLDER DesktopFolder; LPMALLOC Malloc; LPITEMIDLIST pidl = NULL; LPCITEMIDLIST pidls[1]; ULONG Attribute; CoInitialize(NULL); /* シェルのタスクアロケータの取得 */ SHGetMalloc(&Malloc); /* デスクトップフォルダの取得 */ SHGetDesktopFolder(&DesktopFolder); /* 表示名からPIDLを取得 */ DesktopFolder->ParseDisplayName( NULL, NULL, OLESTR("a:\\temp"), NULL, &pidl, NULL); Attribute = SFGAO_CAPABILITYMASK | SFGAO_DISPLAYATTRMASK | SFGAO_CONTENTSMASK | SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_REMOVABLE | SF GAO_VALIDATE; /* 属性の取得 */ pidls[0] = pidl; DesktopFolder->GetAttributesOf(1, pidls, &Attribute); /* 取得した属性の表示 */ if(Attribute & SFGAO_CANCOPY) printf("複製可能.\n"); if(Attribute & SFGAO_CANMOVE) printf("移動可能.\n"); if(Attribute & SFGAO_CANLINK) printf("ショートカットを作成可能.\n"); if(Attribute & SFGAO_CANRENAME) printf("リネーム可能.\n"); if(Attribute & SFGAO_CANDELETE) printf("削除可能.\n"); if(Attribute & SFGAO_HASPROPSHEET) printf("プロパティシートを持つ.\n"); if(Attribute & SFGAO_DROPTARGET) printf("ドロップターゲット.\n"); if(Attribute & SFGAO_LINK) printf("オブジェクトはショートカット.\n"); if(Attribute & SFGAO_SHARE) printf("共有フォルダ.\n"); if(Attribute & SFGAO_READONLY) printf("読み込み専用.\n"); if(Attribute & SFGAO_GHOSTED) printf("ゴーストアイコンを使用\n"); if(Attribute & SFGAO_FILESYSANCESTOR) printf("ファイルシステムのフォルダを持つ. \n"); if(Attribute & SFGAO_FOLDER) printf("オブジェクトはフォルダ.\n"); if(Attribute & SFGAO_FILESYSTEM) printf("オブジェクトはファイルシステムのオブジ ェクト.\n"); if(Attribute & SFGAO_HASSUBFOLDER) printf("サブフォルダを持つ.\n"); if(Attribute & SFGAO_VALIDATE) printf("キャッシュされた情報は有効.\n"); if(Attribute & SFGAO_REMOVABLE) printf("リムーバブルなメディア上のオブジェクト. \n"); /* デスクトップフォルダの開放 */ DesktopFolder->Release(); /* PIDLの開放 */ if(pidl != NULL) Malloc->Free(pidl); /* アロケータの開放 */ Malloc->Release(); CoUninitialize(); } sample_sn03_c.txt /* a:\windowsに含まれるサブフォルダを列挙する */ void EnumSubObject() { LPSHELLFOLDER DesktopFolder; LPSHELLFOLDER WindowsFolder; LPENUMIDLIST EnumIDList; LPMALLOC Malloc; LPITEMIDLIST pidlRoot; /* 列挙するフォルダのPIDL */ LPITEMIDLIST pidlSubFolder; /* 列挙されているサブフォルダのPIDL */ STRRET SubFolderName; /* サブフォルダの名前 */ CoInitialize(NULL); /* アロケータの取得 */ SHGetMalloc(&Malloc); /* デスクトップフォルダの取得 */ SHGetDesktopFolder(&DesktopFolder); /* a:\windowsのPIDLを取得 */ DesktopFolder->ParseDisplayName( NULL, NULL, OLESTR("a:\\windows"), NULL, &pidlRoot, NULL); /* a:\windowsのIShellFolderインターフェースを取得 */ DesktopFolder->BindToObject( pidlRoot, NULL, IID_IShellFolder, (LPVOID *)&WindowsFolder); /* 列挙オブジェクトを作成 */ WindowsFolder->EnumObjects(NULL, SHCONTF_FOLDERS, &EnumIDList); /* 列挙の繰り返し */ EnumIDList->Reset(); while(EnumIDList->Next(1, &pidlSubFolder, NULL)==NOERROR) { /* 表示名の取得 */ WindowsFolder->GetDisplayNameOf(pidlSubFolder, SHGDN_NORMAL, &SubFolderName); /* サブフォルダの表示名の表示 */ switch(SubFolderName.uType) { case STRRET_CSTR: printf("%s (CSTR)\n", SubFolderName.cStr); break; case STRRET_OFFSET: printf("%s (OFFSET)\n", ((BYTE *)pidlSubFolder)+SubFolderName.uOffset); break; case STRRET_WSTR: printf("... (WSTR)\n"); break; } /* 表示名の開放 */ if(SubFolderName.uType == STRRET_WSTR) Malloc->Free(SubFolderName.pOleStr); /* サブフォルダのPIDLの開放 */ Malloc->Free(pidlSubFolder); } /* WindowsフォルダのPIDLの開放 */ Malloc->Free(pidlRoot); /* インターフェースの開放 */ EnumIDList->Release(); WindowsFolder->Release(); DesktopFolder->Release(); Malloc->Release(); CoUninitialize(); } sample_sn04_c.txt void SelectPath() { BROWSEINFO bi; LPITEMIDLIST pidl; LPMALLOC Malloc; char Path[MAX_PATH]; CoInitialize(NULL); ZeroMemory(&bi, sizeof(BROWSEINFO)); /* シェルのタスクアロケータの取得 */ SHGetMalloc(&Malloc); /* フォルダ選択ダイアログボックスの表示 */ pidl = SHBrowseForFolder(&bi); if(pidl == NULL) { printf("no folder selected.\n"); goto Exit; } SHGetPathFromIDList(pidl, Path); printf("選択されたパスは '%s'.\n", Path); Exit: if(pidl != NULL) Malloc->Free(pidl); Malloc->Release(); CoUninitialize(); } sample_sn05_c.txt void ClearRecentDocs() { SHAddToRecentDocs(SHARD_PATH, NULL); } sample_sn06_c.txt void TestRecentDocs() { SHAddToRecentDocs(SHARD_PATH, "a:\\doc\\abc.txt"); } sample_sn07_c.txt void TestUIObject() { LPSHELLFOLDER DesktopFolder; LPMALLOC Malloc; LPDATAOBJECT DataObject; LPITEMIDLIST pidl; LPCITEMIDLIST pidls[1]; LPENUMFORMATETC EnumFormatEtc; FORMATETC FormatEtc; char FormatName[1000]; OleInitialize(NULL); /* シェルのタスクアロケータの取得 */ SHGetMalloc(&Malloc); /* デスクトップフォルダの取得 */ SHGetDesktopFolder(&DesktopFolder); /* 表示名からPIDLを取得 */ DesktopFolder->ParseDisplayName( NULL, NULL, OLESTR("a:\\my documents\\abc.txt"), NULL, &pidl, NULL); /* IDataObjectインターフェースを取得 */ pidls[0] = pidl; DesktopFolder->GetUIObjectOf( NULL, 1, pidls, IID_IDataObject, NULL, (LPVOID *)&DataObject); /* FORMATETCの列挙オブジェクトを作成 */ DataObject->EnumFormatEtc(DATADIR_GET, &EnumFormatEtc); /* 列挙開始 */ EnumFormatEtc->Reset(); while(EnumFormatEtc->Next(1, &FormatEtc, NULL) == NOERROR) { /* フォーマット名の表示 */ GetClipboardFormatName(FormatEtc.cfFormat, FormatName, 1000); printf("'%s'\n", FormatName); /* FORMATETCの開放 */ } /* 後処理 */ EnumFormatEtc->Release(); DataObject->Release(); DesktopFolder->Release(); Malloc->Free(pidl); Malloc->Release(); OleUninitialize(); }