![]()
前回までに「お気に入り」メニューが少しずつ使えるようになってきた。しかしWindows標準のメニューのままで見た目がイマイチだった。
今回は「お気に入り」のインターネットショートカットからアイコンを取得して、メニューに表示する。
前回までに作成したプロジェクトを開き、「MainFrm.h」のお気に入りメニュー用クラスにメニューアイテムが追加されたときに呼ばれる処理を追加する。Internet Explorerの「お気に入り」メニューはオーナードローで作成され、アイコンはおそらくマルチスレッドで順次読み込み表示をかけているのだと思う。
しかし、今回はメニューアイテム追加時にアイコンを設定するようにした。結果として最初にメニューを開くときにアイコンを読み込む処理が発生するため、「お気に入り」メニューが重くなる。そのためこれはちょっと改悪な実装だ。
//「お気に入り」メニュークラス
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;
}
![]()
これでビルド/実行すると「お気に入り」メニューにアイコンが表示された。まだ簡易的な実装なため、アイコンの余白部分が黒くなっていたり、先に述べたように重かったりする。しかしとりあえずこのまま保留する。
次回はタブに表示している現在のページ名をもう少しきちんとしたタイミングで実装されるように修正する。
