![]()
Windows Vistaではシェルで利用できるアイコンの数や種類が増えた。それらの新しいアイコンを取得するAPIとしてSHGetStockIconInfoが用意されている。
SHGetStockIconInfoはWindows Vista以降でしか利用できないため、ソースコード中でそのまま利用するとWindows XPなど従来のOSではプログラムが起動しなくなる。そのためここではLoadLibrary、GetProcAddressを利用して動的に呼び出すようにしている。
シェルアイコンを従来のアイコンとしてすべて取得、それらをデスクトップにDrawIconExで描画した。
#include "shellapi.h"
//
// SHGetStockIconInfo API
//
//シェルアイコン取得用のAPI「SHGetStockIconInfo」をGetProcAddressしただけのもの。
//Windows Vista以前のOSの場合はE_FAILもしくはE_NOTIMPLが返る。
//Windows Vista以降の場合はAPIが実行された結果が返る。
//
//対応OS:Windows Vista以降
//
//
HRESULT SafeSHGetStockIconInfo(SHSTOCKICONID siid,UINT uFlags,SHSTOCKICONINFO *psii)
{
HMODULE hDLL;
HRESULT hr;
HRESULT (CALLBACK* pfnSHGetStockIconInfo)(SHSTOCKICONID siid,UINT uFlags,SHSTOCKICONINFO *psii);
hDLL = ::LoadLibrary(_T("shell32.dll"));
if(hDLL == NULL)
return E_FAIL;
(*(FARPROC*)&pfnSHGetStockIconInfo) = ::GetProcAddress(hDLL,"SHGetStockIconInfo");
if(pfnSHGetStockIconInfo)
hr = pfnSHGetStockIconInfo(siid,uFlags,psii);
else
hr = E_NOTIMPL;
::FreeLibrary(hDLL);
return hr;
}
bool Test(void)
{
int i;
HRESULT hr;
HDC hDC;
hDC = ::GetDC(NULL);
if(hDC == NULL)
return false;
//MSDNライブラリではSIID_MAXだが、実際の定義はSIID_MAX_ICONS
for(i = 0; i < (int)SIID_MAX_ICONS ; i++)
{
SHSTOCKICONINFO sInfo;
::ZeroMemory(&sInfo,sizeof(SHSTOCKICONINFO));
sInfo.cbSize = sizeof(SHSTOCKICONINFO);
hr = SafeSHGetStockIconInfo((SHSTOCKICONID)i,SHGSI_ICON,&sInfo);
if(FAILED(hr))
continue;
::DrawIconEx(hDC,200 + (i%16)*35,100 + (i/16)*35, sInfo.hIcon, 0, 0, 0, NULL, DI_IMAGE | DI_COMPAT | DI_DEFAULTSIZE);
}
::ReleaseDC(NULL,hDC);
return true;
}
