I have been working through my app adding the OnHelpInfo
message handler. This is not because my app will support context help. Rather, I wanted to intercept the F1 key and then simply call the existing "Help" code that is triggered when then press the dialog button or menu item. Example:
#pragma warning (suppress : 26434)
BOOL CBrotherExcludeDlg::OnHelpInfo(HELPINFO* pHelpInfo)
{
OnButtonHelp();
// return CResizingDialog::OnHelpInfo(pHelpInfo);
return TRUE;
}
My problem is for the property pages. They handle the displaying on the help topics by using a different mechanism. Example:
void CCalendarSettingsGooglePage::OnPsnHelp(NMHDR* hdr, LRESULT* res)
{
theApp.DisplayHelpTopic(_T("msa-options-calendars.html"));
}
It uses the PSN_HELP
handler. When I add the OnHelpInfo
to the property page, I am now not sure how to simply run the OnPsnHelp
event. I am trying to avoid having two places where I call DisplayHelpTopic
.
How can we either directly call OnPsnHelp
(like I called the Help button click handler function) or invoke it via a message?
This is the boiler plate code:
BOOL CPropertyPage::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
ASSERT(pResult != NULL);
NMHDR* pNMHDR = (NMHDR*)lParam;
// allow message map to override
if (CDialog::OnNotify(wParam, lParam, pResult))
return TRUE;
// don't handle messages not from the page/sheet itself
if (pNMHDR->hwndFrom != m_hWnd && pNMHDR->hwndFrom != ::GetParent(m_hWnd))
return FALSE;
// handle default
switch (pNMHDR->code)
{
case PSN_SETACTIVE:
{
CPropertySheet* pSheet = GetParentSheet();
if (pSheet != NULL && !(pSheet->m_nFlags & WF_CONTINUEMODAL) && !(pSheet->m_bModeless) && !(pSheet->m_psh.dwFlags & PSH_AEROWIZARD))
*pResult = -1;
else
*pResult = OnSetActive() ? 0 : -1;
}
break;
case PSN_KILLACTIVE:
*pResult = !OnKillActive();
break;
case PSN_APPLY:
*pResult = OnApply() ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE;
break;
case PSN_RESET:
OnReset();
break;
case PSN_QUERYCANCEL:
*pResult = !OnQueryCancel();
break;
case PSN_WIZNEXT:
*pResult = MapWizardResult(OnWizardNext());
break;
case PSN_WIZBACK:
*pResult = MapWizardResult(OnWizardBack());
break;
case PSN_WIZFINISH:
*pResult = reinterpret_cast<LRESULT>(OnWizardFinishEx());
break;
case PSN_HELP:
SendMessage(WM_COMMAND, ID_HELP);
break;
default:
return FALSE; // not handled
}
return TRUE; // handled
}
So I don't get that. If I use SendMessage(WM_COMMAND, ID_HELP);
the response in the software is a popup Failed to launch help
.
As you mentioned in the comments, you could just call your
OnPsnHelp
function with twonullptr
values, because that function doesn't actually use those parameters. However, this is asking for trouble if, in a future version of your software, theOnPsnHelp
is modified so that it does use those.So, you should construct an appropriate
PSHNOTIFY
structure and pass the address of that, and of a valid return-code variable, in your 'proxy' call ofOnPsnHelp
. The construction of thatPSHNOTIFY
structure is quite trivial; it is simply anNMHDR
structure followed by an unusedlParam
item.Here's a possible implementation:
From the M/S docs:
Here are the definitions of the
PSHNOTIFY
andNMHDR
structures: