HC31下Windows帮助文件窗口的中文标题的创建 1引言 随着Windows的普及,越来越多的中文软件选择中文Windows作为其开发平台,相应 制作一个完善的Windows中文帮助系统对于一个完整的软件十分必要。通常制作 Windows中文帮助文件可分为三个步骤:编写帮助主题文件.RTF、编写帮助项目工程 文件.HPJ、用Windows帮助编译器生成帮助文件.HLP。当今许多流行的编程语言如 VisualC++、Borland 、C++Dephi等)提供的Windows帮助编译器均是HC31,因此软件 开发人员大多选用HC31帮助编译器。但HC31在制作中文帮助时,却有一定缺陷。本 文将具体分析HC31的问题存在,并提出一种解决方案。 2问题的提出与分析 2.1问题提出 帮助文件编译器HC31完成帮助项目文件(HPJ文件)的编译(包括帮助主题文件-RTF文 件),最后生成可执行的Windows帮助文件(HLP文件)。对于RTF文件的中文内容, HC31能够进行正确的编译,但是在编译生成帮助文件的中文窗口标题时却出现了问 题。即HC31在对帮助项目文件中[OPTIONS]字段的TITLE的中文内容进行编译时出 了错。假设帮助的项目文件内容如下: [OPTIONS] TITLE=帮助 ;帮助文件窗口的中文标题(四个字节) CONTENTS=HID_CONTENTS COMPRESS=true WARNING=2 [FILES] HELP.RTF;帮助的主题文件 如编译正确,所生成帮助的窗口标题栏中将显示“帮助”两个字,而实际上标题栏 中显示的却是“赐”。经过实验,不仅仅是“帮助”两个汉字无法被HC31正确编译 入写入帮助的窗口标题栏,而是所有TITLE选项的汉字(也就是最高位为“1”的字 节)都是无法被HC31正确的编译。 2.2问题分析 如果把上面帮助项目文件中的“TITLE=帮助”改为“TITLE=HELP”,经HC31编译所 得的帮助文件的窗口标题正确。比较两者生成的帮助文件(笔者自编制的比较程序, 比较算法简单,在此省略),发现仅有四个字节不同,并且这四个字节在帮助文件中 的位置相同。这说明HC31在编译帮助项目文件中TITLE的汉字时,只是改变了汉字的 二进制码,并没有改变整个文件的结构格式和字节数。即HC31编译上面的帮助项目 文件后,生成的帮助窗口标题内容不是“帮助”而是“赐”。是因为HC31在编译过 程中把“帮助”的二进制码“0xBoEF ”(显示为“帮助”)改为“0xD6FA”(显示为 “赐”),文件字节数并没有发生改变。 3问题的解决 3.1解决问题的原理 由上面的分析可知,HC31对中文窗口标题编译出错,只是改变了窗口标题汉字的二 进制码的大小,没有改变窗口标题的字节数以及整个文件的结构格式。因此,最简 单的解决方法是直接修改帮助文件中的被错误编译的窗口标题。这种方法的两个关 键技术的“定位”和“改错”。“定位”——定位窗口标题在帮助文件中的起始位 置;“改错”——在帮助文件的窗口标题位置写入正确的标题内容,并且不改变帮 助文件的结构格式。显然,如果已知Windows的帮助文件格式,实现“定位”与“改 错”是极为容易的。但要弄清楚帮助文件的格式,工作量太大,显得不实际。在 此,作者采用了一种简单的定位窗口标题的方法,即在帮助项目文件中用“特殊” 字符设置TITLE的内容,这里的“特殊”字符是指在帮助主题文件(.RTF)中不会出现 这些字符,并且HC31对它们编译不会出错。这样,用户就可以在编译生成的帮助文 件中搜索出窗口标题的位置,从而实现“定位”。实现“改错”的关键技术在于必 须“改错”的过程中,不改变帮助文件的结构格式。这就要求正确窗口标题内容的 字节数必须和帮助项目文件中TITLE内容的字节数相同,如果前后不一致,将会破坏 原有的帮助文件格式,Windows帮助系统将不能识别该帮助文件。 3.2窗口中文标题的具体实现 根据上述“定位”与“改错”原理,具体实现在使用HC31编译器条件下创建Windows 帮助文件的中文窗口标题分为三个步骤: 1)在帮助项目工程文件中的TITLE字段写入具有与将写入的中文标题内容的字节数相 同的“特殊”字符。为满足用户在不能确定中文标题内容的情况下使用本工具的需 要,笔者采用了如下TITLE内容: [OPTIONS] TITLE=@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@;帮助文件窗口的 “特殊”标题(50个字节) CONTENTS=HID_CONTENTS COMPRESS=true WARNING=2 [FILES] HELP.RTF ;帮助的主题文件 由于HC31限制了TITLE内容的最大字节数是50,因此作者使用50个“特殊”字符,如 果帮助文件窗口的中文标题内容字节数不足50个字节,在“改错”步骤中将用空格 补足50个字节,这样既没有改变帮助文件的格式和字节数又确保了在帮助主题文件 HELP.RTF中不会有与TITLE相同的内容。 2)用HC31编译该帮助项目工程文件,生成需要被改错的帮助文件。 3)编程(本文采用Visual c++)实现窗口标题的定位与标题内容的写入。首先利用 Visual c++的Appwizard自动生成一个Windows单文档应用程序的函数框架源程序, 然后在生成的主窗口菜单条中设两个主要命令:“文件打开…”与“写中文标题 ……”。“文件打开……”命令是弹出“文件打开”对话框提供用户选择需要改错 的Windows帮助文件;“写中文标题…”命令是弹出一个对话框,提示用户在对话框 中输入将要写入的窗口中文标题内容,确认此操作后,接着会再弹出一对话框需用 户确定改错后的帮助文件名,最后完成中文标题写入的算法(包括“定位”与“改 错”)。其中“文件打开…”命令执行源程序已由Appwizard自动生成,本文在这不 详述。而“写中文标题…”命令的执行源程序是需要笔者自行编制的,它包括两个 对话框类及其函数与一个主函数下面列出这段源程序: /*获得用户输入的窗口中文标题的内容对话框类*/ class GetTitleDlg:public CDialog { public: GetTitleDlg():CDialog("TITLEDLG"){} ptotected: virtual void OnOK(); virtual BOOL OnInitDialog()//;初始化对话框类 } BOOL GetTitleDlg::OnInitDialog()//初始化对话框类 { /*HC31限制TITLE内容的最大字节数为50*/ SendDlgitemMessage(IDC_EDIT1,EM_LIMITTEXT,50,NULL);// return CDialog::OninitDialog(); } void GetTitleDlg::OnOK() { GetDlgitemText(IDC_EDIT1,TitleName,50);//获得用户输入的窗口中文标题的内容 EndDialog(1); } /*确定改错后的帮助文件名的对话框类*/ class SetFileNameDlg:public CFileDialog { public: SetFileNameDlg():CFileDialog(FALSE,"*.dat",NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"数据文件(*.HLP) |*.HLP|所有文件(*.*)|*.*||",NULL){} virtual BOOL OnInitDialog();//初始化对话框函数 }; BOOL SetFileNameDlg::OninitDialog()//初始化对话框函数 { SetWindowText("输出的帮助文件名设定"); SetDlgItemText(IDOK,"确定"); SetDlgItemText(IDCANCEL,"取消"); SetDlgItemText(1090,"文件名:"); SetDlgItemText(1091,"驱动器:"); SetDlgItemText(-1,"路径:"); SetDlgItemText(1089,"文件类型:"); return CDialog::OnInitDialog():+ }+ /*主函数实现“定位”与“改错”*/ void CMainFrame::SetTitle()//假设主窗口函数类名是CMainFrame { int i=0,j; char ch[60] GetTitleDlg dlg; SetFileNameDlg dlg1; BOOL a=0,b=0; a=dlg.DoModal();//弹出获得用户输入的窗口中文标题的内容对话框 if(a==1) b=dlg1.DoModal();//弹出确定改错后的帮助文件名的对话框 if((a==1)&&(b==1)){ OutFileName=dlg1.GetPathName();//得到用户确定改错后的帮助文件名 if(lstrcmpi(FileName,OutFileName)==0){//判断两帮助文件名是否相同 MessageBox("输出的帮助文件名不能与原帮助文件名相同!","出错信息",,MB_OK|MB_ICONEXCLAMATION); return; } CDC*pDC=GetDC(); pDC_>SetTextColor(RGB(255,0,0)); pDC_>TextOut(100,180,"正在写中文帮助题头,请稍等…",29); //打开将要改错的帮助文件,变量FileName来自“文件打开…” CFile*Helphpj=new CFile(); xx->Open(FileName,CFile::modeReadWrite,NULL); //创建改错后的帮助文件 CFile*xx=new CFile(); xx->Open(OutFileName,CFile::modeCreate|CFile::modeWrite,NULL); ch[52]='\0'; for(;;){ j=Helphpj->Read(ch,3);//从被改错文件中读取3个字节 if(j<3){ xx->Write(ch,j);//写字节 break;//退出 } if((ch[2]=='@')&&(i==0)) Helphpj->Read(ch+3,49); if(lstrcmp(ch+3,"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")==0{//判断是 否是窗口标题位置 xx->Write(ch,2); xx->Write(TitleName,lstrlen(TitleName));//写窗口标题内容 for(i=0;i<50-lstrlen(TitleName);i++) xx->Write("",1);//补空格 } else{ xx->Write(ch.1); Hekphpj->Seep(-51,CFile::current);//重新定位 } } else{ xx->Write(ch,1); Hekphpj->Seek(-2,CFile::current); } } Helphpj->Close();//关闭打开的被改错的帮助文件 xx->Close;//关闭改错后的帮助文件 delete xx; delete Helphpj; pDC->SetTextColor(RGB(255,0,0)); pDC->TestOut(100,180,"中文帮助题头写完!",56); ReleaseDC(pDC): } } 4.结束语 本文提出了一种依据“定位”与“改错”原理实现在HC31(帮助编译器)环境下生成 具有中文窗口标题的Windows帮助的方法。这种方法不需知道Windows帮助的格式, 因此易于实现。依此原理也可利用其它工具软件(比如PCTOOLS等)手工完成中文标题 的创建。