![]()
前回はステータスバーへ現在のインターネットゾーン名を表示した。今回はゾーン用のアイコンを表示する。
ありがたいことにゾーン名を取得するときに利用したIInternetZoneManager::GetZoneAttributesはゾーン名に加えて、表示用のアイコンファイル名も教えてくれる。今回はこの情報を元にアイコンを表示する。
まずはファイルからアイコンを読み込むようにCIconManagerに機能を実装する。ステータスバーにアイコンを表示するたびにファイルからアイコンをロードしていたのでは効率が悪いので、_acItemという配列を用意してそこに一度読み込んだアイコンファイルの情報を格納しておくことにした。
//アイコンを管理
//アイコンをAddする関数などは未実装。今後追加
class CIconManager
{
protected:
CAtlArray<HICON> _ahIcon; //アイコンリスト
//■追加
//ファイルからアイコンを読み込むときのキャッシュ用クラス
class CItem
{
public:
CItem()
{
nIconIndex = -1;
}
CItem(LPCTSTR pszFile,UINT nIndex)
{
strIconFile = pszFile;
nIconIndex = nIndex;
}
CAtlString strIconFile;
UINT nIconIndex;
};
CAtlArray<CItem> _acItem; //■追加 ファイルから読み込んだアイコンキャッシュ情報
//■追加
//キャッシュ情報からアイコンを取得する
bool GetIcon(LPCTSTR pszFile,HICON& hIcon)
{
size_t i;
size_t nSize;
nSize = _acItem.GetCount();
for(i = 0; i < nSize; i++)
{
if(_acItem[i].strIconFile != pszFile)
continue;
hIcon = GetIcon(_acItem[i].nIconIndex);
return true;
}
hIcon = NULL;
return false;
}
//■追加
//キャッシュおよび_ahIconへアイコンを追加する
//ファイルから読み込んだ場合は必ずこの関数で追加すること
bool AddIcon(LPCTSTR pszFile,HICON hIcon)
{
UINT nIndex;
nIndex = _ahIcon.Add(hIcon);
_acItem.Add(CItem(pszFile,nIndex));
return true;
}
//■追加
//ファイルやファイルのリソースからアイコンを取得
HICON GetIcon(LPCTSTR pszIconFile)
{
bool ret;
int nFind;
HICON hIcon;
ret = GetIcon(pszIconFile,hIcon);
if(ret)
return hIcon;
//LoadIconのは自動でDestroyされる
hIcon = (HICON)::LoadImage(NULL,pszIconFile,IMAGE_ICON,0,0,LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
if(hIcon)
hIcon = (HICON)::CopyImage(hIcon,IMAGE_ICON,::GetSystemMetrics(SM_CXSMICON),::GetSystemMetrics(SM_CYSMICON),LR_COPYFROMRESOURCE | LR_COPYDELETEORG | LR_COPYRETURNORG);
if(hIcon)
{
AddIcon(pszIconFile,hIcon);
return hIcon;
}
//アイコンがロードできなかった場合は...
//「c:¥xxx.dll#0010」のようなリソース指定としてトライ
HMODULE hDLL;
CAtlString strFile(pszIconFile);
nFind = strFile.ReverseFind(_T('#'));
if(nFind < 0)
return NULL; //リソース名ではなかった
hDLL = ::LoadLibrary(strFile.Left(nFind));
if(hDLL == NULL)
return NULL;
//LoadIconのは自動でDestroyされる
hIcon = (HICON)::LoadImage(hDLL,(LPCTSTR)::_tcstoi64(strFile.Right(strFile.GetLength() - nFind - 1),NULL,10),IMAGE_ICON,0,0,LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
if(hIcon)
hIcon = (HICON)::CopyImage(hIcon,IMAGE_ICON,::GetSystemMetrics(SM_CXSMICON),::GetSystemMetrics(SM_CYSMICON),LR_COPYFROMRESOURCE | LR_COPYDELETEORG | LR_COPYRETURNORG);
::FreeLibrary(hDLL);
AddIcon(pszIconFile,hIcon); //NULLでも登録してしまう
return hIcon;
}
bool SetZone(DWORD dwZone)
{
_dwZone = dwZone;
if(IsWindow() == FALSE)
return true; //trueを返す
//ゾーンのテキストをステータスバーに表示
{
ZONEATTRIBUTES sZoneAttributes;
CComPtr<IInternetZoneManager> pIInternetZoneManager;
::ZeroMemory(&sZoneAttributes,sizeof(ZONEATTRIBUTES));
sZoneAttributes.cbSize = sizeof(ZONEATTRIBUTES);
pIInternetZoneManager.CoCreateInstance(CLSID_InternetZoneManager,NULL,CLSCTX_INPROC_SERVER);
if(pIInternetZoneManager)
pIInternetZoneManager->GetZoneAttributes(dwZone,&sZoneAttributes);
CAtlString strZone = sZoneAttributes.szDisplayName;
CStatusBarCtrl wndStatusBar = m_hWnd;
//■追加
//ゾーンアイコン表示
{
HICON hIcon = NULL;
if(sZoneAttributes.szIconPath && *sZoneAttributes.szIconPath)
hIcon = _cIconList.GetIcon(sZoneAttributes.szIconPath);
wndStatusBar.SetIcon(PAIN_ZONE,hIcon);
}
wndStatusBar.SetText(PAIN_ZONE,strZone);
}
return true;
}
![]()
これでビルド/実行するとステータスバーにゾーンのアイコンが表示されるようになった。ステータスバーの幅が狭すぎてゾーン名がはみ出てしまったのはご愛敬。そのうちに修正することにして今は保留しておく。
次回はステータスバーのゾーン情報表示部分をダブルクリックしたときにゾーン設定画面が開くようにする。
