1、课程设计CHM电子书生成软件制作实例CHM电子书生成软件制作实例CHM格式的电子书是网上用得比较多的一种,特别是计算机类的电子书几乎都用CHM格式。CHM格式的电子书简单易用,只要是Windows 98以上的操作系统都能直接使用,免去了安装阅读器的麻烦。同时CHM格式已经成为微软产品的标准帮助文件格式,而且不少基于Windows平台的软件也适用该格式作为其帮助文件的格式。所以,CHM格式已经相当普及。电子书有两个要素,第一点是电子书本身的格式,第二点就是电子书的阅读器。CHM格式的电子书也不例外。CHM格式其实是对 HTML文件打包并压缩的结果。CHM格式的创始者微软提供了一个将HTML文件编
2、译成CHM文件的免费软件hhc.exe,这样CHM的第一个要素就得到了解决。同时Windows 98以上的操作系统都提供了CHM文件的阅读软件hh.exe。hh.exe是Windows操作系统的一部分,这就是CHM格式的文件可以在Windows平台间流传而不需要专门阅读器的原因。既然微软提供了现成的编译器,那就从它入手来研究CHM生成软件的开发。首先,我们来看一下CHM文件有哪些元素。如图所示。图CHM文件的元素从上图可知,一个CHM文件需要标识三个部分:工具栏,控制面板,和文件显示。那么怎样才能在生成的CHM文件里表示这些元素呢?这就需要了解微软免费软件hhc.exe的用法了。hhc.exe
3、可以直接编译HTML或HTM格式的文件,但这样生成的CHM文件只有文件显示区,不能实现CHM文件的所有功能。hhc.exe更多的是编译扩展名为hhp的工程文件,该文件就是在总体上标识CHM文件的各元素的关键所在。同时配合扩展名为hhc的主体文件与扩展名为hhk的索引文件就能实现CHM文件的所有元素。下面将具体解析三种文件的格式。1)工程文件*.hhp。工程文件由OPTIONS,WINDOWS,FILES,INFOTYPES,MERGE FILES等几个部分组成。其中OPTIONS,WINDOWS和FILES三个部分是主要部分,其余部分一般不用,所以这里只讨论这三部分。 OPTIONSOPTIO
4、NS部分描述的是整个工程的宏观信息,它的格式比较固定,它是由许多选项组成的,一般组成如下:OPTIONSCompatibility=1.1 or laterCompiled file=D:MYCHMpptest.chmContents file=test.hhcDefault Window=mainDefault topic=D:MYCHMpp042.htmDefault font=幼圆,14,134面板的tag显示字体,大小,语种Display compile progress=NoBinary Index=Yes Binary TOC=YesEnhanced decompilation=Y
5、esFlat=YesFull-text search=YesIndex file=test.hhkLanguage=0x804 中文(中国)上面的每一项占据一行,等号左边是每一项的名称,等号右边是每一项的值。其中每一项的具体意义如下项目名称项目意义Compatibility版本的兼容性,一般为固定值 “1.1 or later”Compiled file编译后的文件名称及所在目录Contents file生成目录所用的目录文件的名称及所在目录Default Window描述CHM文件窗体样式的窗体文件名,在WINDOWS部分会用到。Default topicCHM文件启动时首页文件的名称及所在
6、目录Display compile progress是否显示编译进程Full-text search是否支持全文检索Index file生成索引所用的索引文件的名称及所在目录Default font控制面板中目录或索引显示的字体,大小及所用的字符集 Binary Index表示是否创建二进制索引Binary TOC表示是否创建二进制目录Enhanced decompilation表示是否支持增强反编译Flat“Yes”表示编译文件中不保存目录信息LanguageCHM文件所用的语言 WINDOWS WINDOWS部分描述的是CHM文件的窗体样式。这一部分是整个工程文件中最为繁琐也是最为关键的一
7、项,它决定了CHM文件是否能按照正常的方式显示。下面我们就来看看它的结构。WINDOWS部分由一个等式组成。等式的左边是窗体名称,即上面所提到的Default Window的值,等式的右边是由一长串用逗号隔开的值,具体样子如下:main = , , , , , ,0可见等式右边是由19个逗号隔开的20个参数。其中前九个参数比较简单其意义如下:参数位置参数意义1chm文件的标题。2目录文件的路径与名称。3索引文件的路径与名称。4CHM文件启动时首页文件的名称及所在目录5CHM文件主页文件的名称及所在目录6跳转按钮1对应的文件名及所在目录。7跳转按钮1的标题。8跳转按钮2对应的文件名及所在目录。9
8、跳转按钮2的标题。第十个参数表示的是chm控制面板的样式。下表中每一个选项对应一个值,如果要选择多个选项只要把它们对应的值相加再赋给参数就可以了,下面碰到的类似问题都这样解决。该参数的具体意义如下:面板选项意义对应值初值(表示具有“目录”与“搜索”两项)0x20添加搜索项0x400添加高级项0x20000添加书签项0x1000自动显示/隐藏面板0x1隐藏工具栏0x40记录位置和大小0x40000同步0x100第十一个参数表示面板宽度,用十进制数表示。第十二个参数表示工具栏按钮的定制具体意义如下:工具栏选项意义对应值初值0x0“隐藏/显示”按钮0x2“后退”按钮0x4“前进”按钮0x8“停止”按
9、钮0x10“刷新”按钮0x20“主页”按钮0x40“字体”按钮0x100000“打印”按钮0x2000“选项”按钮0x1000“定位”按钮0x800“自定义1”按钮0x40000“自定义2”按钮0x80000“”按钮第十三个参数表示窗体大小与位置,其具体的格式是:ddd1,ddd2,ddd3,ddd4。这四个参数都是十进制数字,并且宽度步超过3位。四个参数的具体意义如下:ddd1CHM文件左上角到桌面左边框的距离,单位为像素ddd2CHM文件左上角到桌面上边框的距离,单位为像素ddd3CHM文件右下角到桌面左边框的距离,单位为像素ddd4CHM文件右下角到桌面上边框的距离,单位为像素第十四个参
10、数表示窗体样式,具体意义如下:窗体样式意义对应值最小化按钮0x10000最大化按钮0x20000厚框架0x40000系统菜单0x80000水平滚动条0x100000垂直滚动条0x200000对话框框架0x400000边框宽度0x800000最大化0x1000000有子窗口0x2000000有同级窗口0x4000000失效0x8000000可视0x10000000最小化0x20000000子窗口(使弹出失效)0x40000000弹出(使子窗口失效)0x80000000迭交(使最小化有效)或空0x0第十五个参数表示窗体的扩展样式,具体意义如下:窗体扩展样式意义对应值不通知父母0x4始终最上0x8接
11、受文件0x10透明0x20工具窗口0x80客户区边框0x200上下文帮助0x400右对齐文本0x1000右到左阅读顺序0x2000左滚动条0x4000控制父窗口0x10000静态边框0x20000第十六个参数一般为空。第十七个参数指示打开时面板是否关闭,若值为1表示启动时面板关闭,否则值为空。第十八个参数表示启动时控制面板的默认面板。空值索引1第十九个参数表示控制面板上的各面板标题的位置在上边空值在左边0x1在下面0x2第二十个参数一般为0。 FILESFILES部分最为简单,其下列出了所要编译的全部文件名称及所在目录。2)目录文件*.hhc先来看一个目录文件的实例DELPHI基础教程-第十六
12、章 数据浏览部件的应用及编程(二)从上可以看出,目录文件与html文件十分相似,它其实就是一个对象列表文件。第一个对像是:其中参数Window Styles描述的是目录文件的目录树在显示时的样式。具体书值如下:参数值意义0x0无效果0x20显示选择0x200轨迹0x600效果0x1显示+-,+代表目录下有文件,-相反0x2显示虚线,(该选项使“行选”无效)0x4显示根0x400展开0x1000行选,(该选项使“显示虚线”无效)如果要修改目录文件显示的前景色,背景色,以及字体则要添加下面三个属性:同时还可以通过添加下面三个属性来指定自己的图标,图标宽度,图标背景色以代替系统图标。从第二个对象开始
13、,描述的是目录项所对应的文件。它一般有两个参数,PARAM NAME=Name 和PARAM NAME=Local。第一个参数对应目录的名称,第二个文件则对应所指向的文件路径。如果要定制目录树节点上的图表,则还要增加一个参数PARAM NAME= ImageNumber,它的值是从1到42的任意一个数字,每一个数字代表一种图标。将这些参数设置好之后,只要将所有的文件对象按照html语言的无序列标排列就形成了目录文件。3)索引文件*.hhk索引文件和目录文件的格式几乎一样,只是少了第一个对象,同时对象不支持参数PARAM NAME= ImageNumber。因为一般情况下索引文件没有对应的目录树
14、显示效果,并且索引的显示也不含图标。有了上面的知识基础,我们就可以来构建具体的编译软件了。由于Delphi在开发Windows程序时相当方便,所以我这里就用Delphi6.0作为软件开发工具。下面就来讲解软件的实现过程。工程文件,目录文件及索引文件的生要用到制作电子书所需的HTML文件,所以制作该软件时首先考虑从文件导入入手,即先把制作电子书的HTML文件导入,然后就可以在此基础上进行修改和编译了。1)导入HTML文件所谓的导入是把电子书的目录结构用程序获取,以便于以后生成目录及索引之用。在使用软件编译电子书时一般要求将所有要编译的文件放在同一目录下,以便于管理。我这里所制作的软件就有这个要求
15、。这样,程序就可以自动从文件夹中获取目录结构。我使用TreeView控件来存放目录结构,使用makeTree(curDir:string; topNod:tTreeNode; tree:tTreeView)过程来完成目录获取,具体的程序如下:procedure makeTree(curDir:string; topNod:tTreeNode; tree:tTreeView);var tmpDir:string; tmpNod:tTreeNode; sr:tSearchRec;begin tmpDir := curDir + ; tmpNod := topNod; if findFirst(tm
16、pDir+*.*, faAnyFile, sr) = 0 then begin repeat if (sr.name .) and (sr.name .) then begin tmpNod := tree.items.addchild(topNod, sr.name); if (sr.Attr and fadirectory) 0 then begin makeTree(tmpDir + sr.name, tmpNod, tree); end; end; until FindNext(sr) 0; findClose(sr); end;end;这一过程运行的结果就是将指定目录下的所有文件,子
17、文件夹及其中的文件的目录结构放到TreeView控件中。其中的每个节点的名称为文件或文件夹本身的名称,它是用sr.name来获取的。如果,有兴趣的话,可以不用sr.name,而是从网页中把之间的标题取出作为节点名称。这样,在生成目录文件及索引文件时所用的名称就是网页标题,这也是网上已有CHM生成软件的一贯做法。同时还可以修改findFirst及findNext函数的第一个参数以达到过滤文件的作用。有了目录树我们就可以来生成编译所需的三个文件了。2)工程文件的生成由上面的知识可知,工程文件主要是实现OPTIONS,WINDOWS和FILES三个部分,而OPTIONS,WINDOWS这两个部分只要
18、向用户提供可选的选项,根据用户的选择便可生成。具体实现可用复选框,文本框来收集输入信息,实现并不复杂,所以不再描述。工程文件中稍微复杂一点的就是FILES项。不过,有了目录树作为基础,便可从中获取文件信息了。我用writeHHP_FILES(topNode:tTreeNode; var f:text; topPath:string)这一过程来实现这一功能,具体代码如下procedure writeHHP_FILES(topNode:tTreeNode; var f:text; topPath:string);var i:integer;begin i := 0; while i topNode
19、.count do begin if topNodei.Count = 0 then begin writeln(f, topPath + + topNodei.text); end; if topNodei.Count 0 then begin writeHHP_FILES(topNodei, f, topPath + + topNodei.text); end; i := i + 1; end;end;需要注意的是,代码中topNodei.text表示的是节点的名称。由于makeTree(curDir:string; topNod:tTreeNode; tree:tTreeView)过程中
20、给节点命名时用的是文件或文件夹的名称,所以这里可以用topNodei.text直接生成路径。如果节点的名称不是文件或文件名,则在建立树型目录时,要把每一个文件的路径保存下来,代替这里的topNodei.text。一个可行的办法就是用tStringList对像,它可以按树型结构保存变量,至于具体实现这里不做讨论。工程文件完成后,让我们来完成目录文件的生成。3)目录文件的生成目录文件的生成可以分成三个部分,头部、中间部分与尾部。目录文件的头部首先是固定部分可以用下面的代码实现。HhcHead := ;Writeln(f, HhcHead);接下来头部的可变部分,即目录树对像。首先根据用户的选择确定
21、参数值,然后用writeln()函数写入文件。具体如下:writeln(f, ); writeln(f, ); writeln(f, ); writeln(f, ); writeln(f, ); writeln(f, ); writeln(f, );writeln(f, );writeln(f, );尾部也比较简单,可用HhcEnd表示,具体如下: HhcEnd := ; Writeln(f, HhcEnd);目录文件的中间部分比较复杂,它要实现的功能是把TreeView中的节点按照HTML语言中的无序列表列出,其实现的本质仍是遍历整个目录树。这里使用了 procedure writeList
22、(topNode:tTreeNode; var f:text; topPath:string);vari:integer;fPath:String;begini:=0;fPath := topPath + + topNodei.text;writeln(f,);while i topNode.count dobeginif topNodei.count = 0 thenbeginwriteln(f, );endelsebegin writeln(f, ); writeList(topNodei, f, fPath);end; i:=i+1;end;writeln(f,);end;这里要注意两个
23、问题,第一个问题在生成工程文件时已经介绍过,就是用topNodei.text来生成路径时有前提的。第二个问题就是在文件列表对像时,对象的参数不是一成不变的,可以根据用户的选择使用不同的参数。目录文件完成后就只剩索引文件了。4)索引文件的生成前面讲过,索引文件的结构与目录文件是一样的,所以只需把目录文件中索引文件不支持的部分去掉就是索引文件了。我们完全可以使用和目录文件一样的程序结构,只需修改两个部分即可。第一,将描述目录树的对象去掉。第二,将在写入文件列表对象时所使用的索引文件不支持的参数去掉。这样,生成的文件就是索引文件了。有了上面三个文件之后,可谓万事俱备只欠东风,只要调用hhc.exe就可以完成编译了。具体代码如下:WinExec(PCHAR(hhc.exe+fileName+.hhp),SW_SHOW);其中fileName为工程文件名称及所在目录。以上就是CHM电子书生成软件的构架与实现,上述的代码知识一个最简单的实现,要想做出功能强大的软件还有很多要做。不过万变不离其中,只要具有上面的知识就一定能做出你想要的CHM电子书生成软件。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1