http://www.blogcn.com/user8/flier_lu/index.html?id=1196784&run=.04005F8
Microsoft 提供的HTML Help Workshop只支持在GUI界面或者使用其自带的HCC.exe程序编译CHM项目文件(.hpp),并不直接提供API供第三方软件使用。而实际上其CHM项目编译器的HHA.DLL中提供了名为HHA_CompileHPP的导出函数,实现了对.hpp的CHM项目文件直接进行编译,并通过两个回调函数通知用户当前编译进度。
以下为引用:
BOOL WINAPI HHA_CompileHHP(PCSTR pszHhpFile, FARPROC pLogString, FARPROC pProgress);
参数pszHhpFile传入要编译的CHM项目工程文件文件(.hhp);pLogString和pProgress分别执行两个回调函数,向用户报告当前编译进度。
以下为引用:
typedef void (CALLBACK *LOGSTRINGPROCA)(PCSTR pszMsg);
typedef BOOL (CALLBACK *PROGRESSPROCA)(PCSTR pszFile);
使用时只需要载入动态链接库HHA.DLL,并通过函数名字(HHA_CompileHHP)或序号(0x13F)获得函数入口即可。
btw: CHM的文件格式好些也被搞定了,Code Project上有一个支持Pocket PC 2003的开源CHM阅读器。
下面HHA_CompileHHP的一个Delphi移值版本:
以下为引用:
unit ChmCompiler;interface
uses
Windows, SysUtils;type
TChmCompileFunc = function(pszHhpFile: PChar; pLogString: Pointer; pProgress: Pointer): Bool; stdcall;TLogMessageEvent = procedure(Msg: string) of object;
TProgressEvent = function(FileName: string): Boolean of object;TChmCompiler = class
private
FDll: HMODULE;
FProc: TChmCompileFunc;FOnLogMessage: TLogMessageEvent;
FOnProgress: TProgressEvent;
protected
constructor Create;
public
destructor Destroy; override;class function Default: TChmCompiler;
function Compile(FileName: TFileName): Boolean;
property OnLogMessage: TLogMessageEvent read FOnLogMessage write FOnLogMessage;
property OnProgress: TProgressEvent read FOnProgress write FOnProgress;
end;implementation
uses
ActiveX;var
GChmCompiler: TChmCompiler;procedure LogMessageFunc(pszMsg: PChar); stdcall;
begin
Assert(Assigned(GChmCompiler));if Assigned(GChmCompiler.OnLogMessage) then
GChmCompiler.OnLogMessage(pszMsg);
end;function ProgressFunc(pszFile: PChar): Bool; stdcall;
begin
Assert(Assigned(GChmCompiler));if Assigned(GChmCompiler.OnProgress) then
Result := GChmCompiler.OnProgress(pszFile)
else
Result := True;
end;{ TChmCompiler }
constructor TChmCompiler.Create;
begin
FDll := SafeLoadLibrary('HHA.DLL');if FDll = 0 then RaiseLastOSError;
FProc := TChmCompileFunc(GetProcAddress(FDll, 'HHA_CompileHHP'));
//FProc := TChmCompileFunc(GetProcAddress(FDll, PChar($13F)));if @FProc = nil then RaiseLastOSError;
CoInitialize(nil);
end;destructor TChmCompiler.Destroy;
begin
CoUninitialize();
FProc := nil;if FDll <> 0 then
Win32Check(FreeLibrary(FDll));inherited;
end;class function TChmCompiler.Default: TChmCompiler;
begin
if not Assigned(GChmCompiler) then
GChmCompiler := TChmCompiler.Create;Result := GChmCompiler;
end;function TChmCompiler.Compile(FileName: TFileName): Boolean;
var
szFileName: PChar;
LogMessageProc, ProgressProc, CompileProc: Pointer;
Ret: BOOL;
begin
szFileName := PChar(FileName);
LogMessageProc := @LogMessageFunc;
ProgressProc := @ProgressFunc;
CompileProc := @FProc;
asm
XOR EAX, EAX
PUSH EAX
MOV EAX, ProgressProc
MOV ECX, LogMessageProc
MOV EDX, szFileName;
PUSH EAX
PUSH ECX
PUSH EDX
CALL CompileProc
MOV Ret, EAX
end;
Result := Ret;
end;initialization
GChmCompiler := nil;finalization
if Assigned(GChmCompiler) then FreeAndNil(GChmCompiler);end.