本文介绍了使用类成员作为WNDPROC / DLGPROC有或没有全局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我将继续并给出一个摘要,如何使用一个类的成员的对话过程?我创建一个窗口包装类,但 CreateDialogParam 需要一个全局对话过程,所以我尝试这种解决方法: 我已经做了一些关于这个话题的搜索。我正在创建一个 Dialog 类,我将其子类化以创建一个 CMainWnd 然后实例化。在 Dialog 类中,我有一个成员函数定义为 INT_PTR CALLBACK Dialog :: cb_proc(HWND,UINT,WPARAM,LPARAM)。现在,我知道windows必须有一个全局函数作为回调过程。 所以我做了一个 std :: map< HWND,Dialog * > DlgProcs 映射将对话框窗口句柄与其Dialog类指针相关联。 和 INT_PTR CALLBACK DlgMainProc UINT,WPARAM,LPARAM)所以我可以传递给 CreateDialogParam()。在 DlgMainProc(...)的主体中搜索地图以使用 hWnd 参数来查找 Dialog * 并返回其 cb_proc(..)成员。 我的问题是没有消息得到处理,这是因为我的 Dialog 类中的成员过程从未被调用。即使当我把 MessageBox()放在里面的 DlgMainProc if(DlgProcs.find (hWnd)!= DlgProcs.end()){语句,显示消息框,一遍又一遍,直到我必须从Visual Studio 2008中止程序。这告诉我, hWnd 。奇怪的是,如果我把它放在 else 语句之后,这反而告诉我,它不是找到 hWnd 在地图中。 如果我在 cb_proc 成员函数中放置一个messagebox,得到显示。但在这期间我从来没有得到任何编译器,链接器或运行时错误。当我从中删除messagebox(为了不必中止程序,它只是为了调试的目的)程序运行,但没有消息得到处理,X按钮不关闭程序,按钮点击什么也不做。 > 以下是PasteBin代码: http://pastebin.com/GsGUBpZU Btw,我没有问题子类化这个,我的窗口创建好,只是没有处理消息, cb_proc 编辑:以下是代码的相关部分 $ b 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()){警报(blah); //重复执行 return g_DlgProcs [hWnd] - > cb_proc(hWnd,msg,wParam,lParam); } else { Alert(blah); //删除上面的警报,这会得到 //重复执行,erm,以及.. O奇怪 return FALSE; } } Dialog :: Dialog(int id,HWND parent / * = HWND_DESKTOP * /){ _id = id; _parent = parent; //在CreateDialogParam之前尝试此方法 g_DlgProcs.insert(make_pair(_handle,this)); _handle = CreateDialogParam((HINSTANCE)GetModuleHandle(NULL), MAKEINTRESOURCE(id),_parent,(DLGPROC)g_MainDlgProc,NULL ) ; //然后在CreateDialogParam后尝试它 g_DlgProcs.insert(make_pair(_handle,this)); } INT_PTR CALLBACK Dialog :: cb_proc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){ Alert(blah); //永不执行 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)默认值: handled = ProcessMsg(msg,wParam,lParam); } //将bool转换为Windows BOOL enum return((handled == true)?TRUE:FALSE); } 永远不会被调用? 解决方案我试过你的代码,它的工作原理: cb_proc 被调用。您将会错过在 CreateDialogParam 返回之前发送的任何消息(例如 WM_INITDIALOG )。 您可以通过在 g_MainDlgProc 中将窗口句柄和对象添加到地图来修复后一个问题。如果你收到一个未知窗口的消息,你知道它属于你创建的窗口;将对象放在一个全局变量中,你可以添加句柄/对象到地图。 I'll go ahead and give a summary to this, how can I use a dialog procedure that is a member of a class? I am creating a window wrapper class, but CreateDialogParam needs a global dialog procedure, so I tried this workaround:I have done a bit of searching on this topic. I am making a Dialog class which I am subclassing to make a CMainWnd and then instantiating that. In the Dialog class I have a member function defined as INT_PTR CALLBACK Dialog::cb_proc(HWND,UINT,WPARAM,LPARAM). Now, I know that windows must have a global function as a callback procedure.So I made a std::map<HWND,Dialog*> DlgProcs map to associate the dialogs window handle with its Dialog class pointer.And a INT_PTR CALLBACK DlgMainProc(HWND,UINT,WPARAM,LPARAM) so I could pass that to CreateDialogParam(). In the body of DlgMainProc(...) I search the map for using the hWnd parameter to find the Dialog* and return its cb_proc(..) member.My problem is that none of the messages get processed, this is because the member procedure in my Dialog class never gets called. Even though when I put a MessageBox() in DlgMainProc inside a if (DlgProcs.find(hWnd) != DlgProcs.end()) { statement, the messagebox is displayed, over and over again until I have to abort the program from Visual Studio 2008. Which tells me that it is finding the hWnd in my map. The weird thing is it also does this if I put it in the else statement after that, which contradictingly tells me it is NOT finding the hWnd in the map.If I put a messagebox in the cb_proc member function it does not get displayed at all. But during this I never get any compiler, linker, or runtime errors. When I remove the messagebox from it (as to not have to abort the program, it was just for debugging purposes) the program runs but no messages get processed, the X button does not close the program, button clicks do nothing.Here is the PasteBin code: http://pastebin.com/GsGUBpZUBtw, I have no problem subclassing this, my window is created fine, just no messages are processed, cb_proc just never gets called.EDIT: Here is the relevant parts of the codemap<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);}Does anybody know why it never gets called? Or maybe just guide me to another way to use a member function as a DLGPROC? 解决方案 I tried your code and it worked: cb_proc gets called. You will miss any messages (e.g. WM_INITDIALOG) that get sent before CreateDialogParam returns.You can fix the latter problem by adding the window handle and the object to the map in g_MainDlgProc. If you get a message for an unknown window, you know it belongs to the window you're creating; put the object in a global and you can add the handle/object to the map. 这篇关于使用类成员作为WNDPROC / DLGPROC有或没有全局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-21 12:50