首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++Builder 使用 ExtractIcon / SHGetFileInfo 取得檔案關聯圖示

     編輯:關於C++

前言:圖示擷取兩大 API

Windows 提供兩種主要方式取得檔案關聯圖示:

  • ExtractIcon / ExtractIconEx:針對 **可執行檔 (.exe/.dll/.ocx)** 內建圖示資源
  • SHGetFileInfo:通用 **Shell 命名空間** 物件 (含捷徑、文件、資料夾、可執行檔),取得系統映像清單索引與圖示控制代碼

方法一:ExtractIcon (僅限可執行檔)

// 介面:Button + Image + OpenDialog
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    if (OpenDialog1->Execute())
    {
        AnsiString file = OpenDialog1->FileName;
        HICON hIcon = ExtractIcon(Handle, file.c_str(), 0); // 索引 0 = 第一個圖示
        if (hIcon)
        {
            TIcon *icon = new TIcon();
            icon->Handle = hIcon;
            AnsiString tmp = "temp.ico";
            icon->SaveToFile(tmp); // 儲存暫存檔
            Image1->Picture->LoadFromFile(tmp); // 載入 TImage
            delete icon;
            DeleteFile(tmp);
        }
    }
}
  • ExtractIcon(hInst, lpszExeFileName, nIconIndex):nIconIndex=-1 回傳圖示總數
  • 優點:簡單、無需 Shell 初始化
  • 缺點:不支援文件類型關聯圖示 (如 .txt/.pdf 的預設圖示)

方法二:SHGetFileInfo (通用、推薦)


#include 
#pragma comment(lib, "shell32.lib")

void __fastcall TForm1::Button2Click(TObject *Sender)
{
    if (OpenDialog1->Execute())
    {
        AnsiString file = OpenDialog1->FileName;
        SHFILEINFO sfi = {0};

        // 取得大圖示 (32x32)
        HIMAGELIST hImg = (HIMAGELIST)SHGetFileInfo(
            file.c_str(), 0, &sfi, sizeof(sfi),
            SHGFI_ICON | SHGFI_LARGEICON | SHGFI_SYSICONINDEX
        );

        if (sfi.hIcon)
        {
            TIcon *icon = new TIcon();
            icon->Handle = sfi.hIcon;
            AnsiString tmp = "temp.ico";
            icon->SaveToFile(tmp);
            Image1->Picture->LoadFromFile(tmp);
            delete icon;
            // 圖示屬系統映像清單,不可 DestroyIcon,若自行複製則需 DestroyIcon
        }
    }
}

SHGetFileInfo 關鍵旗標組合

旗標用途
SHGFI_ICON取得圖示控制代碼
SHGFI_LARGEICON32x32 (預設小圖示 16x16)
SHGFI_SMALLICON16x16
SHGFI_SYSICONINDEX回傳系統映像清單索引 (sfi.iIcon),可搭配 ImageList_GetIcon
SHGFI_USEFILEATTRIBUTES檔案不存在時,依屬性模擬 (如僅有副檔名)
SHGFI_TYPENAME取得類型名稱 (sfi.szTypeName,如 "Text Document")
SHGFI_DISPLAYNAME取得顯示名稱 (sfi.szDisplayName)

進階:直接使用系統映像清單 (效能最佳)


// 取得系統映像清單控制代碼
HIMAGELIST hSysImg = (HIMAGELIST)SHGetFileInfo(
    "C:\\", 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX | SHGFI_SMALLICON);

// 直接從映像清單繪製/取得圖示
HICON hIcon = ImageList_GetIcon(hSysImg, sfi.iIcon, ILD_TRANSPARENT);
// 繪製至 Canvas
ImageList_Draw(hSysImg, sfi.iIcon, Canvas->Handle, x, y, ILD_TRANSPARENT);
  • 避免重複 SHGetFileInfo 呼叫、暫存檔 I/O
  • 適合列表檢視、樹狀檢視大量檔案圖示顯示

結語

需可執行檔內建圖示用 ExtractIcon;需**完整 Shell 關聯圖示** (含文件、捷徑、資料夾) 必用 SHGetFileInfo。現代 UI 開發建議直接操作系統映像清單,效能與視覺一致性最佳。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved