此说明介绍了在 MFC 中分配帮助上下文 ID 和其他帮助问题的规则。 上下文相关的帮助支持需要 Visual C++ 中提供的帮助编译器。
注释
除了使用 WinHelp 实现上下文相关的帮助之外,MFC 还支持使用 HTML 帮助。 有关此支持和 HTML 帮助编程的详细信息,请参阅 HTML 帮助:Context-Sensitive 程序帮助。
支持的帮助类型
Windows 应用程序中实现了两种类型的上下文相关帮助。 第一个,称为“F1 帮助”,涉及使用基于当前活动对象的相应上下文启动 WinHelp。 第二种是“Shift+ F1”模式。 在此模式下,鼠标光标更改为帮助光标,用户继续单击对象。 此时,将启动 WinHelp,为用户单击的对象提供帮助。
Microsoft基础类实现这两种形式的帮助。 此外,框架还支持两个简单的帮助命令:帮助索引和使用帮助。
帮助文件
Microsoft基础类假定单个帮助文件。 该帮助文件必须与应用程序具有相同的名称和路径。 例如,如果可执行文件 C:\MyApplication\MyHelp.exe 帮助文件必须是 C:\MyApplication\MyHelp.hlp。 通过 CWinApp 类的m_pszHelpFilePath成员变量设置路径。
帮助上下文范围
MFC 的默认实现要求程序遵循有关帮助上下文 ID 分配的一些规则。 这些规则是分配给特定控件的一系列 ID。 可以通过提供各种与帮助相关的成员函数的不同实现来替代这些规则。
0x00000000 - 0x0000FFFF : user defined
0x00010000 - 0x0001FFFF : commands (menus/command buttons)
0x00010000 + ID_
(note: 0x18000-> 0x1FFFF is the practical range since command IDs are>=0x8000)
0x00020000 - 0x0002FFFF : windows and dialogs
0x00020000 + IDR_
(note: 0x20000-> 0x27FFF is the practical range since IDRs are <= 0x7FFF)
0x00030000 - 0x0003FFFF : error messages (based on error string ID)
0x00030000 + IDP_
0x00040000 - 0x0004FFFF : special purpose (non-client areas)
0x00040000 + HitTest area
0x00050000 - 0x0005FFFF : controls (those that are not commands)
0x00040000 + IDW_
简单的“帮助”命令
有两个简单的帮助命令由 Microsoft 基础类实现:
由 CWinApp::OnHelpIndex 实现的ID_HELP_INDEX
由 CWinApp::OnHelpUsing 实现的ID_HELP_USING
第一个命令显示应用程序的帮助索引。 第二个显示有关使用 WinHelp 程序的用户帮助。
Context-Sensitive 帮助 (F1 帮助)
F1 键通常转换为 ID 为ID_HELP的命令,该命令由放置在主窗口的快捷键表中的快捷键。 ID_HELP命令也可以由主窗口或对话框中 ID 为ID_HELP的按钮生成。
无论如何生成ID_HELP命令,它都会路由为普通命令,直到它到达命令处理程序。 有关 MFC 命令路由体系结构的详细信息,请参阅 技术说明 21。 如果应用程序已启用帮助,ID_HELP命令将由 CWinApp::OnHelp 处理。 应用程序对象接收帮助消息,然后相应地路由命令。 这是必要的,因为默认命令路由不足以确定最具体的上下文。
CWinApp::OnHelp
尝试按以下顺序启动 WinHelp:
使用帮助 ID 检查活动
AfxMessageBox
呼叫。 如果消息框当前处于活动状态,则会启动 WinHelp,其上下文适用于该消息框。将WM_COMMANDHELP消息发送到活动窗口。 如果该窗口未通过启动 WinHelp 做出响应,则相同的消息将发送到该窗口的上级,直到处理消息或当前窗口是顶级窗口。
将ID_DEFAULT_HELP命令发送到主窗口。 这会调用默认帮助。 此命令通常映射到
CWinApp::OnHelpIndex
。
若要全局替代默认 ID 基值(例如命令0x10000,以及对话框等资源的0x20000),应用程序应替代 CWinApp::WinHelp。
若要重写此功能以及确定帮助上下文的方式,应处理WM_COMMANDHELP消息。 你可能希望提供比框架提供的更具体的帮助路由,因为它仅深入到当前的 MDI 子窗口。 你可能还希望为特定窗口或对话提供更具体的帮助,可能基于该对象或对话框中的活动控件的当前内部状态。
WM_COMMANDHELP
afx_msg LRESULT CWnd::OnCommandHelp(WPARAM wParam, LPARAM lParam)
WM_COMMANDHELP是请求帮助时活动窗口收到的专用 Windows MFC 消息。 当窗口收到此消息时,它可能会调用 CWinApp::WinHelp
与窗口的内部状态匹配的上下文。
lParam
包含当前可用的帮助上下文。 如果尚未确定帮助上下文,则 lParam 为零。 一个实现 OnCommandHelp
,可以使用 lParam 中的上下文 ID 来确定不同的上下文,也可以只传递给它 CWinApp::WinHelp
。
wParam
未使用,将为零。
OnCommandHelp
如果函数调用CWinApp::WinHelp
,它应返回 TRUE。 返回 TRUE 将停止此命令的路由到其他类和其他窗口。
帮助模式 (Shift+F1 帮助)
这是上下文相关的帮助的第二种形式。 通常,按 Shift+F1 或通过菜单/工具栏输入此模式。 它作为命令(ID_CONTEXT_HELP)实现。 当模式对话框或菜单处于活动状态时,消息筛选器挂钩不用于转换此命令,因此,仅当应用程序执行主消息泵时CWinApp::Run
,此命令才可供用户使用。
进入此模式后,即使应用程序通常会为该区域显示自己的光标(如窗口周围的大小边框),帮助鼠标光标也会显示在应用程序的所有区域上。 用户可以使用鼠标或键盘选择命令。 显示该命令上的帮助,而不是执行该命令。 此外,用户可以单击屏幕上的可见对象,例如工具栏上的按钮,并且将显示该对象的帮助。 此帮助模式由 CWinApp::OnContextHelp
.
执行此循环期间,除访问菜单的键外,所有键盘输入都处于非活动状态。 此外,仍通过执行 PreTranslateMessage
命令转换,以允许用户按快捷键并接收有关该命令的帮助。
如果在在 SHIFT+F1 帮助模式下不应发生的函数中 PreTranslateMessage
发生特定翻译或作,则应在执行这些作之前检查 其m_bHelpMode 成员 CWinApp
。
CDialog
例如,在调用IsDialogMessage
之前检查此作的PreTranslateMessage
实现。 这会在 SHIFT+F1 模式下在无模式对话上禁用“对话导航”键。 此外, CWinApp::OnIdle
此循环期间仍会调用。
如果用户从菜单中选择命令,则会处理该命令的帮助(通过WM_COMMANDHELP,请参阅下面的命令)。 如果用户单击应用程序窗口的可见区域,则确定是非单击还是客户端单击。
OnContextHelp
自动处理非客户端单击到客户端单击的映射。 如果是客户端单击,则会将WM_HELPHITTEST发送到已单击的窗口。 如果该窗口返回非零值,该值将用作帮助上下文。 如果返回零, OnContextHelp
则尝试父窗口(并失败该窗口及其父窗口等)。 如果无法确定帮助上下文,则默认值是将ID_DEFAULT_HELP命令发送到主窗口,然后(通常)映射到 CWinApp::OnHelpIndex
该窗口。
WM_HELPHITTEST
afx_msg LRESULT CWnd::OnHelpHitTest(
WPARAM, LPARAM lParam)
WM_HELPHITTEST是一条 MFC 专用窗口消息,在 SHIFT+F1 帮助模式下单击的活动窗口接收。 当窗口收到此消息时,它将返回 一个 DWORD 帮助 ID 供 WinHelp 使用。
LOWORD(lParam)包含相对于窗口工作区单击鼠标的 X 轴设备坐标。
HIWORD(lParam) 包含 Y 轴坐标。
wParam
未使用,将为零。 如果返回值为非零,则使用该上下文调用 WinHelp。 如果返回值为零,则会查询父窗口以获取帮助。
在许多情况下,可以利用可能已有的命中测试代码。 有关处理WM_HELPHITTEST消息的示例,请参阅实现 CToolBar::OnHelpHitTest
(代码利用按钮和工具提示 CControlBar
中使用的命中测试代码)。
MFC 应用程序向导支持和 MAKEHM
MFC 应用程序向导创建生成帮助文件(.cnt 和 .hpj 文件)所需的文件。 它还包括Microsoft帮助编译器接受的多个预生成.rtf文件。 许多主题已完成,但某些主题可能需要针对特定应用程序进行修改。
名为 MAKEHM 的实用工具支持自动创建“帮助映射”文件。 MAKEHM 实用工具可以转换应用程序的 RESOURCE。H 文件到帮助映射文件。 例如:
#define IDD_MY_DIALOG 2000
#define ID_MY_COMMAND 150
将转换为:
HIDD_MY_DIALOG 0x207d0
HID_MY_COMMAND 0x10096
此格式与帮助编译器的设施兼容,它映射上下文 ID(右侧的数字)与主题名称(左侧的符号)。
MFC 编程实用工具示例 MAKEHM 中提供了 MAKEHM 的源代码。
运行 MFC 应用程序向导后添加帮助支持
向应用程序添加帮助的最佳方式是在创建应用程序之前,在 MFC 应用程序向导的“高级功能”页上检查“上下文相关的帮助”选项。 这样,MFC 应用程序向导会自动将必要的消息映射条目添加到 CWinApp
-derived 类以支持帮助。
消息框的帮助
消息框(有时称为警报)的帮助通过 AfxMessageBox
函数(Windows API 的 MessageBox
包装器)得到支持。
有两个版本 AfxMessageBox
,一个用于字符串 ID,另一个用于指向字符串的指针(LPCSTR
):
int AFXAPI AfxMessageBox(LPCSTR lpszText,
UINT nType,
UINT nIDHelp);
int AFXAPI AfxMessageBox(UINT nIDPrompt,
UINT nType,
UINT nIDHelp);
在这两种情况下,都有一个可选的帮助 ID。
在第一种情况下,nIDHelp 的默认值为 0,表示此消息框没有帮助。 如果用户按下 F1(例如消息框)处于活动状态,用户将不会收到帮助(即使应用程序支持帮助)。 如果不需要,则应为 nIDHelp 提供帮助 ID。
第二种情况下,nIDHelp 的默认值为 -1,表示帮助 ID 与 nIDPrompt 相同。 当然,仅当应用程序已启用帮助时,帮助才能工作。 如果希望消息框没有帮助支持,则应为 nIDHelp 提供 0。 如果希望消息启用帮助,但需要与 nIDPrompt 不同的帮助 ID,只需为 nIDHelp 提供与 nIDPrompt 不同的正值。