EternalWindows
シェル拡張 / 仮想フォルダサンプル
サンプルはこちら

今回は、これまでの節で取り上げた内容を合わせたサンプルを確認します。 まず、右側のリンクのコードを基にDLLのビルドを行ってください。 このとき、DLLにはリソースとしてアイコンを含めておきます。 DLLの作成が完了したらこれをレジストリに登録して、シェルを再起動するようにします。 すると、DLLのリソースに含まれていたアイコンがデスクトップに表示されますが、 これが今回作成した仮想フォルダになります。 仮想フォルダを開くと、次のようなウインドウが表示されます。

フォルダビューに表示されている2つのアイテムはCEnumIDList::Nextによって列挙されたものであり、 アイテムのアイコンはCUIObject::Extractから取得したものです。 アイテムを開くとCUIObject::InvokeCommandが呼ばれ、選択したアイテムがアイテムAであるならばメッセージボックスが表示されます。 一方、選択したアイテムがアイテムBである場合は、CShellFolder::BindToObjectが呼ばれてフォルダの階層が1つ進むことになり、 アイテムCが表示されます。

仮想フォルダを登録するには、次に示すレジストリキーを作成することになります。

HKEY_CLASSES_ROOT
  CLSID
    <オブジェクトのCLSID> (既定) = 仮想フォルダの名前
      DefaultIcon (既定) = 仮想フォルダのアイコンを格納するファイルパス
      ShellFolder Attributes = 仮想フォルダの属性

HKEY_LOCAL_MACHINE
  SOFTWARE
    Microsoft
      Windows
        CurrentVersion
          Explorer
            Virtual Folder Name
        NameSpace
                <オブジェクトのCLSID> (既定) = 独自のハンドラ名

Virtual Folder Nameという箇所には、DesktopやMy Computer、Control Panelなどの名前が入ることになります。 たとえば、デスクトップ以下に仮想フォルダのアイコンを表示したい場合は、Desktopキー以下を参照することになります。 各キーを作成するコードは次のようになります。

DWORD dwData = SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANDELETE;

wsprintf(szKey, TEXT("CLSID\\%s\\DefaultIcon"), g_szClsid);
if (!CreateRegistryKey(HKEY_CLASSES_ROOT, szKey, NULL, szModulePath))
	return E_FAIL;
	
wsprintf(szKey, TEXT("CLSID\\%s\\ShellFolder"), g_szClsid);
if (!CreateRegistryKeyDword(HKEY_CLASSES_ROOT, szKey, TEXT("Attributes"), &dwData))
	return E_FAIL;

wsprintf(szKey, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\NameSpace\\%s"), g_szClsid);
if (!CreateRegistryKey(HKEY_LOCAL_MACHINE, szKey, NULL, TEXT("ShellFolder Sample")))
	return E_FAIL;

DefaultIconキーの既定のエントリには、szModulePathの中身を書き込むようにしています。 この変数にはDLLのフルパスが格納されており、このDLLにアイコンが格納されているものと仮定しています。 ShellFolderキーのAttributesエントリには、SFGAOから始まる定数を書き込むことになります。 SFGAO_FOLDERはアイテムがフォルダであることを意味し、 SFGAO_HASSUBFOLDERはフォルダがサブフォルダを持つことを意味し、 SFGAO_CANDELETEはフォルダを削除できることを意味します。 最後のCreateRegistryKeyの呼び出しでは、Desktop\NameSpace以下にオブジェクトのCLSIDのキーを作成して、 そこにDLLを識別する名前を書き込んでいます。 この名前は自由に指定して問題ありません。

仮想フォルダの属性としてSFGAO_CANDELETEを指定した場合はそのフォルダを削除することができるわけですが、 このフォルダはシェルの再起動後に復元されるようなことはありません。 理由は、仮想フォルダの削除時にその仮想フォルダのCLSIDが次に示すレジストリキー以下に作成されるからです。

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\CLSID

このキーの下には削除された仮想フォルダのCLSIDが作成されるため、 仮想フォルダを復元したい場合はその作成されたキーを削除することになります。


戻る