调用HHA_CompileHHP编译chm工程

编译chm工程(.hhp)有两种方法:

调用hhc.exe

调用HHA_CompileHHP

调用hhc.exe编译,代码如下:

// strChmFileName为你的hhp文件的长文件名
CString strCmdLine;
strCmdLine = "hhc.exe ";
strCmdLine += strChmFileName;
WinExec(strCmdLine, SW_SHOWNORMAL);

用这种方法调用有很多缺点,首先,没有编译进度,没有任何提示,根据我的测试,还不支持有空格的文件名。一般专业的chm制作软件都是调用的hha.dll中的HHA_CompileHHP函数进行编译。我们这里不讨论如何生成chm的工程文件,这个可以参考Html Help WorkShop生成的文件。调用HHA_CompileHHP,微软没有提供函数声明,也没有提供帮助信息。(据说要和微软签订协议,才可以拿到函数声明及相关的头文件)参考了网上一篇介绍用delphi实现函数调用的文章,加上我的一点试验,终于我VC实现了。ok,看看我是怎么实现的。

先说下HHA_CompileHHP的参数:

(const char*, LPVOID, LPVOID, int)

第一个参数为你要编译的hhp文件名

第二个参数是编译日志回调函数

第三个参数是编译进度回调函数

第四个参数不知道什么用,我把他置为0

开始写代码了

///////////////////////////////////
// 下面是两个回调函数的声明
BOOL CALLBACK FunLog(char* pstr);
BOOL CALLBACK FunProc(char* pstr);
//
// CompileHHP
// 调用HHA_CompileHHP编译chm工程
// 参数:pzFileName为待编译hhp文件名
// 作者:吴会然(wuhran@126.com)
// blog: http://blog.sina.com.cn/u/1272907062
////////////////////////////////////////////////////////////////////////////////////
void CCompileCHMDemoDlg::BuildChmFile(CString strHHPFile)
{
  HINSTANCE hinstLib;
  typedef BOOL (WINAPI *MYFUNC)(const char*, LPVOID, LPVOID, int);
  BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
  MYFUNC ProcAdd = NULL;

  // Get a handle to the DLL module.
  hinstLib = LoadLibrary("hha.dll");

  // If the handle is valid, try to get the function address.
  if (hinstLib != NULL)
  {
    ProcAdd = (MYFUNC) GetProcAddress(hinstLib, "HHA_CompileHHP");

    // If the function address is valid, call the function.
    LPCSTR pzFileNmae = strHHPFile.GetBuffer(strHHPFile.GetLength());
    if (fRunTimeLinkSuccess = (ProcAdd != NULL))
    {
      if(ProcAdd(pzFileNmae, FunLog, FunProc, 0))
      {
      }
    }

    // Free the DLL module.
    fFreeResult = FreeLibrary(hinstLib);
  }

  if(m_pStatusBar)
    m_pStatusBar->SetPaneText(0, "编译完成!");
  // If unable to call the DLL function, use an alternative.
  if (! fRunTimeLinkSuccess)
    printf("message via alternative method\n");

}
//////////////////////////////////////////////////////////////////////////////////////
// FunLog()
// 编译日志回调函数
// 参数:日志字符串
// 作者:吴会然(wuhran@126.com)
// blog: http://blog.sina.com.cn/u/1272907062
////////////////////////////////////////////////////////////////
BOOL FunLog(char* pstr)
{
  ASSERT(pstr);
  CString strMsg;
  strMsg.Format("%s", pstr);
  // AfxMessageBox(strMsg);

  return true;
}
//////////////////////////////////////////////////////////////
//
// FunProc()
// 编译进度回调函数
// 参数:进度字符串
// 作者:吴会然(wuhran@126.com)
// blog: http://blog.sina.com.cn/u/1272907062
//////////////////////////////////////////////////////////////
BOOL FunProc(char* pstr)
{
  ASSERT(pstr);
  CString strMsg;
  strMsg.Format("%s", pstr);

  // AfxMessageBox(strMsg);

  return true;
}

联系方式:

wuhran@126.com

http://blog.sina.com.cn/u/1272907062

上面的测试代码在VC6.0+WIN2003下编译通过,请确保你的系统目录或程序当前目录下存在hha.dll文件。

欢迎大家交流指正……

本文配套源码

时间: 2025-01-02 12:02:48

调用HHA_CompileHHP编译chm工程的相关文章

如何在一个VS的工程里面调用另外一个VS工程

问题描述 如何在一个VS的工程里面调用另外一个VS工程 我建立了两个VS工程,第一个工程要生成库文件给第二个工程调用,我想在第一个工程生成库文件后,就可以直接调用下一个工程,可以吗?应该怎样做了? 解决方案 在VS中新建一个解决方案,然后新建两个项目,一个是Windows应用程序,一个是dll类库,然后再在前一个项目中点项目-添加引用,选择第二个项目,即可. 解决方案二: 你把你两个工程置于同一个解决方案下! 打开一个工程的解决方案--右键菜单--Add--existing project 把另

动态调用dll-C#如何动态调用VB编译的dll里的函数

问题描述 C#如何动态调用VB编译的dll里的函数 有一个VB的工程项目,里面有很多类,每个类里都有相同的函数: 比如 a工程:类模块里有 b类,c类:而b类和c类都有相同的函数d: 我怎么在C#里动态调用b类的d函数呢? 因为是动态调用,所以不能是直接引用dll,再"对象名.函数名": DLLImport和反射都尝试过,关键是我要定位到某个类的那个函数,就不知道怎么弄,麻烦大神帮帮忙

pb程序里如何调用vs2012编译的dll ,该dll是封装的第三方的webservice

问题描述 pb程序里如何调用vs2012编译的dll ,该dll是封装的第三方的webservice 第三方给了一个webservice,我用vs的命令,编译成了dll,可惜pb程序里无法正常调用该dll 解决方案 .net的dll,需要包装成com对象,才能被pb调用,不是一般的dll.关于如何包装com组件,以及pb如何调用com组件,请google. 解决方案二: pb程序里如何调用vs2012编译的dll ,该dll是封装的第三方的webservice 第三方给了一个webservice

vfp-VFP如何调用C#编译的DLL

问题描述 VFP如何调用C#编译的DLL RT如题.譬如A.DLL,里面有个类名为Ainfo,类里的方法GetAinfo(参数1参数2).VFP怎么调用这方法,还有这DLL存放的位置有什么规则.请大神赐教 解决方案 http://download.csdn.net/download/net0118/3797783 解决方案二: C# Oracle VFP 调用dllC#调用C++DLL的方法

关于android 调用自己编译的su文件报错的问题

问题描述 关于android 调用自己编译的su文件报错的问题 百度加google,自己弄了一个zlsu执行文件,放到system/bin/目录下后,调用它的时候,报错: java.io.IOException: write failed: EPIPE (Broken pipe). 解决方案 su文件代码如下: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/type

使用Ant编译Hadoop工程报错

在win7用Ant编译hadoop工程的时候,遇到了一个报错,如下: org.eclipse.core.runtime.CoreException: D:\workspace\hadoop-1.1.2\build.xml:83: Execute failed: java.io.IOException: Cannot run program "sed" 打开build.xml文件,找到sed,然后把注释掉即可,这段内容是为了替换苹果系统的空格的,但是..Windows出错啦,也难怪,因为

java调用matlab编译打包出的jar文件调用randperm问题

问题描述 java调用matlab编译打包出的jar文件在matlab函数中调用了randperm但每次执行所产生的随机数都是一样的如何解决这个问题 解决方案

service-Android Service类中调用NDK编译的库的问题

问题描述 Android Service类中调用NDK编译的库的问题 现碰到的问题如下: 在Java层写了一个类代码如下: public?class?MeiaPush?{ ????????public?native?int?meia_push_init?(); ????????public?native?int?meia_push_set_client_info?(String?cid,?String?pwd,?String?type,?String?token); ????????public

missing-展讯平台编译整个工程出显了“Missing base address for region”错误

问题描述 展讯平台编译整个工程出显了"Missing base address for region"错误 哪位大神能帮一下忙啊!! 感谢了! 解决方案 SCF 文件的格式错误了,你是不是修改了 SCF 文件? 解决方案二: 没有修改,昨天把sc6531_scatter.scf 替换掉了,编译就能通过了, 但下面link还没有解决,那是一个生成文件,也是出现了同样的错误,请问这个需要怎么做啊! 解决方案三: 没有修改,昨天把sc6531_scatter.scf 替换掉了,编译就能通过了