フォルダーの ID の取得

名前空間オブジェクトを使用する前に、それを識別する方法が必要です。 つまり、項目識別子リスト (PIDL) へのポインター、またはファイル システム オブジェクトの場合はそのパスを取得します。 このセクションでは、オブジェクト ID を取得する 2 つの簡単な方法について説明します。

任意のフォルダーで動作するより強力な方法については、 IShellFolder インターフェイスを使用します。 詳細については、「 フォルダーの内容に関する情報を取得 する」を参照してください。

[ファイルを開く] ダイアログ ボックス

ユーザーが名前空間を移動してフォルダーを選択できるようにするには、アプリケーションで IFileDialog インターフェイスを使用できます。 FOS_PICKFOLDERS フラグを指定してこのインターフェイスを呼び出すと、[フォルダーの選択] モードで [ファイルを開く] 共通ダイアログ ボックスが起動します。

Windows Vista 以降の場合は、フォルダーを選択するための推奨される方法です。

[SHBrowseForFolder] ダイアログ ボックス

ユーザーが名前空間内を移動してフォルダーを選択できるようにするには、アプリケーションで SHBrowseForFolder を呼び出すだけです。 この関数を呼び出すと、[ 開く] または [名前を付けて保存 ] の一般的なダイアログ ボックスのように動作する UI を含むダイアログ ボックスが起動します。

ユーザーがフォルダーを選択すると、 SHBrowseForFolder は フォルダーの完全修飾 PIDL とその表示名を返します。 フォルダーがファイル システムにある場合、アプリケーションは SHGetPathFromIDList を呼び出すことによって PIDL をパスに変換できます。 アプリケーションでは、ルート フォルダーを指定することで、ユーザーが選択できるフォルダーの範囲を制限することもできます。 名前空間内のルートの下にあるフォルダーのみが表示されます。 次の図は、ルート フォルダーが Program Files に設定されている [SHBrowseForFolder ] ダイアログ ボックスを示しています。

[フォルダーの参照] ダイアログ ボックスのスクリーン ショット

SHBrowseForFolder の使用方法の簡単な例については、後で説明します。

特殊なフォルダーと CSIDLs

一般的に使用されるフォルダーの数は、システムによって 特別 なものとして指定されます。 これらのフォルダーには明確に定義された目的があり、そのほとんどはすべてのシステムに存在します。 最初に存在しない場合でも、名前と場所は定義されたままであるため、後で追加できます。 特別なフォルダーのコレクションには、プリンター、マイ ドキュメント、ネットワーク近隣など、システムのすべての標準仮想フォルダーが含まれます。 また、Program Files や System などの標準ファイル システム フォルダーも多数含まれています。

フォルダーはすべてのシステムの標準コンポーネントですが、名前空間内の名前と場所は異なる場合があります。 たとえば、システム ディレクトリは一部のシステムでは C:\Winnt\System32、他のシステムでは C:\Windows\System32 です。 以前は、環境変数は、特定のシステム上の特別なフォルダーの名前と場所を決定する方法を提供しました。 シェルでは、特別なフォルダー である CSIDL を識別するための、より堅牢で柔軟な方法が提供されるようになりました。 一般に、環境変数の代わりにそれらを使用する必要があります。

CSIDL は、特定のシステム上の名前や場所に関係なく、特別なフォルダーを識別および検索する一様な方法を提供します。 環境変数とは異なり、CSIDL は仮想フォルダーとファイル システム フォルダーで使用できます。 各特殊フォルダーには、一意の CSIDL が割り当てられます。 たとえば、Program Files ファイル システム フォルダーの CSIDL は CSIDL_PROGRAM_FILES、Network Neighborhood 仮想フォルダーには CSIDL のCSIDL_NETWORKがあります。

CSIDL は、特殊なフォルダーの PIDL または特殊なファイル システム フォルダーのパスを取得するために、いくつかのシェル関数の 1 つと組み合わせて使用されます。 フォルダーがシステム上に存在しない場合、アプリケーションは CSIDL と CSIDL_FLAG_CREATEを組み合わせることによって、フォルダーを強制的に作成できます。 CSIDL は、次の関数に渡すことができます。

これら 2 つの関数は、シェルのバージョン 5.0 で導入され、 SHGetSpecialFolderLocation 関数と SHGetSpecialFolderPath 関数よりも優先されることに注意してください。

CSIDLs と SHBrowseForFolder を使用する方法の簡単な例

次のサンプル関数 PidlBrowse は、CSIDL を使用してフォルダーの PIDL を取得し、 SHBrowseForFolder を使用してユーザーにフォルダーを選択させる方法を示しています。 選択したフォルダーの PIDL と表示名を返します。

LPITEMIDLIST PidlBrowse(HWND hwnd, int nCSIDL, LPSTR pszDisplayName)
{
    LPITEMIDLIST pidlRoot = NULL;
    LPITEMIDLIST pidlSelected = NULL;
    BROWSEINFO bi = {0};

    if(nCSIDL)
    {
        SHGetFolderLocation(hwnd, nCSIDL, NULL, NULL, &pidlRoot);
    }

    else
    {
        pidlRoot = NULL;
    }

    bi.hwndOwner = hwnd;
    bi.pidlRoot = pidlRoot;
    bi.pszDisplayName = pszDisplayName;
    bi.lpszTitle = "Choose a folder";
    bi.ulFlags = 0;
    bi.lpfn = NULL;
    bi.lParam = 0;

    pidlSelected = SHBrowseForFolder(&bi);

    if(pidlRoot)
    {
        CoTaskMemFree(pidlRoot);
    }

    return pidlSelected;
}

呼び出し元のアプリケーションは、 SHBrowseForFolder で必要なウィンドウ ハンドルを渡します。 nCSIDL パラメーターは、ルート フォルダーを指定するために使用される省略可能な CSIDL です。 階層内のルート フォルダーの下にあるフォルダーのみが表示されます。 前に示した図は、 nCSIDLCSIDL_PROGRAM_FILES に設定してこの関数を呼び出すことによって生成されました。 呼び出し元のアプリケーションは、PidlBrowse が返されたときに選択したフォルダーの表示名を保持するために、文字列バッファー pszDisplayName も渡します。 呼び出し元のアプリケーションは、CoTaskMemFree を使用して SHBrowseForFolder によって返される IDList を解放する必要があります。