hhc.exe?專業 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 可中斷編譯。
#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("編譯失敗,請查看日誌輸出。"));
}
HHA_CompileHHP 參數為 const char* (ANSI)。Unicode 專案 (VS2005+) **必須**用 CStringA / WideCharToMultiByte 轉換路徑,否則中文路徑會亂碼導致找不到檔案。hha.dll 依賴 msvcr71.dll 等 VC7.1 執行庫,目標機需安裝 HTML Help Workshop 或手動部署相關 DLL。PostMessage 發送自定義訊息到主執行緒更新介面。FALSE 僅表示啟動失敗或嚴重錯誤;詳細錯誤 (如標籤語法錯、檔案缺失) 只能從 LogCallback 解析。CChmCompiler 類,內含 CEvent 同步、CStringList 日誌緩衝。測試環境:VC6.0 + Win2003 + HTML Help Workshop 1.3。確保
hha.dll位於系統路徑 (通常C:\Program Files\HTML Help Workshop\) 或複製至專案輸出目錄。