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

調用 HHA_CompileHHP 編譯 CHM 專案:告別 hhc.exe 命令行的局限

     編輯:關於VC++

為什麼不用 hhc.exe?

  • 無編譯進度回饋。
  • 無錯誤/警告即時日誌。
  • 不支援含空格路徑 (需手動加引號處理)。
  • 進程獨立,難以整合至 IDE/建構腳本。

專業 CHM 工具 (如 HTML Help Workshop 自身) 均調用 hha.dll 導出函數 HHA_CompileHHP。

HHA_CompileHHP 函數簽名 (逆向推導)


BOOL WINAPI HHA_CompileHHP(
    const char* pszHHPFile,  // .hhp 專案檔完整路徑
    LPVOID pfnLogCallback,   // 日誌回調: BOOL CALLBACK FunLog(char* pszMsg)
    LPVOID pfnProgressCallback, // 進度回調: BOOL CALLBACK FunProc(char* pszMsg)
    int reserved             // 保留,置 0
);

回調返回 TRUE 繼續,FALSE 可中斷編譯。

VC++ 動態載入與調用完整實作


#include 
#include 

// 回調函數定義 (需 __stdcall / CALLBACK)
BOOL CALLBACK CompileLogCallback(char* pszMsg)
{
    // 將 pszMsg 顯示到 UI 列表框、輸出視窗或寫入檔案
    // 範例: m_listLog.AddString(CString(pszMsg));
    return TRUE; // 繼續編譯
}

BOOL CALLBACK CompileProgressCallback(char* pszMsg)
{
    // 解析進度資訊 (如 "Compiling topic 12/100...") 更新進度條
    // 範例: m_progress.SetPos(ParsePercent(pszMsg));
    return TRUE;
}

void CMyClass::BuildChmFile(const CString& strHHPPath)
{
    // 1. 載入 hha.dll (系統目錄或應用目錄需存在)
    HMODULE hMod = LoadLibrary(_T("hha.dll"));
    if (!hMod) {
        AfxMessageBox(_T("找不到 hha.dll,請安裝 HTML Help Workshop 或複製 DLL 至系統目錄。"));
        return;
    }

    // 2. 獲取函數位址
    typedef BOOL (WINAPI *PFN_COMPILE)(const char*, LPVOID, LPVOID, int);
    PFN_COMPILE pfnCompile = (PFN_COMPILE)GetProcAddress(hMod, "HHA_CompileHHP");
    if (!pfnCompile) {
        FreeLibrary(hMod);
        AfxMessageBox(_T("hha.dll 中未找到 HHA_CompileHHP,版本可能不符。"));
        return;
    }

    // 3. 呼叫編譯 (注意: 參數為 const char*,ANSI 路徑)
    // Unicode 專案需轉換: CStringA strAnsi(strHHPPath);
    CStringA strAnsiPath(strHHPPath); // ATL/MFC 轉換宏
    BOOL bResult = pfnCompile(strAnsiPath, CompileLogCallback, CompileProgressCallback, 0);

    // 4. 釋放資源
    FreeLibrary(hMod);

    if (bResult)
        AfxMessageBox(_T("CHM 編譯成功完成!"));
    else
        AfxMessageBox(_T("編譯失敗,請查看日誌輸出。"));
}

關鍵技術細節

  1. 字元集轉換:HHA_CompileHHP 參數為 const char* (ANSI)。Unicode 專案 (VS2005+) **必須**用 CStringA / WideCharToMultiByte 轉換路徑,否則中文路徑會亂碼導致找不到檔案。
  2. DLL 依賴:hha.dll 依賴 msvcr71.dll 等 VC7.1 執行庫,目標機需安裝 HTML Help Workshop 或手動部署相關 DLL。
  3. 回調執行緒:回調在編譯執行緒中被呼叫,**不可**直接操作 UI 控制項。需用 PostMessage 發送自定義訊息到主執行緒更新介面。
  4. 錯誤處理:返回 FALSE 僅表示啟動失敗或嚴重錯誤;詳細錯誤 (如標籤語法錯、檔案缺失) 只能從 LogCallback 解析。

進階整合建議

  • 封裝為 CChmCompiler 類,內含 CEvent 同步、CStringList 日誌緩衝。
  • 專案建構事件 (Pre/Post Build Event) 中調用編譯器可實現「原始碼修改 → 自動重編 CHM → 整合 MSDN」全自動流程。
  • 結合 MSDN 整合指南,打造文檔持續交付管線。

測試環境:VC6.0 + Win2003 + HTML Help Workshop 1.3。確保 hha.dll 位於系統路徑 (通常 C:\Program Files\HTML Help Workshop\) 或複製至專案輸出目錄。

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