csh_dialog.shtml

来自「mfc资源大全包含MFC编程各个方面的源码」· SHTML 代码 · 共 249 行

SHTML
249
字号
<HTML>

<!-- Header information-->
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
   <META NAME="Author" CONTENT="Chris Maunder">
   <TITLE>Misc - Implementing ToolTip style Context sensitive help in Dialogs</TITLE>
</HEAD>

<!-- Set background properties -->
<body background="../fancyhome/back.gif" bgcolor="#FFFFFF" link="#B50029" vlink="#8E2323" alink="#FF0000">

<!-- A word from our sponsors... -->
<table WIDTH="100%">
<tr WIDTH="100%"><td align=center><!--#exec cgi="/cgi/ads.cgi"--><td></tr>
</table>


<!-- Article Title -->
<CENTER><H3><FONT COLOR="#AOAO99">
Implementing ToolTip style Context sensitive help in Dialogs
</FONT></H3></CENTER>
<CENTER><H3><HR></H3></CENTER>

<!-- Author and contact details -->
This article was contributed by <A HREF="mailto:yawar@isb.comsats.net.pk">Yawar Jawaad Maajed</A>.

<!-- Sample image and source code/demo project -->
<P>
&nbsp;<A HREF="csh.zip">Download Source Code and Example</A>
</p>
<br>

<!-- The article... -->

<P><B>Steps Required</B></P>

<P><B>1.</B>In your dialog you are working with,
turn &quot;Help ID&quot; property on for every control for which you want
to have context sensitive help.</P>

<CENTER><P><IMG SRC="csh1.gif" HEIGHT=162 WIDTH=403></P></CENTER>

<P><B>2. </B>#define a double word Array in your Dialog class as 
<FONT COLOR="#990000"><TT><PRE>static const DWORD m_nHelpIDs[];
</tt></PRE></FONT>

<P>and in your Implementation do the following:

<FONT COLOR="#990000"><TT><PRE>const DWORD CMyDialog ::m_nHelpIDs[] =
{
	CONTROL ID, HELP ID GENERATED WITH MAKEHM TOOL,
	0,0
};
</tt></PRE></FONT>

In our case </P>

<P>declaration of help IDs array is as</P>

<FONT COLOR="#990000"><TT><PRE>static const DWORD m_nHelpIDs[]; 
</tt></PRE></FONT>

<P>and these IDs are defined as

<FONT COLOR="#990000"><TT><PRE>const DWORD CDlgSample::m_nHelpIDs[] =
{
	IDC_CHECK1, HIDC_CHECK1,
	IDC_COMBO1, HIDC_COMBO1,
	IDC_LIST1, HIDC_LIST1,
	IDOK, HIDOK,
	0, 0
};
</tt></PRE></FONT>

<P><B>3. </B>Include resource.hm file in your Dlg.CPP file.</P>

<P><B>4.</B> Open your application's HPJ (help project file) and add the
following line at the end of the file</P>

<FONT COLOR="#990000"><TT><PRE>#include &lt;D:\Development\CSH\resource.hm&gt;
</tt></PRE></FONT>

<P>The path will differ according to the location of your project.</P>

<P><B>5. </B>Now override two functions of your CDialog based class. One
is WM_CONTEXTMENU and other is WM_HELPINFO. </P>

<P>Fill the functions' bodies as follows.</P>

<FONT COLOR="#990000"><TT><PRE>void CDlgSample::OnContextMenu(CWnd* pWnd, CPoint point)
{
	::WinHelp(pWnd-&gt;m_hWnd, AfxGetApp()-&gt;m_pszHelpFilePath, HELP_CONTEXTMENU,
	          (DWORD)(LPVOID)m_nHelpIDs);
}

BOOL CDlgSample::OnHelpInfo(HELPINFO* pHelpInfo)
{
	return ::WinHelp((HWND)pHelpInfo-&gt;hItemHandle, AfxGetApp()-&gt;m_pszHelpFilePath,
	                 HELP_WM_HELP, (DWORD)(LPVOID)m_nHelpIDs);
}
</tt></PRE></FONT>

<P>It would be good to add another line in your OnInitDialog() function
also to make Question mark icon visible in your dialog title bar. Add the
following line in your OnInitDialog funciton</P>

<FONT COLOR="#990000"><TT><PRE>ModifyStyleEx(0, WS_EX_CONTEXTHELP);
</tt></PRE></FONT>

<P>You can also do this directly in the resource editor.</P>

<P><B>6. </B>Now Open Microsoft Word (or any other RTF word processor)
and open &quot;AfxCore.RTF&quot; file located in your projects HLP directory.
This file was generated by Application Wizard. </P>

