第62回 IShellMenuによる「お気に入り」にメニュー項目を追加する (タブブラウザーを作る)

tabbrowser284.gif
今回は再び「お気に入り」メニュー関連項目を実装する。

「お気に入り」メニューの表示方法をIShellMenuに変えてから、「お気に入りに追加」などの項目が表示されなくなった。今回はこれらの項目を再び表示、使えるようにする。

IShellMenuへのメニュー追加はIShellMenu::SetMenuで行える。ここにリソースから読みだしたHMENUを渡すだけでいい。内部でDestroyMenuされるため、m_Cmdbar.GetMenu()などの引数は渡せない。
	bool	PopupMenu(int nX,int nY)
	{
		LPITEMIDLIST	pidl;

		CComPtr<IShellFolder>		pIShellFolder;

		if(_pIMenuBand)
		{
			//すでにメニューが開いていたら、まずはそのメニューを閉じる

			CComPtr<IOleCommandTarget>	pIOleCommandTarget;

			_pIMenuBand->QueryInterface(&pIOleCommandTarget);
			if(pIOleCommandTarget)
				pIOleCommandTarget->Exec(&CLSID_MenuBand,22,0,NULL,NULL);
		}


		//「お気に入り」フォルダのPIDLとIShellFolderを取得
		{
			CComPtr<IShellFolder>	pIShellFolderDesktop;

			::SHGetDesktopFolder(&pIShellFolderDesktop);
			if(pIShellFolderDesktop == NULL)
				return	false;
			::SHGetSpecialFolderLocation(NULL,CSIDL_FAVORITES,&pidl);
			pIShellFolderDesktop->BindToObject(pidl,NULL,IID_IShellFolder,(void **)&pIShellFolder);
		}



		CComPtr<IDeskBand>	pIDeskBand;

		//PIDLとIShellFolderの示すIShellMenu(IDeskBand)を取得
		{
			HRESULT		hr;
			CRegKey		cRegOrder;
			CComPtr<IShellMenu>	pIShellMenu;
			CComPtr<IDeskBar>	pIDeskBar;
			CComPtr<IMenuPopup>	pIMenuPopup;

			//並び順用レジストリ。必要ならCreateしてもいいが今回は「お気に入り」のみなのでopen
			cRegOrder.Open(HKEY_CURRENT_USER,_T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MenuOrder\\Favorites"));

			::CoCreateInstance(CLSID_MenuBand,NULL,CLSCTX_INPROC_SERVER,IID_IShellMenu,(void**)&pIShellMenu);

			//■追加
			//「お気に入りに追加」などのメニュー項目をメニューリソースから追加
			//IShellMenu::Initializeよりも先にIShellMenu::SetMenuを使わないとだめなことに注意
			if(pIShellMenu)
			{
				HMENU	hMenu;
				HMENU	hSubMenu = NULL;

				hMenu = ::LoadMenu(::_Module.m_hInst,MAKEINTRESOURCE(IDR_MAINFRAME));
				if(hMenu)
					hSubMenu = ::GetSubMenu(hMenu,4);			//■メニュー位置固定

				if(hSubMenu)
					pIShellMenu->SetMenu(hSubMenu,m_hWnd,SMSET_TOP);
				//if(hMenu)
				//	::DestroyMenu(hMenu);		//不要
			}

tabbrowser285.gif そのままでは追加したメニュー項目にデフォルトのアイコンが表示されてしまう。アイコンが表示されないように、SMC_GETINFOを受けとったときに、SMIM_ICONで-1を指定して、アイコンを消す。
	//普通のメニュー項目に関する情報
	HRESULT	OnSMC_GETINFO(LPSMDATA psmd,UINT uMsg,WPARAM wParam,LPARAM lParam)
	{
		SMINFO*		pSmInfo = (SMINFO*)lParam;

		if(pSmInfo->dwMask & SMIM_FLAGS)
			pSmInfo->dwFlags |= SMIF_DROPCASCADE | SMIF_TRACKPOPUP;

		//■追加
		if(pSmInfo->dwMask & SMIM_ICON)
			pSmInfo->iIcon = -1;			//追加メニューのアイコンを非表示にする。iIcon==0のときのみ-1にすべき?

		return	S_OK;
	}

tabbrowser286.gif
またIShellMenuを使う前にお気に入りが開いたことを検出するために「dummy」というメニュー項目を用意していた。それはもう不要なのでリソースから消しておく。

tabbrowser287.gif
これでビルド/実行すると「お気に入りの整理」などのメニュー項目が追加され、利用できるようになった。

だんだんソースコードが荒れてきて利用されていない関数も多くなってきた。そのため次回は再びソースコードの整理をする。

プロジェクトファイルをダウンロード


カテゴリー「タブブラウザーを作る」 のエントリー