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

DLL 中使用資源完整指南:Win32 DLL 與 MFC DLL 兩種模式詳解

     編輯:VC 教學

一、Win32 DLL 使用對話框資源

建立步驟 (以 UseDll 專案為例)

  1. File → New → Win32 Dynamic-Link Library,名稱 UseDlg,選 A simple DLL project
  2. Insert → Resource → Dialog,建立兩個對話框:
    IDD_DLG_SHOW (僅保留 OK 鈕)、IDD_ABOUTBOX (Caption: About)
  3. 儲存資源檔為 UseDlg.rc,將 resource.h、UseDlg.rc 加入專案
  4. UseDll.cpp 核心代碼:
// UseDll.cpp
#include "resource.h"

HINSTANCE g_hInst = NULL;
HWND      g_hDlg  = NULL;

BOOL CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
BOOL CALLBACK AboutProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);

BOOL APIENTRY DllMain(HANDLE hModule, DWORD reason, LPVOID lpReserved)
{
    if (reason == DLL_PROCESS_ATTACH)
        g_hInst = (HINSTANCE)hModule;
    return TRUE;
}

extern "C" __declspec(dllexport) void ShowDlg()
{
    // 建立非模態對話框
    g_hDlg = CreateDialog(g_hInst, MAKEINTRESOURCE(IDD_DLG_SHOW), NULL, (DLGPROC)DlgProc);
    ShowWindow(g_hDlg, SW_SHOW);
}

BOOL CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
{
    switch (msg)
    {
    case WM_INITDIALOG: return TRUE;
    case WM_COMMAND:
        if (LOWORD(wp) == IDOK)
            DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hDlg, (DLGPROC)AboutProc);
        return TRUE;
    case WM_CLOSE:
        DestroyWindow(hDlg);
        g_hDlg = NULL;
        return TRUE;
    }
    return FALSE;
}

BOOL CALLBACK AboutProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
{
    if (msg == WM_CLOSE) {
        EndDialog(hDlg, 0);
        return TRUE;
    }
    return FALSE;
}

呼叫端測試程式 (MFC Dialog Based)

  1. 新建 MFC AppWizard (exe) 專案 Use,Dialog Based
  2. 主對話框加按鈕,雙擊加入處理函數:
// UseDlg.cpp (呼叫端)
extern "C" __declspec(dllimport) void ShowDlg();
#pragma comment(lib, "Debug/UseDlg.lib")

void CUseDlg::OnButton1()
{
    ShowDlg(); // 呼叫 DLL 匯出函數
}
  1. 將 UseDlg.dll、UseDlg.lib 複製到 Use\Debug 目錄
  2. 編譯執行,點擊按鈕彈出非模態對話框,再點 OK 彈出模態 About 框

Win32 DLL 關鍵點總結

  • 資源編譯進 DLL 內部,載入時自動繫結到 DLL 模組實例 (g_hInst)
  • CreateDialog (非模態) / DialogBox (模態) 直接指定資源 ID
  • 回調函數處理訊息,**不需要 MFC 架構**,極輕量
  • 匯出函數使用 extern "C" __declspec(dllexport) 避免 C++ 名稱修飾

二、MFC DLL (Extension DLL / Regular DLL) 使用資源

因篇幅限制,此處略述核心差異:

類型資源載入方式典型用法
MFC Extension DLL共享主程式資源鏈,**直接使用資源 ID**擴充 MFC 類別庫、自訂控制項
MFC Regular DLL (共享 MFC DLL)AfxFindResourceHandle / AfxSetResourceHandle 切換模組狀態包含 MFC 對話框、視圖的功能模組
MFC Regular DLL (靜態連結 MFC)同 Regular DLL,但體積較大無 MFC DLL 部署環境時

MFC Regular DLL 切換資源句柄範例

// DLL 內部函數
void CMyDllClass::ShowMyDialog()
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState()); // 關鍵:切換到 DLL 模組狀態
    CMyDialog dlg;
    dlg.DoModal(); // 此處資源 ID 會從 DLL 而非 EXE 載入
}

AFX_MANAGE_STATE 宏自動保存/還原 AfxGetResourceHandle(),確保資源正確載入。

三、常見錯誤與避坑

錯誤現象原因解決
對話框不顯示/Assert 失敗資源句柄指向 EXE 而非 DLLWin32 DLL: 傳正確 hInst;MFC DLL: 加 AFX_MANAGE_STATE
找不到資源 ID資源未編譯進 DLL、或 ID 衝突檢查 .rc 檔是否加入專案、資源 ID 範圍避開系統保留值
模態對話框關閉後主視窗凍結父視窗傳遞錯誤 (NULL vs 實際 HWND)非模態用 NULL 或主視窗;模態用實際父視窗 HWND
DLL 卸載時崩潰非模態對話框未銷毀就 FreeLibrary提供 DLL 清理函數,應用程式退出前呼叫 DestroyWindow

選型建議

  • **純 C/API 風格、極致輕量、無 MFC 依賴** → Win32 DLL
  • **大量使用 MFC 類別、需共享 MFC 物件、團隊熟悉 MFC** → MFC Extension DLL
  • **封裝獨立 MFC 功能模組 (含對話框、文檔/視圖)、獨立部署** → MFC Regular DLL (共享 MFC DLL)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved