#include<windows.h> #include<tchar.h> // HIMAGELIST // ImageList_GetIcon #include <commctrl.h> #pragma comment(lib, "comctl32.lib") // IID_IImageList に必要 #include <commoncontrols.h> #include <cstdio> #pragma warning(disable:4996) // アイコンを取得 HICON my_get_icon(const wchar_t* path) { // システムイメージリストの取得 HIMAGELIST hImageList; HRESULT hr = SHGetImageList(SHIL_JUMBO , IID_IImageList, (void**)&hImageList); // SHIL_JUMBO 256x256 // SHIL_EXTRALARGE 48x48 // SHIL_LARGE 32x32 // SHIL_SMALL 16x16 // hrからファイルのアイコンを取得 if (SUCCEEDED(hr)) { SHFILEINFO shfi; memset(&shfi, 0, sizeof(SHFILEINFO)); // path からアイコンの「イメージリスト上のインデクス」を取得 // ※ アイコンハンドルではない SHGetFileInfo(path, 0, &shfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX); // SHGetImageListで取得したイメージリストから // SHGetFileInfoで取得したインデクスを指定してアイコンハンドルを取得 HICON hicon = ImageList_GetIcon(hImageList, shfi.iIcon, ILD_NORMAL); // ※ hiconは使わなくなったら DestroyIcon で破棄すること return hicon; } }
#include<windows.h> #include<tchar.h> // HIMAGELIST // ImageList_GetIcon // 表示用に ImageList_Draw も使える #include <commctrl.h> #pragma comment(lib, "comctl32.lib") // SHGetSpecialFolderLocation // SHGetFolderLocation #include <ShlObj.h> #include <cstdio> #pragma warning(disable:4996)
// アイコンを取得 HICON my_get_special_icon() { #if 0 // 注: SHGetSpecialFolderLocation は非推奨 // https://learn.microsoft.com/ja-jp/windows/win32/api/shlobj_core/nf-shlobj_core-shgetspecialfolderlocation PIDLIST_ABSOLUTE pidl; HRESULT hr = SHGetSpecialFolderLocation(NULL, CSIDL_FONTS, &pidl); #else LPITEMIDLIST pidl; // マイコンピュータのPIDLを取得 HRESULT hr = SHGetFolderLocation(NULL, CSIDL_DRIVES, NULL, 0, &pidl); // CSIDL_DRIVES マイコンピュータアイコン // CSIDL_FONTS フォントアイコン // CSIDL_DESKTOP デスクトップアイコン // ... etc #endif SHFILEINFO shfi; memset(&shfi, 0, sizeof(SHFILEINFO)); DWORD_PTR ret = SHGetFileInfoW(// イメージリストとその中のpidlで指定したアイコンのidを取得 (LPCTSTR)pidl, 0, &shfi, sizeof(SHFILEINFO), SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_LARGEICON); HIMAGELIST imagelist = (HIMAGELIST)ret; // アイコンリストが取得できたかどうかを表す if (imagelist != nullptr) { // imagelistからアイコンを取得 // ImageList_GetIconはアイコンのコピーを渡すので、後でDestroyIconが必要 HICON hicon = ImageList_GetIcon(imagelist, shfi.iIcon, ILD_NORMAL); // SHGFI_SYSICONINDEX を指定した場合、hIconは無効 //DestroyIcon(shfi.hIcon); return hicon;// コピーしたアイコンを返す } return NULL; }
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { PAINTSTRUCT ps; HDC hdc; // アイコン static HICON myicon; switch (msg) { case WM_CREATE: // コピーしたアイコンを取得 myicon = my_get_special_icon(); return 0; case WM_DESTROY: // コピーしたアイコンを破棄 DestroyIcon(myicon); PostQuitMessage(0); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); // アイコンを描画 DrawIconEx(hdc, 0 + 10, 10, myicon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT); EndPaint(hwnd, &ps); return 0; } return DefWindowProc(hwnd, msg, wp, lp); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow) { HWND hwnd; WNDCLASS winc; MSG msg; winc.style = CS_HREDRAW | CS_VREDRAW; winc.lpfnWndProc = WndProc; winc.cbClsExtra = winc.cbWndExtra = 0; winc.hInstance = hInstance; winc.hIcon = LoadIcon(NULL, IDI_APPLICATION); winc.hCursor = LoadCursor(NULL, IDC_ARROW); winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); winc.lpszMenuName = NULL; winc.lpszClassName = TEXT("SZL-WND"); if (!RegisterClass(&winc)) return 0; hwnd = CreateWindow( TEXT("SZL-WND"), TEXT("icon test"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 200, 200, NULL, NULL, hInstance, NULL ); if (hwnd == NULL) return 0; while (GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg); return msg.wParam; }