一般的なエクスプローラーの概念
Shell 名前空間 は、シェルによって管理されるファイル システムおよびその他のオブジェクトを 1 つのツリー構造階層に編成します。 概念的には、ファイル システムのより大規模で包括的なバージョンです。
はじめに
シェルの主な責任の 1 つは、システムを構成するさまざまなオブジェクトの管理とアクセスの提供です。 これらのオブジェクトの中で最も多く使い慣れているのは、コンピューター ディスク ドライブに存在するフォルダーとファイルです。 ただし、シェルは、多数の非ファイル システムまたは 仮想 オブジェクトも管理します。 次に例をいくつか示します。
- ネットワーク プリンター
- その他のネットワークコンピューター
- コントロール パネル アプリケーション
- ごみ箱
一部の仮想オブジェクトには、物理ストレージがまったく含まれていません。 たとえば、プリンター オブジェクトには、ネットワークプリンターへのリンクのコレクションが含まれています。 ごみ箱などの他の仮想オブジェクトには、ディスク ドライブに格納されているデータが含まれている場合がありますが、通常のファイルとは異なる方法で処理する必要があります。 たとえば、仮想オブジェクトを使用して、データベースに格納されているデータを表すことができます。 名前空間に関しては、データベース内のさまざまな項目は、すべて 1 つのディスク ファイルに格納されている場合でも、Windows エクスプローラーで個別のオブジェクトとして表示される可能性があります。
仮想オブジェクトは、リモート コンピューター上に配置することもできます。 たとえば、ローミングを容易にするために、ユーザーのドキュメント ファイルがサーバーに格納される場合があります。 ユーザーが複数のデスクトップ PC からファイルにアクセスできるようにするには、現在使用しているデスクトップ PC の [マイ ドキュメント] フォルダーが、デスクトップ PC のハード ディスクではなくサーバーを指します。 そのパスには、マップされたネットワーク ドライブまたは UNC パス名が含まれます。
ファイル システムと同様に、 名前空間には、フォルダーとファイルという 2 つの基本的な種類のオブジェクトが含まれています。 Folder オブジェクトはツリーの ノード です。これらは、ファイル オブジェクトやその他のフォルダーのコンテナーです。 ファイル オブジェクトはツリーの 葉 です。これらは、通常のディスク ファイルまたはプリンター リンクなどの仮想オブジェクトです。 ファイル システムの一部ではないフォルダーは、 仮想フォルダーと呼ばれることもあります。
ファイル システム フォルダーと同様に、仮想フォルダーのコレクションは通常、システムによって異なります。 仮想フォルダーには、次の 3 つのクラスがあります。
- すべてのシステムで見つかる標準の仮想フォルダー (ごみ箱など)。
- 標準の名前と機能を備えているが、すべてのシステムに存在しない可能性があるオプションの仮想フォルダー。
- ユーザーがインストールする標準以外のフォルダー。
ファイル システム フォルダーとは異なり、ユーザーは新しい仮想フォルダー自体を作成できません。 Microsoft 以外の開発者によって作成されたもののみをインストールできます。 したがって、仮想フォルダーの数は通常、ファイル システム フォルダーの数よりもはるかに少なくなります。 仮想フォルダーを実装する方法については、「 名前空間拡張機能」を参照してください。
Windows エクスプローラーのエクスプローラー バーで、名前空間がどのように構成されているかを視覚的に表現できます。 たとえば、次の Windows エクスプローラーのスクリーン ショットは、比較的単純な名前空間を示しています。
名前空間階層の最終的なルートはデスクトップです。 ルートのすぐ下には、マイ コンピューターやごみ箱などのいくつかの仮想フォルダーがあります。
さまざまなディスク ドライブのファイル システムは、より大きな名前空間階層のサブセットと見なすことができます。 これらのファイル システムのルートは、マイ コンピューター フォルダーのサブフォルダーです。 マイ コンピューターには、マップされたネットワーク ドライブのルートも含まれています。 ツリー内の他のノード (マイ ドキュメントなど) は仮想フォルダーです。
名前空間オブジェクトの識別
名前空間オブジェクトを使用する前に、まずそれを識別する方法が必要です。 ファイル システム内のオブジェクトには、MyFile.htmなどの名前を付ける場合があります。 システム内の他の場所にその名前のファイルが存在する可能性があるため、ファイルまたはフォルダーを一意に識別するには、"C:\MyDocs\MyFile.htm" などの完全修飾パスが必要です。 このパスは、基本的には、ファイル システムルート C:\からのパス内のすべてのフォルダーの順序付きリストであり、ファイルで終わる。
名前空間のコンテキストでは、パスは、名前空間のファイル システム部分にあるオブジェクトを識別するために非常に役立ちます。 ただし、仮想オブジェクトには使用できません。 代わりに、シェルは、任意の名前空間オブジェクトで使用できる別の識別手段を提供します。
アイテム ID
フォルダー内の各オブジェクトには、ファイル名またはフォルダー名と同等の機能を持つ アイテム ID があります。 項目 ID は実際には 、SHITEMID 構造体です。
typedef struct _SHITEMID {
USHORT cb;
BYTE abID[1];
} SHITEMID, * LPSHITEMID;
abID メンバーはオブジェクトの識別子です。 abID の長さは定義されておらず、その値は オブジェクトを含むフォルダーによって決まります。 abID 値がフォルダーによって割り当てられる方法に関する標準の定義がないため、関連付けられたフォルダー オブジェクトに対してのみ意味があります。 アプリケーションでは、特定のフォルダー内のオブジェクトを識別するトークンとして扱う必要があります。 abID の長さは異なるため、cb メンバーは、SHITEMID 構造体のサイズをバイト単位で保持します。
アイテム ID は表示目的では役に立たないため、オブジェクトを含むフォルダーには通常、表示名が割り当てられます。 これは、フォルダーの内容を表示するときに Windows エクスプローラーによって使用される名前です。 表示名の処理方法の詳細については、「 フォルダーから情報を取得する」を参照してください。
アイテム ID リスト
アイテム ID が単独で使用されることはほとんどありません。 通常、これはアイテム ID リストの一部であり、ファイル システム パスと同じ目的を果たします。 ただし、パスに使用される文字列の代わりに、項目 ID リストは ITEMIDLIST 構造体です。 この構造体は、2 バイト の NULL で終わる 1 つ以上の項目 ID の順序付けられたシーケンスです。 項目 ID リストの各項目 ID は、名前空間オブジェクトに対応します。 その順序は、ファイル システム パスと同様に、名前空間内のパスを定義します。
次の図は、C:\MyDocs\MyFile.htmに対応する ITEMIDLIST 構造体の概略図を示しています。 各項目 ID の表示名は、その上に表示されます。 abID メンバーの幅は任意です。彼らは、このメンバーのサイズが異なる可能性があることを示しています。
PIDL
シェル API の場合、名前空間オブジェクトは通常、 ITEMIDLIST 構造体へのポインター、または項目識別子リスト (PIDL) へのポインターによって識別されます。 便宜上、PIDL という用語は、通常、このドキュメントで参照される構造体自体ではなく、そのポインターです。
前の図に示した PIDL は、 完全な PIDL または 絶対 PIDL と呼ばれます。 完全な PIDL はデスクトップから開始され、パス内のすべての中間フォルダーの項目 ID が含まれます。 オブジェクトの項目 ID の後に終端の 2 バイト NULL が続きます。 完全な PIDL は完全修飾パスに似ていて、シェル名前空間内のオブジェクトを一意に識別します。
完全な PIDL は頻繁に使用されません。 多くの関数とメソッドでは、 相対 PIDL が必要です。 相対 PIDL のルートは、デスクトップではなくフォルダーです。 相対パスと同様に、構造体を構成する一連の項目 ID によって、2 つのオブジェクト間の名前空間内のパスが定義されます。 オブジェクトは一意に識別されませんが、通常は完全な PIDL よりも小さく、多くの目的に十分です。
最も一般的に使用される相対 PIDL ( 単一レベルの PIDL) は、オブジェクトの親フォルダーを基準にしています。 オブジェクトの項目 ID と終端の NULL のみが含まれます。 複数レベルの PIDL は、多くの目的にも使用されます。 2 つ以上のアイテム ID が含まれており、通常は、親フォルダーから 1 つ以上のサブフォルダーを介してオブジェクトへのパスを定義します。 単一レベルの PIDL は引き続き完全修飾 PIDL であることに注意してください。 特に、デスクトップ オブジェクトはデスクトップの子であるため、完全修飾 PIDL には項目 ID が 1 つだけ含まれます。
「フォルダーの ID を取得する」で説明したように、シェル API には、オブジェクトの PIDL を取得するさまざまな方法が用意されています。 これを取得したら、通常は、他のシェル API 関数とメソッドを呼び出すときにオブジェクトを識別するために使用します。 このコンテキストでは、PIDL の内部コンテンツは不透明で無関係です。 この説明では、PIDL を特定の名前空間オブジェクトを表すトークンと考え、一般的なタスクに使用する方法に焦点を当てます。
PIDL の割り当て
PIDL はパスと似ていますが、それらを使用するには、ある程度異なるアプローチが必要です。 主な違いは、メモリの割り当てと割り当て解除の方法です。
パスに使用される文字列と同様に、PIDL にメモリを割り当てる必要があります。 アプリケーションが PIDL を作成する場合は、 ITEMIDLIST 構造体に十分なメモリを割り当てる必要があります。 ここで説明するほとんどの場合、シェルは PIDL を作成し、メモリ割り当てを処理します。 PIDL が割り当てられたものに関係なく、アプリケーションは通常、不要になったときに PIDL の割り当てを解除します。
CoTaskMemAlloc 関数を使用して PIDL を割り当て、CoTaskMemFree 関数を使用して割り当てを解除します。