スポンサーリンク

SHGetFileInfoでアイコンを取得(2) 大きなアイコン,コンピュータアイコンなど

256x256のアイコンを取得

#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; }

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: