且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题

更新时间:2022-05-19 18:46:56

最近升级了一下doxygen到最新版1.5.6,结果发现生成的chm文件导航栏中文会出现乱码,折腾了一天,终于查明原因并解决,特此分享给大家。

原因:
doxygen 1.5.6版(不知道从哪个版本开始的)内部一律使用UTF-8编码,生成的index.hhc文件也是使用UTF-8编码,然而微软的hhc编译工具不支持UTF-8编码,结果导致编译出的chm文件正文部分中文一切正常,但导航栏全是乱码。从网上搜了一圈,好像大家基本都遇到了这一情况,解决办法各异。

解决办法:
解决办法的核心就是将index.hhc文件用编码转换工具(例如iconv,ultraedit等)转换成GBK,再用hhc编译即可。

由于doxygen会生成index.hhc之后直接自动调用hhc进行编译,中间并未留有供我进行转换的机会,而我又不想在doxygen运行完毕生成了chm文件之后再重新修改index.hhc文件(自动或手动),然后再次重新生成chm文件,没办法,只有修改doxygen的源码重新编译了。


修改过程:
首先下载源码并编译doxygen,注意一定要先阅读编译指南,我就是没看编译指南导致走了不少弯路,因为doxygen编译过程中要用到UnxUtil工具,需要下载并装好。

编译通过后,找到生成index.hhc文件的源代码文件HtmlHelp.h/HtmlHelp.cpp,进行修改。修改思路为:
在保存index.hhc文件之前先进行编码转换,直接转换到GBK编码在存储,这样就可以直接生成GBK编码的index.hhc文件,后续过程就水到渠成了。

相关代码:
HtmlHelp.h
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题class HtmlHelp  : public IndexIntf
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题
{
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  
private:
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题    QFile 
*cf,*kf; 
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题    QBuffer 
*cb;        // Added by zwjia
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题
    QTextStream cts,kts;
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题}
;


HtmlHelp.cpp
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题void HtmlHelp::initialize()
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题{
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  const char *str = Config_getString("CHM_INDEX_ENCODING");
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  if(!str) str = "Windows-1250";
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  m_fromUtf8 = portable_iconv_open(str,"UTF-8"); 
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  /* open the contents file&nb
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题sp;
*/

彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  QCString fName = Config_getString("HTML_OUTPUT") + "/index.hhc";
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  cf = new QFile(fName);
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  if (!cf->open(IO_WriteOnly))
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  {
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题    err("Could not open file %s for writing\n",fName.data());
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题    exit(1);
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  }

彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  cb = new QBuffer();       // Added by zwjia
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题
  cb->open(IO_WriteOnly);   // Added by zwjia
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题
  /* Write the header of the contents file */
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  cts.setDevice(cb);
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  cts.setEncoding(QTextStream::Latin1);
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题}

彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题void HtmlHelp::finalize()
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题{
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  // end the contents file
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题
  cts << "</UL>\n";
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  cts << "</BODY>\n";
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  cts << "</HTML>\n";
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  cts.unsetDevice();
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  ////////////////////////////////////////
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题
////////

彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  // Modified by zwjia
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题
  QByteArray buf = cb->buffer();
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  void* handle = portable_iconv_open("GBK","UTF-8");
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  size_t inputsize = buf.size();
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  size_t outputsize = inputsize*4+1;
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  charin = buf.data();
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  QByteArray outbuf;
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  outbuf.resize(outputsize);
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  charout = outbuf.data();
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  size_t len = portable_iconv(handle,(const char **)&in,&inputsize, &out, &outputsize );
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  outbuf.resize(out-outbuf.data());
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  cf->writeBlock(outbuf);
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  cf->close();
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  delete cf;
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  delete cb;
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  portable_iconv_close(handle);
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  // Modified by zwjia --end
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题
  //////////////////////////////////////////////////////////////
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题  彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题
彻底解决使用Doxygen 1.5.6自动生成的chm文件导航栏中文乱码问题}

重新编译后,大功告成!
本想顺便把编译后的exe作为附件贴在这里供大家直接使用,却没找到贴附件的地方...