副标题#e#
本文主要讲授如安在C++Builder6.0及之前的版本中利用Microsoft的新型辅佐:"CHM名目辅佐文件",对付如何建造CHM名目辅佐,以及如何获取辅佐文件建造东西,本文只会一笔带过,给出官方链接或推荐其它这方面好的教程,就不再赘述。
CHM名目辅佐文件建造东西
需要Microsoft的html help workshop来建造CHM名目标辅佐,可以到Microsoft站点下载:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/htmlhelp/html/hwMicrosoftHTMLHelpDownloads.asp
好的CHM辅佐建造教程
进修如何建造CHM名目辅佐文档,请参考:
Html Help Sample in Delphi[卡夫].chm 作者:卡夫[[email protected]]
跟我学HtmlHelp Workshop[冯惠军][石家庄铁道学院].chm 作者:冯惠军[石家庄铁道学院]
假如想相识更多关于Microsoft Html Help的常识,可以查阅:
Microsoft Html Help Docs.zipMicrosoft官方文档
更好的是直接在线查阅Microsoft的官方文档,到MSDN搜索要害字:"html help",可以搜索到许多关于Microsoft html help的内容,有最新的html workshop下载、在线API手册、建造辅佐文件示例等等。
到这里,我假设读者已经安装了Microsoft html help workshop,且已把握如何建造CHM名目辅佐文件。
本文中措施中挪用的示例辅佐文件包括四个主题,这四个主题的源代码如下:
1001.htm
<html>
<head>
<title>第一个主题</title>
</head>
<body>
<p>第一个主题</p>
</body>
</html>
1002.htm
<html>
<head>
<title>第二个主题</title>
</head>
<body>
<p>第二个主题</p>
</body>
</html>
1003.htm
<html>
<head>
<title>第三个主题</title>
</head>
<body>
<p>第三个主题</p>
</body>
</html>
1004.htm
<html>
<head>
<title>第四个主题</title>
</head>
<body>
<p>第四个主题</p>
</body>
</html>
#p#副标题#e#
添加索引“第一个主题”、“第二个主题”、“第三个主题”、“第四个主题”,添加搜索要害定“第一个主题”、“第二个主题”、“第三个主题”、“第四个主题”,建造好CHM辅佐文件。下一步的事情,是添加此辅佐文件对措施UI界面的上下文敏感干系。要领如下:
用文本编辑器写一个.h文件(头文件,CHM编译器需要用它),文件名任意,内容如下:
#define 第一个主题 1001
#define 第二个主题 1002
#define 第三个主题 1003
#define 第四个主题 1004
即把主题“第一个主题”界说为一个数字1001…,向CHM工程文件中添加这个.h文件,要领如下:
(1).打开HTML HELP WorkShop,打开适才这个CHM工程,在Project页面上左侧,点击第四个按钮“HtmlHelp API information”,在弹出的界面上点击“Alias”,添加主主题的别名,添加“第一个主题”对应html文件1001.htm…;
(2).在适才的“HtmlHelp API Information”弹出界面上点击“Map”,点击右侧第一个按钮“Head Files”,选择“include”适才建造的谁人.h文件
(3).从头编译CHM工程,生成的文件就是满意要求的有上下文敏感干系的CHM辅佐文件了。
测试一下您的CHM名目辅佐文件是否正确,点击HTML HELP WorkShop的“Text”->“HTMLHelp API”,在弹出的界面上,欣赏适才生成的CHM文件,“Command”选择“HH_HELP_CONTEXT”,第二个参数“Window”默认,第三个参数“Map Numbers”,输入谁人.h文件中界说的数字,点击确定,就会打开这个CHM文件并激活相关的主题了。
到这为止,已经乐成了一半,我们已经用HTML HELP WorkShop建造出了上下文敏感的CHM名目辅佐,下一步的重点是在C++Builder和Delphi中来挪用这个上下文敏感的CHM辅佐文件。
早期的Windows中,Microsoft 为其设计了一套API,用于Windows Help系统,一直到Windows XP SP2仍然保存这套API,它的问题是,只能表示文字等简朴内容,不能象HTML而那样表示富厚的内容。因此,Microsoft在1998年推出了全新一代的辅佐系统:Compiled Help Manual,将HTML文件编译和压缩,提供了WEB页一样的富厚的表示力,遏制了对旧的Windows Help的开拓。
Borland C++ Builder 6.0/Delphi7.0及之间的版本的用户手册等资源都是旧的Windows Help的,而VCL也只提供了对旧的Windows Help的支持,在当今WEB风行的本日,假如你的软件还用旧的Windows Help,未免有些老土吧!
我搜索了大量的网络资源并在季老大的辅佐下,完美办理了在C++Builder6.0/Delphi7.0及以前版本中利用上下文敏感的CHM名目辅佐的要领。
#p#分页标题#e#
VCL默认支持旧的上下文敏感的Windows Help,通过配置控件的HelpContext值来指定与控件相关的辅佐主题,假如Application收到WM_HELP动静,就会理会WM_HELP动静中的HelpContext,挪用Windows Help,显示相关的主题,因此,挪用CHM名目辅佐时,我们也需要配置相应控件的HelpContext(值就是上面界说的.h文件中的与主题相关的数值),我们需要截获发到措施中的WM_HELP动静,阐明HelpContext,并挪用我们本身建造的CHM辅佐,一切就完成了。可是事实却没有这么简朴。
(1).HTML Help的API都封装在hhctrl.ocx库中(Windows 98及今后的Windows系统安装这一个库),因此,我们利用Borland开拓东西中的导入东西implib.exe即可以导入这个库的静态版本:implib hhctrl.lib hhctrl.dll,把这个静态库添加到我们的工程中,在我们的措施中添加htmlhelp.h头文件(Borland开拓东西已包括这个头文件),即可以挪用HELP Help的API了;
(2).VCL构架的应用措施在以下三种方法中收到WM_HELP动静:在主菜单及其菜单项上按F1、在窗体元素上按F1、在弹出的PopupMenu上按F1,第一种和第二种环境下的动静很容易截取,可是第三种环境却较量非凡,VCL对PopupMenu动静的处理惩罚较量非凡,它封装了一个不行见的窗体PopupList->Window来统一打点弹出菜单的动静,十分谢谢季老大,我才截取了第三种方法的WM_HELP动静。
实现的细节如下:
在上述的第一种和第二种方法的WM_HELP动静来历,只要自界说一个WM_HELP动静处理惩罚句柄即可,然后按照菜单动静照旧其它控件动静来分隔处理惩罚;
对付上述第三种WM_HELP动静来历,需要在措施运行时重设PopupList->Window的窗体函数,并在措施退出还原,然后在本身界说的这个窗体函数中处理惩罚WM_HELP动静。
说再多也没有代码有说服力,我实现的代码如下:
MainFormUnit.h
//---------------------------------------------------------------------------
// 作者:yifei
// 日期:2005-08-31
//---------------------------------------------------------------------------
#ifndef MainFormUnitH
#define MainFormUnitH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Menus.hpp>
#include <ActnList.hpp>
#include <DBGrids.hpp>
#include <ExtCtrls.hpp>
#include <Grids.hpp>
#include <AppEvnts.hpp>
#include <ComCtrls.hpp>
#include <ImgList.hpp>
#include <ToolWin.hpp>
//---------------------------------------------------------------------------
class TMainForm : public TForm
{
__published: // IDE-managed Components
TMainMenu *MMenu;
TMenuItem *F1;
TMenuItem *cdefg1;
TPopupMenu *PPMenu;
TActionList *AList;
TAction *ActionNew;
TAction *ActionOpen;
TAction *ActionClose;
TAction *ActionHelp;
TMenuItem *O1;
TMenuItem *X1;
TMenuItem *H1;
TMenuItem *C1;
TButton *Button1;
TEdit *Edit1;
TButton *Button2;
TComboBox *ComboBox1;
TMenuItem *N1;
TMenuItem *O2;
TMenuItem *X2;
TMenuItem *N2;
TMenuItem *C2;
TLabel *Label1;
TLabel *Label2;
TCheckBox *CheckBox1;
TMenuItem *N3;
TImageList *ImageList;
TToolBar *ToolBar1;
TToolButton *ToolButton1;
TToolButton *ToolButton2;
TToolButton *ToolButton3;
TToolButton *ToolButton4;
TToolButton *ToolButton5;
TToolButton *ToolButton6;
void __fastcall ActionNewExecute(TObject *Sender);
void __fastcall ActionOpenExecute(TObject *Sender);
void __fastcall ActionCloseExecute(TObject *Sender);
void __fastcall ActionHelpExecute(TObject *Sender);
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
void __fastcall FormCreate(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TMainForm(TComponent* Owner);
protected:
// 打消编译器内联优化,制止编译器告诫
#pragma option push -vi-
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_HELP, Messages::TMessage, MyHelp)
END_MESSAGE_MAP(TForm)
#pragma option pop
// 自界说的WM_HELP动静处理惩罚句柄
void __fastcall MyHelp(Messages::TMessage &Message);
};
//---------------------------------------------------------------------------
extern PACKAGE TMainForm *MainForm;
//---------------------------------------------------------------------------
#endif
MainFormUnit.cpp
//---------------------------------------------------------------------------
// 作者:yifei
// 日期:2005-08-31
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "htmlhelp.h"
#include "MainFormUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;
static FARPROC OldMenuProc = NULL; // 生存旧的弹出菜单处理惩罚函数
// NewMenuProc 为新的动静处理惩罚函数--新的PopupList->Window的窗体函数
static long CALLBACK NewMenuProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::MyHelp(Messages::TMessage &Message)
{
HELPINFO *HI = (HELPINFO*)Message.LParam;
TWinControl *WC;
TMenuItem *MI;
TMenu *Menu;
// 主菜单上传来的WM_HELP动静
if(HI->iContextType == HELPINFO_MENUITEM)
{
for(int i=0; i<this->ComponentCount; i++)
{
Menu = dynamic_cast<TMenu *>(this->Components[i]);
if(Menu != NULL)
{
MI = Menu->FindItem(HI->iCtrlId, fkCommand);
if(MI != NULL)
{
break;
}
}
}
if(MI != NULL && MI->HelpContext != 0)
{
HtmlHelp(this->Handle, Application->HelpFile.c_str(), HH_HELP_CONTEXT, MI->HelpContext);
}
else
{
HtmlHelp(this->Handle, Application->HelpFile.c_str(), HH_DISPLAY_TOPIC, 0);
}
}
// 勾当控件上传来的WM_HELP动静
else
{
WC = FindControl(HI->hItemHandle);
if(WC != NULL && WC->HelpContext != 0)
{
HtmlHelp(this->Handle, Application->HelpFile.c_str(), HH_HELP_CONTEXT, WC->HelpContext);
}
else
{
HtmlHelp(this->Handle, Application->HelpFile.c_str(), HH_DISPLAY_TOPIC, 0);
}
}
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ActionCloseExecute(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ActionHelpExecute(TObject *Sender)
{
HtmlHelp(this->Handle, Application->HelpFile.c_str(), HH_DISPLAY_TOPIC, 0);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)
{
// 还原 PopupList 的动静处理惩罚函数,必需要还原,不然会有问题
::SetWindowLong(PopupList->Window, GWL_WNDPROC, (long)OldMenuProc);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormCreate(TObject *Sender)
{
// 变动 PopupList 的动静处理惩罚函数并生存旧的PopupList的动静处理惩罚函数
OldMenuProc = (FARPROC)::SetWindowLong(PopupList->Window, GWL_WNDPROC, (long)NewMenuProc);
}
static long CALLBACK NewMenuProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int n;
int ContextID;
TMenu* PopMenu;
TMenuItem* MenuItem;
// 假如动静不是WM_HELP,直接利用CallWindowProc 这个API把动静通报到旧的动静处理惩罚函数中处理惩罚
if(uMsg != WM_HELP)
return ::CallWindowProc(OldMenuProc, hwnd, uMsg, wParam, lParam);
HELPINFO* phi = (HELPINFO*)lParam;
for(n=0; n<PopupList->Count; n++)
{
PopMenu = (TMenu *)PopupList->Items[n];
if (phi->hItemHandle == PopMenu->Handle)
MenuItem = PopMenu->Items; // 无SubMenu环境
else
MenuItem = ((TPopupMenu*)PopMenu)->FindItem(
(int)phi->hItemHandle, fkHandle); // 有SubMenu的环境
if(MenuItem != NULL)
{
ContextID = PopMenu->GetHelpContext(phi->iCtrlId, true); // iCtrlId生存TMenuItem的Command
if(ContextID == 0)
ContextID = PopMenu->GetHelpContext((int)phi->hItemHandle, false);
if(Screen->ActiveForm==NULL)
break;
if(ContextID == 0)
ContextID = Screen->ActiveForm->HelpContext;
// 这儿弹出 ContextID 的辅佐信息
if(ContextID != 0)
{
HtmlHelp(hwnd, Application->HelpFile.c_str(), HH_HELP_CONTEXT, ContextID);
}
else
{
HtmlHelp(hwnd, Application->HelpFile.c_str(), HH_DISPLAY_TOPIC, 0);
}
break;
}
}
return TRUE;
}