PropertySheet API允许您定义一个PropSheetProc,当按下OK或Apply按钮时,它可以(在Windows和更高版本上)接收消息。这使您可以在单击其中一个按钮时进行处理。
但是,在各个属性页通过各自的对话框过程接收PSN_APPLY通知之前,将调用此处理程序。我想在处理完这些通知之后再进行处理,最好不要有难看的黑客攻击。我该怎么做?
背景:我将我的配置存储在一个struct中,每个页面在应用该struct的部分时都会修改它们。然后,在编写这些值之后,我希望一次性应用来自struct的设置,而不是从每个属性页面重新应用所有设置。
发布于 2009-10-01 20:38:47
最后,我使用PropSheetProc回调来捕获属性表的窗口句柄,然后挂起一个子类窗口过程,如下所示:
// This is not officially defined, but the whole world uses it.
#define ID_APPLY_NOW 0x3021
WNDPROC origWinProc;
LRESULT CALLBACK MyWinProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
// Call the original window procedure.
LRESULT retVal = CallWindowProc(origWinProc, hwndDlg, msg, wParam, lParam);
// Now, and only now, do our own stuff.
switch (msg) {
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
case ID_APPLY_NOW:
applyConfig();
saveConfig();
break;
}
break;
}
// Return the original winproc's result.
return retVal;
}
int CALLBACK myPropSheetProc(HWND hwndDlg, UINT msg, LPARAM lParam) {
switch (msg) {
case PSCB_INITIALIZED:
// Override the property sheet's window procedure with our own.
origWinProc = (WNDPROC)SetWindowLongPtr(hwndDlg, GWLP_WNDPROC, (LONG_PTR)&MyWinProc);
break;
}
return 0;
}(是的,即使只有一种情况需要考虑,我也使用switch语句。我很奇怪。)
发布于 2009-09-30 20:50:50
您就不能拦截IDAPPLY和IDCANCEL的WM_ BL_CLICKED消息吗?
你在用MFC吗?还是ATL?
虽然我想不出有一段时间我无法拦截BM_CLICKED.
编辑:嗯,从没有通过这个函数使用过属性页面..。刚读了一遍。您是否设置了pfnCallback函数和PSH_USECALLBACK标志集?
每个页面都有一个对话框proc。你能不能不拦截,取消和申请从那里以及?不过,我认为另一个计划似乎更合适。
发布于 2009-10-01 08:09:31
您不需要从任何对话框处理程序内部应用结构。因此,如果它是一个模态属性表,您可以做一些简单的事情,比如:
// Display the property sheet.
PropertySheet(&theSheet);
// The peroperty sheets PSN_APPLY notification sets this bool to true in the struct.
if(theStruct.fApply)
ApplyTheStruct(&theStruct);或者,我不明白为什么,考虑到' struct‘只是收集页面上输入的信息,您不会在用户与页面交互时更改结构。忽略每页PSN_APPLY消息,并在调用PropSheetProc时应用结构。如果通知为PSN_CANCEL,则完全放弃它。
https://stackoverflow.com/questions/1500565
复制相似问题