Visual Studio 2003 + COM(Shell)です。
エクスプローラーのようなリストコントロールを作りたいと思っています。
リストコントロールは常に詳細表示で、ヘッダーは名前、サイズ、更新日時の3つに固定
したいと思っています。
IShellFolder.GetDetailsOf()に0、1、3を渡して情報を取得しようと思っていますが、
通常のフォルダー以外がリストコントロールに表示されていた場合は、違う情報が取得
されてしまいます。
例)
ごみ箱:名前、元の場所、サイズ
C:\WINDOWS\Fonts:フォント名、ファイル名、更新日時
C:\Documents and Settings\{USER}\Local Settings\History:期間
通常のフォルダーとそれ以外のフォルダーを判別する方法はありますでしょうか?
よろしくお願いします。
> 通常のフォルダーとそれ以外のフォルダーを判別する方法はありますでしょうか?
難しいと思います。
それより、GetDetailsEx を使ったほうがいいかもしれません。
IShellFolder::GetAttributesOf で取得した属性に
SFGAO_FILESYSTEM が含まれていればシステムファイル or フォルダーで、
このうちさらに SFGAO_FOLDER を含むものがシステムフォルダーとして
取得できたように思います。
MSDN には SFGAO_FILESYSTEM はファイルシステムの一部という説明くらいしか
ないので、このフラグが厳密にシステムファイル or フォルダーだけを
指すかどうかまでは検証してませんが、通常のフォルダーとそれ以外という
判断にはなりそうです。
> subaru さん
たとえば、C:\Windows\Fonts は物理的なディレクトリとしても存在しているので、そこ
から「特殊フォルダではなく、物理的なディレクトリとしての側面を表す
IShellFolder を取得」みたいなことができないと難しいだろうな、と思います。
# ちなみに、俺は
# ディレクトリ=ファイルのコンテナとしてファイルシステム上に存在するもの
# フォルダ=IShellFolder を実装する仮想的なシェルオブジェクトのコンテナ
# として意図的に区別しています(ファイルはディレクトリを包含する)。
まちがい。
> (ファイルはディレクトリを包含する)。
正しくは「フォルダはディレクトリを包含する」です。
>たとえば、C:\Windows\Fonts は物理的なディレクトリとしても存在しているので、そこ
>から「特殊フォルダではなく、物理的なディレクトリとしての側面を表す
>IShellFolder を取得」みたいなことができないと難しいだろうな、と思います。
なるほど。そこまで深読みしてませんでした。
確かに SHGetSpecialFolderLocation に CSIDL_FONTS を指定して取得した
PIDL から BindToObject した場合と、
C:\Windows\Fonts というパスから作成した PIDL から BindToObject した場合で、
列挙されたファイルへの GetDetailsOf の結果が異なってきますね。
そもそも私の回答は、列挙されたフォルダーの内容の判断で
バインドする PIDL の方ではなかったので質問の意図を取違えていたようです。
aetosさん、.....さん、subaruさん、レスありがとうございます。
返信が遅くなり、申し訳ございませんでした。
やはり難しそうですね。
GetAttributesOf()でいろいろなフォルダーの
SFGAO_系を取得してみたのですが、判別は不可能でした。。。
GetDetailsOf()で、デスクトップフォルダーのヘッダー数をあらかじめ取得しておき、
そのヘッダー数と同じかどうかで判別しようかなぁと思ったり思わなかったりです。
ただ、処理が多少重くなりそうなので、迷っています。
IShellFolder2::MapColumnToSCID でヘッダーの並び順を調べるって
手もありそうですが。。。
目的にもよりますが、aetos さんが提案されている GetDetailsEx を使えば
ヘッダーの並び順に関わらず全ての項目を同じように表示することができます。
(表示できない項目は GetDetailsEx がエラーを返すだけです)