我正在编写一个包装Windows PropertySheet的(非托管) C++类。从本质上讲,就像这样:
class PropSheet {
PROPSHEETHEADER d_header;
public:
PropSheet(/* parameters */);
INT_PTR show();
private:
static int CALLBACK *propSheetProc(HWND hwnd, UINT msg, LPARAM lParam);
};构造函数只是初始化d_header成员:
PropSheet::PropSheet(/* parameters */) {
d_header.dwSize = sizeof(PROPSHEETHEADER);
d_header.dwFlags = PSH_USECALLBACK;
// ...
d_header.pfnCallback = &propSheetProc;
// ...
}之后,我可以使用以下命令以模态方式显示它:
INT_PTR PropSheet::show() {
return PropertySheet(&d_header);
}现在的问题是,因为回调是静态的,所以它无法访问包装器类。如果这是一个普通的窗口,使用WindowProc而不是PropSheetProc,我可以在WNDCLASS中使用cbWndExtra将一些额外的数据附加到窗口,在这个窗口中,我可以像在this article中那样存储一个指向包装器的指针。但属性页不提供此功能。
此外,因为属性表是以模式显示的,所以在创建和销毁实际窗口之间不能执行任何代码,除非该代码是通过回调或表的某个窗口过程执行的。
到目前为止,我想出的最好的解决方案是,在显示属性表之前,在全局变量中存储一个指向包装器类的指针。但这假设我一次只显示一个属性表,而且非常难看。
有没有人有更好的办法来解决这个问题?
发布于 2009-12-15 05:10:26
当您以模式方式显示属性表单时,您应该能够使用属性表单的父窗口(即它的句柄)来映射到一个实例,方法是在PropSheetProc()的hwndDlg参数上使用::GetParent()。
发布于 2009-12-15 05:54:40
很棒,这是另一个使用回调而不使用用户定义的上下文参数的Win32应用程序接口。遗憾的是,这不是唯一的一个。例如,CreateWindow很糟糕(它提供了用户定义的上下文,但该上下文在前几个窗口消息中不可用),SetWindowsHookEx更糟糕(根本没有上下文)。
唯一通用且有效的“解决方案”是发出一小段硬编码为“this”指针的可执行代码。如下所示:http://episteme.arstechnica.com/eve/forums/a/tpc/f/6330927813/m/848000817831?r=848000817831#848000817831
太可怕了。
发布于 2009-12-15 10:10:24
PROPSHEETPAGE结构有一个可用于回调的lParam字段。在PROPSHEETHEADER中,可以包含PSH_PROPSHEETPAGE标志来传递描述页面的PROPSHEETPAGE项的数组,或者省略该标志以传递预分配的HPROPSHEETPAGE句柄数组(这意味着使用CreatePropertySheetPage(),因此无论如何都要使用PROPSHEETPAGE )。
https://stackoverflow.com/questions/1903066
复制相似问题