我们自己如何在 属性 页面中直接 运行 OnPsnHelp 事件(或调用它)?
How can we directly run the OnPsnHelp event (or invoke it) in a property page ourselves?
我一直在通过我的应用添加 OnHelpInfo
消息处理程序。这不是因为我的应用程序将支持上下文帮助。相反,我想拦截 F1 键,然后简单地调用现有的“帮助”代码,该代码在按下对话框按钮或菜单项时触发。示例:
#pragma warning (suppress : 26434)
BOOL CBrotherExcludeDlg::OnHelpInfo(HELPINFO* pHelpInfo)
{
OnButtonHelp();
// return CResizingDialog::OnHelpInfo(pHelpInfo);
return TRUE;
}
我的问题是 属性 页面。他们使用不同的机制来处理帮助主题的显示。示例:
void CCalendarSettingsGooglePage::OnPsnHelp(NMHDR* hdr, LRESULT* res)
{
theApp.DisplayHelpTopic(_T("msa-options-calendars.html"));
}
它使用 PSN_HELP
处理程序。当我将 OnHelpInfo
添加到 属性 页面时,我现在不确定如何简单地 运行 OnPsnHelp
事件。我试图避免在两个地方调用 DisplayHelpTopic
.
我们如何直接调用 OnPsnHelp
(就像我调用“帮助”按钮单击处理函数)或通过消息调用它?
这是样板代码:
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
}
所以我不明白。如果我使用 SendMessage(WM_COMMAND, ID_HELP);
,软件中的响应是一个弹出窗口 Failed to launch help
。
正如您在评论中提到的,您 可以 只需使用两个 nullptr
值调用 OnPsnHelp
函数,因为该函数实际上并不使用那些参数。但是,这是自找麻烦,如果在您的软件的未来版本中,OnPsnHelp
被修改为 使用那些。
因此,您应该构造一个适当的 PSHNOTIFY
结构,并在 [=12] 的 'proxy' 调用中传递该结构和有效 return 代码变量的地址=]. PSHNOTIFY
结构的构造非常简单;它只是一个 NMHDR
结构,后跟一个 unused lParam
项。
这是一个可能的实现:
BOOL CCalendarSettingsGooglePage::OnHelpInfo(HELPINFO*)
{
PSHNOTIFY psns;
psns.lParam = 0; // The docs say this contains no information.
psns.hdr.hwndFrom = GetParent()->GetSafeHwnd(); // The parent P/Sheet
psns.hdr.idFrom = IDHELP; // Not sure what this should REALLY be?
#pragma warning(suppress: 26454) // For: #define PSN_HELP (PSN_FIRST-5)
psns.hdr.code = PSN_HELP; // One would assume this is the correct code!
LRESULT result;
OnPsnHelp(&psns.hdr, &result); // Make the call.
return TRUE; // Or possibly: return static_cast<BOOL>(result);
}
来自M/S docs:
lParam
Pointer to a PSHNOTIFY
structure that contains information about the
notification code. This structure contains an NMHDR
structure as its
first member, hdr. The hwndFrom member of this NMHDR
structure contains the handle to the property sheet. The lParam
member of the PSHNOTIFY
structure does not contain any information.
下面是 PSHNOTIFY
和 NMHDR
结构的定义:
typedef struct _PSHNOTIFY
{
NMHDR hdr;
LPARAM lParam;
} PSHNOTIFY, *LPPSHNOTIFY;
typedef struct tagNMHDR
{
HWND hwndFrom;
UINT_PTR idFrom;
UINT code; // NM_ code
} NMHDR;
我一直在通过我的应用添加 OnHelpInfo
消息处理程序。这不是因为我的应用程序将支持上下文帮助。相反,我想拦截 F1 键,然后简单地调用现有的“帮助”代码,该代码在按下对话框按钮或菜单项时触发。示例:
#pragma warning (suppress : 26434)
BOOL CBrotherExcludeDlg::OnHelpInfo(HELPINFO* pHelpInfo)
{
OnButtonHelp();
// return CResizingDialog::OnHelpInfo(pHelpInfo);
return TRUE;
}
我的问题是 属性 页面。他们使用不同的机制来处理帮助主题的显示。示例:
void CCalendarSettingsGooglePage::OnPsnHelp(NMHDR* hdr, LRESULT* res)
{
theApp.DisplayHelpTopic(_T("msa-options-calendars.html"));
}
它使用 PSN_HELP
处理程序。当我将 OnHelpInfo
添加到 属性 页面时,我现在不确定如何简单地 运行 OnPsnHelp
事件。我试图避免在两个地方调用 DisplayHelpTopic
.
我们如何直接调用 OnPsnHelp
(就像我调用“帮助”按钮单击处理函数)或通过消息调用它?
这是样板代码:
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
}
所以我不明白。如果我使用 SendMessage(WM_COMMAND, ID_HELP);
,软件中的响应是一个弹出窗口 Failed to launch help
。
正如您在评论中提到的,您 可以 只需使用两个 nullptr
值调用 OnPsnHelp
函数,因为该函数实际上并不使用那些参数。但是,这是自找麻烦,如果在您的软件的未来版本中,OnPsnHelp
被修改为 使用那些。
因此,您应该构造一个适当的 PSHNOTIFY
结构,并在 [=12] 的 'proxy' 调用中传递该结构和有效 return 代码变量的地址=]. PSHNOTIFY
结构的构造非常简单;它只是一个 NMHDR
结构,后跟一个 unused lParam
项。
这是一个可能的实现:
BOOL CCalendarSettingsGooglePage::OnHelpInfo(HELPINFO*)
{
PSHNOTIFY psns;
psns.lParam = 0; // The docs say this contains no information.
psns.hdr.hwndFrom = GetParent()->GetSafeHwnd(); // The parent P/Sheet
psns.hdr.idFrom = IDHELP; // Not sure what this should REALLY be?
#pragma warning(suppress: 26454) // For: #define PSN_HELP (PSN_FIRST-5)
psns.hdr.code = PSN_HELP; // One would assume this is the correct code!
LRESULT result;
OnPsnHelp(&psns.hdr, &result); // Make the call.
return TRUE; // Or possibly: return static_cast<BOOL>(result);
}
来自M/S docs:
lParam
Pointer to a
PSHNOTIFY
structure that contains information about the notification code. This structure contains anNMHDR
structure as its first member, hdr. The hwndFrom member of thisNMHDR
structure contains the handle to the property sheet. The lParam member of thePSHNOTIFY
structure does not contain any information.
下面是 PSHNOTIFY
和 NMHDR
结构的定义:
typedef struct _PSHNOTIFY
{
NMHDR hdr;
LPARAM lParam;
} PSHNOTIFY, *LPPSHNOTIFY;
typedef struct tagNMHDR
{
HWND hwndFrom;
UINT_PTR idFrom;
UINT code; // NM_ code
} NMHDR;