65.9K
CodeProject 正在变化。 阅读更多。
Home

向消息框添加帮助按钮

2000年5月24日

viewsIcon

98733

如何向消息框添加帮助按钮并将其与上下文相关的帮助 ID 相关联。

Sample Image - mbhelp.gif

引言

如果您在MFC文档中查找AfxMessageBox函数,您会看到它具有以下声明

int AfxMessageBox( LPCTSTR lpszText, UINT nType = MB_OK, UINT nIDHelp = 0 );

int AFXAPI AfxMessageBox( UINT nIDPrompt, UINT nType = MB_OK, UINT nIDHelp = (UINT) -1 );

您会注意到,一个帮助上下文ID号被传递给该函数。问题在于,在对话框上没有办法显示帮助按钮,因此用户不知道消息有帮助可用。他们只能按 F1 来获取帮助,这并不直观,即使对于高级用户也是如此。

获得消息框上帮助按钮的唯一方法是调用::MessageBoxIndirect。然而,这要求您每次想使用消息框时都填写一个结构体(一些UI设计师对此没有意见,因为它会阻止程序员在他们的应用程序中放置太多的消息框,并且许多人认为使用消息框是糟糕的UI设计)。您还必须提供一个回调函数来处理帮助按钮命令。

一个改进的 AfxMessageBox 函数

我创建了一个新版本的AfxMessageBox,它调用了::MessageBoxIndirect。如果帮助上下文号非零,则在消息框中添加一个帮助按钮。如果帮助上下文号为 0,则不添加帮助按钮。

请注意,第一个参数是父窗口的句柄。这允许编译器区分我的AfxMessageBox函数和标准的MFCAfxMessageBox函数。我还发现,有时您希望显式地向消息框提供父窗口的句柄(例如,从无模式对话框调用时)。当然,您可以始终为句柄传递 NULL。

我的AfxMessageBox版本也使用应用程序标题作为标题,就像MFCAfxMessageBox一样(您必须在您对 Windows API 中的::MessageBox的调用中指定一个标题)。但是,您可以轻松地更改该函数以提供不同的标题。

// this version accepts a resource string identifier
UINT AfxMessageBox(HWND hWnd, UINT nIDText, UINT nType, UINT nIDHelp = 0)
{
	CString s;
	s.LoadString(nIDText);
	return AfxMessageBox(hWnd, s, nType, nIDHelp);
}

// this version accepts a text string
UINT AfxMessageBox(HWND hWnd, LPCTSTR szText, UINT nType, UINT nIDHelp = 0)
{
	MSGBOXPARAMS mbp;

	memset(&mbp, 0, sizeof mbp);

	mbp.cbSize = sizeof MSGBOXPARAMS; 
	mbp.hwndOwner = hWnd; 
	mbp.hInstance = AfxGetInstanceHandle(); 
	mbp.lpszText = szText; 

	// if you wanted to specify a different caption, here is where you do it
	mbp.lpszCaption = AfxGetAppName(); 

	// if Help ID is not 0, then add a help button
	if (nIDHelp != 0)
	{
		mbp.dwStyle = nType | MB_HELP; 
	}
	else
	{
		mbp.dwStyle = nType; 
	}

	//  mbp.lpszIcon = ; // note, you could provide your own custom ICON here!

	mbp.dwContextHelpId = nIDHelp; 
	mbp.lpfnMsgBoxCallback = &MsgBoxCallback; 
	mbp.dwLanguageId = 0x0409;
	
	return ::MessageBoxIndirect(&mbp); 
}

回调函数 -- 如何调用帮助

当用户单击“帮助”按钮时,将调用一个回调函数,接收有关帮助上下文号的信息。我们必须提供回调函数。在回调函数中,我们只需调用CWinApp::WinHelp,指定正确的帮助上下文 ID。

VOID CALLBACK MsgBoxCallback(LPHELPINFO lpHelpInfo)
{
	AfxGetApp()->WinHelp(lpHelpInfo->dwContextId);
} 


指定帮助文件

为这个AfxMessageBox实现调用的帮助文件由您的CWinApp派生应用程序类的m_pszHelpFilePath成员指定。此成员默认被赋予一个值,但最好始终在您的应用程序的OnInitInstance成员函数中显式指定帮助文件的位置。即使这也不简单,因为m_pszHelpFilePath只是一个指针。您必须显式地为字符串提供缓冲区空间(请参阅CWinApp::m_pszHelpFilePath的 MFC 文档,了解如何执行此操作的示例)。

最后一点,将“帮助”按钮添加到您的消息框是容易的部分。挑战在于为每个消息创建帮助主题,并为每个消息框实现正确的上下文号。希望,增加的用户满意度和减少的技术支持需求将使这一切努力值得。

© . All rights reserved.