<P><B>7. </B>In Tools menu click Options and then highlight &quot;View&quot;
tab. Then turn &quot;Hidden Text&quot; check box on which is in the group
&quot;Non Printing characters&quot;. Now Click &quot;Show/Hide&quot; button
<IMG SRC="csh2.gif" HEIGHT=31 WIDTH=59 ALIGN=ABSCENTER></P>

<P><B>8. </B>Now navigate to the end of file and press Ctrl + Enter to
enter a hard page break.</P>

<P><B>9. </B>Type help text here for the first control. In our case it
is IDC_CHECK1. We type &quot; This is tooltip
style help for this check box.&quot; here. </P>

<P><B>10.</B> Now go to beginning of the line and insert
a footnote with a custom mark &quot;#&quot; and in the footnote type HIDC_CHECK1
here. Click in the view window again.</P>

<P><B>11.</B> Repeat this step for other controls which
need to have help.

<P><B>12.</B> Bingo厖. We are done. Compile the project
and see the online context sensitive help in action. Press Shift + F1 key
when the focus is on the &quot;Close&quot; button or any other control
in the dialog window and see a little tooltip style window containing the
help you wrote. Here is how it will look like

<P><IMG SRC="csh4.gif" HEIGHT=230 WIDTH=370></P>

<CENTER><P><HR></P></CENTER>

<P><B>A better solution?</b>

<P>In my own applications I implement context sensitive
help in a better way. I have derived a generic class from Cdialog having
no dialog ID in it. Here is the declaration of the class.

<FONT COLOR="#990000"><TT><PRE>
// CSHDialog.h

/////////////////////////////////////////////////////////////////////////////
// CCSHDialog dialog
class CCSHDialog : public CDialog
{
// Construction
public:
	CCSHDialog();
	CCSHDialog(LPCTSTR lpszTemplateName,
	CWnd* pParentWnd = NULL);
CCSHDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL);

// Implementation
protected: 
	virtual const DWORD* GetHelpIDs() = 0;

	// Generated message map functions
	//{{AFX_MSG(CCSHDialog)
	virtual BOOL OnInitDialog();
	afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
	afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

//CSHDialog.CPP
/////////////////////////////////////////////////////////////////////////////
// CCSHDialog dialog
CCSHDialog::CCSHDialog(UINT nIDTemplate, CWnd* pParentWnd)
	: CDialog(nIDTemplate, pParentWnd)
{
}

CCSHDialog::CCSHDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd)
	: CDialog(lpszTemplateName, pParentWnd)
{
}

CCSHDialog::CCSHDialog() : CDialog()
{
}

BEGIN_MESSAGE_MAP(CCSHDialog, CDialog)
	//{{AFX_MSG_MAP(CCSHDialog)
	ON_WM_CONTEXTMENU()
	ON_WM_HELPINFO()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CCSHDialog message handlers

void CCSHDialog::OnContextMenu(CWnd* pWnd, CPoint point) 
{
	::WinHelp(pWnd-&gt;m_hWnd, AfxGetApp()-&gt;m_pszHelpFilePath,
	          HELP_CONTEXTMENU, (DWORD)(LPVOID)GetHelpIDs());
}

BOOL CCSHDialog::OnHelpInfo(HELPINFO*
pHelpInfo)
{
	return ::WinHelp((HWND)pHelpInfo-&gt;hItemHandle, AfxGetApp()-&gt;m_pszHelpFilePath, 
	                 HELP_WM_HELP, (DWORD)(LPVOID)GetHelpIDs());
}

BOOL CCSHDialog::OnInitDialog()
{
	CDialog::OnInitDialog();
	ModifyStyleEx(0, WS_EX_CONTEXTHELP);
	return TRUE; 
}
</tt></PRE></FONT>

<P>and I derive all of my dialog classes from CCSHDialog
instead of CDialog. GetHelpIDs() is a pure virtual function of this class
and I override it in each of the derived classes. I have a double word
array in each dialog which describes its controls identifiers and related
help identifiers exactly as we did in the above CDlgSample class. And the
overrided version of GetHelpIDs() returns the pointer to this help array.
I merely have to do NOTHING at all to implement context sensitive help
in my dialogs, except to derive my class from CCSHDialg and provide a control
identifiers and related help identifier array.

<P>We can also place ALL of our control identifiers
and their related help identifiers in the same base class厖 and thus we
will avoid &quot;#include&quot;ing resource.hm file in every file that
has a dialog class in it, and further we will avoid GetHelpIDs() and m_nHelpIDs
stuff from every class also厖 

<P>And needless to say that I&nbsp;use a separate class
as parent class for all of my property pages. That class is exactly similar
to the CCSHDialog except that it is derived from CPropertPage instead of
CDialog.

<P>So you do it as you like to

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?