我将继续对此进行总结,如何使用作为类成员的对话过程?我正在创建一个窗口包装类,但CreateDialogParam
需要一个全局对话框过程,所以我尝试了这个解决方法:
我已经对这个主题进行了一些搜索。我正在创建一个Dialog
类,我将其子类化为 aCMainWnd
然后实例化它。在Dialog
类中,我有一个成员函数定义为INT_PTR CALLBACK Dialog::cb_proc(HWND,UINT,WPARAM,LPARAM)
. 现在,我知道windows必须有一个全局函数作为回调过程。
所以我制作了一个std::map<HWND,Dialog*> DlgProcs
映射来将对话框窗口句柄与其 Dialog 类指针相关联。
所以INT_PTR CALLBACK DlgMainProc(HWND,UINT,WPARAM,LPARAM)
我可以将它传递给CreateDialogParam()
. 在DlgMainProc(...)
我的正文中搜索地图以使用hWnd
参数查找Dialog*
并返回其cb_proc(..)
成员。
我的问题是没有任何消息得到处理,这是因为我的Dialog
班级中的成员过程永远不会被调用。即使当我在语句中放入一个inMessageBox()
时,消息框也会一遍又一遍地显示,直到我不得不从 Visual Studio 2008 中止程序。这告诉我它正在我的地图中找到 。奇怪的是,如果我把它放在之后的语句中,它也会这样做,这与我矛盾地告诉我它没有在地图中找到。DlgMainProc
if (DlgProcs.find(hWnd) != DlgProcs.end()) {
hWnd
else
hWnd
如果我在成员函数中放置一个消息框,cb_proc
它根本不会显示。但在此期间,我从未遇到任何编译器、链接器或运行时错误。当我从中删除消息框时(不必中止程序,它只是为了调试目的)程序运行但没有处理任何消息,X 按钮不会关闭程序,按钮单击什么也不做。
这是 PasteBin 代码:http ://pastebin.com/GsGUBpZU
顺便说一句,我对它进行子类化没有问题,我的窗口创建得很好,只是没有处理任何消息,cb_proc
只是永远不会被调用。
编辑:这是代码的相关部分
map<HWND,Dialog*> g_DlgProcs;
INT_PTR CALLBACK g_MainDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if (g_DlgProcs.find(hWnd) != g_DlgProcs.end()) {
Alert("blah"); // Gets executed repeatedly
return g_DlgProcs[hWnd]->cb_proc(hWnd, msg, wParam, lParam);
} else {
Alert("blah"); // Removing the above alert, this gets
// executed repeatedly, erm, as well.. O.o strange
return FALSE;
}
}
Dialog::Dialog(int id, HWND parent /* = HWND_DESKTOP */) {
_id = id;
_parent = parent;
// Tried this before CreateDialogParam
g_DlgProcs.insert(make_pair(_handle, this));
_handle = CreateDialogParam(
(HINSTANCE)GetModuleHandle(NULL),
MAKEINTRESOURCE(id), _parent,
(DLGPROC)g_MainDlgProc, NULL
);
// Then tried it after CreateDialogParam
g_DlgProcs.insert(make_pair(_handle, this));
}
INT_PTR CALLBACK Dialog::cb_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
Alert("blah"); // Never gets executed
bool handled = true;
switch (msg)
{
case WM_INITDIALOG:
OnInitialize();
break;
case WM_COMMAND:
if (HIWORD(wParam) == 0 || HIWORD(wParam) == 1) {
OnMenuCommand((HIWORD(wParam) == 1), (int)LOWORD(wParam));
} else {
OnCtrlCommand((int)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam);
}
break;
case WM_NOTIFY:
{
LPNMHDR head = (LPNMHDR)lParam;
OnNotification(head->code, head->idFrom, head->hwndFrom);
}
break;
case WM_CLOSE:
OnClose(); // DestroyWindow(_handle)
break;
case WM_DESTROY:
OnDestroy(); // PostQuitMessage(0)
default:
handled = ProcessMsg(msg, wParam, lParam);
}
// Convert bool to Windows BOOL enum
return ((handled == true) ? TRUE : FALSE);
}
有人知道为什么它永远不会被调用吗?或者也许只是引导我以另一种方式将成员函数用作 DLGPROC?