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

VC 實作圖示資源擷取與儲存:打造專屬圖示提取工具

     編輯:VC++

專屬圖示提取工具核心實作

想從其他應用程式提取精美圖示?本文以自製工具「輕輕鬆鬆抓圖示」為例,完整示範如何擷取各類檔案(ICO、BMP、EXE、DLL、ICL)中的圖示資源,並儲存為 ICO 或 BMP 格式。核心封裝為 CIcons 與 CDib 兩大類別(四個檔案:Icons.h/cpp、Dib.h/cpp),專案加入即可直接呼叫。

介面示意

圖示提取工具介面

核心功能實作

1. 讀取並顯示圖示到列表框

void CIconSnapDlg::OnOK() {
    CFileDialog fileDialog(TRUE, _T("*.ICO"), NULL, NULL,
        _T("資源檔(*.ICO,*.BMP,*.EXE,*.DLL,*.ICL)|*.ICO;*.BMP;*.EXE;*.DLL;*.ICL||"));
    if (fileDialog.DoModal() == IDOK) {
        szOpenFileName = fileDialog.GetPathName();
        szOpenFileExtName = fileDialog.GetFileExt(); szOpenFileExtName.MakeLower();
        m_List.ResetContent();

        if (szOpenFileExtName == _T("ico")) { // ICO 檔
            lpIR = pIcons->ReadIconFromICOFile(szOpenFileName);
            HICON hIcon = ExtractIcon(AfxGetInstanceHandle(), szOpenFileName, 0);
            if (hIcon) m_List.AddString(szOpenFileName);
            ((CStatic*)GetDlgItem(IDC_ICONS))->SetIcon(hIcon);
        }
        else if (szOpenFileExtName == _T("bmp")) { // BMP 檔
            pIcons->IconImageFromBMPFile(szOpenFileName, &lpIR->IconImages[0], TRUE);
            HICON hIcon = pIcons->MakeIconFromResource(&lpIR->IconImages[0]);
            if (hIcon) m_List.AddString(szOpenFileName);
            ((CStatic*)GetDlgItem(IDC_ICONS))->SetIcon(hIcon);
        }
        else { // EXE/DLL/ICL 資源檔
            HINSTANCE hLibrary = LoadLibraryEx(szOpenFileName, NULL, LOAD_LIBRARY_AS_DATAFILE);
            if (!hLibrary) { MessageBox(_T("載入失敗,需為 Win32 檔案!")); return; }
            EDII.szFileName = szOpenFileName; EDII.hInstance = hLibrary;
            if (!EnumResourceNames(EDII.hInstance, RT_GROUP_ICON, (ENUMRESNAMEPROC)MyEnumProcedure, (LPARAM)GetSafeHwnd()))
                { MessageBox(_T("列舉圖示資源失敗!")); return; }
        }

        m_List.SetCurSel(0);
        if (m_List.GetCount() == 0) { MessageBox(_T("無圖示資源!")); m_Copy.EnableWindow(FALSE); m_SaveAs.EnableWindow(FALSE); return; }
        m_Copy.EnableWindow(TRUE); m_SaveAs.EnableWindow(TRUE);
        InvalidateRect(NULL, TRUE); // 觸發 OnPaint 顯示
    }
}

2. OnPaint 繪製選中圖示

LPTSTR lpIconID; HICON hIcon;
if ((lpIconID = (LPTSTR)m_List.GetItemData(m_List.GetCurSel())) != (LPTSTR)LB_ERR) {
    if (szOpenFileExtName == _T("exe") || szOpenFileExtName == _T("dll") || szOpenFileExtName == _T("icl")) {
        hIcon = pIcons->GetIconFromInstance(EDII.hInstance, lpIconID);
        ((CStatic*)GetDlgItem(IDC_ICONS))->SetIcon(hIcon);
    }
}

3. 儲存為 ICO 或 BMP

void CIconSnapDlg::OnButtonSaveas() {
    LPTSTR lpIconID;
    CFileDialog fileDialog(FALSE, _T("*.ICO"), NULL, NULL, _T("圖示檔(*.ICO)|*.ICO|位圖檔(*.BMP)|*.BMP||"));
    if (fileDialog.DoModal() == IDOK) {
        szSaveFileName = fileDialog.GetPathName();
        szSaveFileExtName = fileDialog.GetFileExt(); szSaveFileExtName.MakeLower();

        if (szOpenFileExtName == _T("exe") || szOpenFileExtName == _T("dll") || szOpenFileExtName == _T("icl"))
            if ((lpIconID = (LPTSTR)m_List.GetItemData(m_List.GetCurSel())) != (LPTSTR)LB_ERR)
                lpIR = pIcons->ReadIconFromEXEFile(szOpenFileName, lpIconID);

        if (szSaveFileExtName == _T("bmp")) {
            if (lpIR && m_List.GetCount() > 0) { BeginWaitCursor(); pIcons->IconImageToBMPFile(szSaveFileName, &lpIR->IconImages[0]); EndWaitCursor(); }
            else MessageBox(_T("無可儲存資源!"));
        }
        else if (szSaveFileExtName == _T("ico")) {
            if (lpIR && m_List.GetCount() > 0) { BeginWaitCursor(); pIcons->WriteIconToICOFile(lpIR, szSaveFileName); EndWaitCursor(); }
            else MessageBox(_T("無可儲存資源!"));
        }
    }
}

核心 API:LoadLibraryEx(LOAD_LIBRARY_AS_DATAFILE) 載入資源模組、EnumResourceNames 列舉群組圖示、CIcons 類別封裝讀寫轉換邏輯。完整原始碼可整合至專案直接使用。

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