第14回 「お気に入り」メニューにアイコンを表示する (タブブラウザーを作る)

tabbrowser58.gif
前回までに「お気に入り」メニューが少しずつ使えるようになってきた。しかしWindows標準のメニューのままで見た目がイマイチだった。

今回は「お気に入り」のインターネットショートカットからアイコンを取得して、メニューに表示する。

前回までに作成したプロジェクトを開き、「MainFrm.h」のお気に入りメニュー用クラスにメニューアイテムが追加されたときに呼ばれる処理を追加する。Internet Explorerの「お気に入り」メニューはオーナードローで作成され、アイコンはおそらくマルチスレッドで順次読み込み表示をかけているのだと思う。
しかし、今回はメニューアイテム追加時にアイコンを設定するようにした。結果として最初にメニューを開くときにアイコンを読み込む処理が発生するため、「お気に入り」メニューが重くなる。そのためこれはちょっと改悪な実装だ。

※実は今回仮想関数OnAppendedMenuが呼び出されるようにCDnpFolderMenuを修正している。その部分はこのページには載せていないです。ここに示したソースコードを正常に動かすにはCDnpFolderMenuを今回のサンプルプロジェクトのものと差し替えてください。
//「お気に入り」メニュークラス
class	CFavoritesMenu	: public CDnpFolderMenu
{
public:
	BEGIN_MSG_MAP(CFavoritesMenu)
		CHAIN_MSG_MAP(CDnpFolderMenu)
	END_MSG_MAP()

	//■追加
	~CFavoritesMenu()
	{
		size_t	i;
		size_t	nSize;

		//メニューで利用したHBITMAPを削除
		nSize = _ahBitmap.GetCount();
		for(i = 0; i < nSize; i++)
			::DeleteObject(_ahBitmap[i]);
		_ahBitmap.RemoveAll();
	}

protected:

	CAtlArray<HBITMAP>	_ahBitmap;	//■追加 メニューで利用したHBITMAPを保持

	//■追加
	//「ファイル」の項目が追加された
	virtual	bool	OnAppendedMenu(INT_PTR nIndex,CAtlArray<CFileData>& acFileList,HMENU hMenu,UINT nID)
	{
		HBITMAP	hBitmap;

		//ビットマップを取得
		hBitmap = GetHBitmapFromFile(acFileList[nIndex]._strPath + acFileList[nIndex]._strFile);
		if(hBitmap == NULL)
			return	false;

		//ビットマップをメニュー項目に割り当てる
		::SetMenuItemBitmaps(hMenu,nID,MF_BYCOMMAND,hBitmap,hBitmap);
		_ahBitmap.Add(hBitmap);

		return	true;
	}

	//■追加
	//「フォルダ」の項目が追加された
	virtual	bool	OnAppendedMenu(INT_PTR nIndex,CAtlArray<CFileData>& acFileList,HMENU hMenu,HMENU hSubMenu)
	{
		HBITMAP		hBitmap;

		//ビットマップを取得
		hBitmap = GetHBitmapFromFile(acFileList[nIndex]._strPath + acFileList[nIndex]._strFile);
		if(hBitmap == NULL)
			return	false;

		//ビットマップをメニュー項目に割り当てる
		::SetMenuItemBitmaps(hMenu,::GetMenuItemCount(hMenu) - 1,MF_BYPOSITION,hBitmap,hBitmap);
		_ahBitmap.Add(hBitmap);

		return	true;
	}

	//■追加
	//ファイル名からアイコンのビットマップ取得
	HBITMAP	GetHBitmapFromFile(LPCTSTR pszFile)
	{
		HBITMAP		hBitmap;
		CAtlString	strFolder;
		CAtlString	strFile;
		SHFILEINFO	sShFileInfo;
		HICON		hIcon;
		ICONINFO	sIconInfo;
		HIMAGELIST	hImageList;

		//パスからアイコン取得
		hImageList = (HIMAGELIST)::SHGetFileInfo(pszFile,0,&sShFileInfo,sizeof(SHFILEINFO),SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
		hIcon = ::ImageList_GetIcon(hImageList,sShFileInfo.iIcon,ILD_NORMAL);
		::ImageList_Destroy(hImageList);
		if(hIcon == NULL)
			return	NULL;

		//アイコンからビットマップ取得
		::ZeroMemory(&sIconInfo,sizeof(ICONINFO));
		::GetIconInfo(hIcon,&sIconInfo);
		hBitmap = sIconInfo.hbmColor;
		::DeleteObject(sIconInfo.hbmMask);
		::DestroyIcon(hIcon);
		if(hBitmap == NULL)
			return	NULL;

		return	hBitmap;
	}

tabbrowser59.gif
これでビルド/実行すると「お気に入り」メニューにアイコンが表示された。まだ簡易的な実装なため、アイコンの余白部分が黒くなっていたり、先に述べたように重かったりする。しかしとりあえずこのまま保留する。

次回はタブに表示している現在のページ名をもう少しきちんとしたタイミングで実装されるように修正する。

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


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