我正在编写一个win32包装类,主要是为了更多地了解win32编程.为了解决c样式回调的问题,下面的方法使用SetWindowLong/GetWindowLong存储/检索指针并将其传递给实际的winproc.
LRESULT CALLBACK WinClass::WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// On window creation, WindowProc receives lParam as a LPCREATESTRUCT
// Store *this* pointer as long in GWL_USERDATA
if (msg == WM_NCCREATE)
::SetWindowLong(hwnd, GWL_USERDATA, reinterpret_cast<long>(reinterpret_cast<LPCREATESTRUCT>(lParam)->lpCreateParams));
// Retrieve the pointer
WinClass *wnd = reinterpret_cast<WinClass*>(::GetWindowLongPtr(hwnd, GWL_USERDATA));
// Call the actual winproc function
if (wnd)
return wnd->WndProc(hwnd, msg, wParam, lParam);
// Default to DefWindowProc message handler function
return ::DefWindowProc(hwnd, msg, wParam, lParam);
}
Run Code Online (Sandbox Code Playgroud)
Winclass是包装CreateWindowEx创建的主窗口的类.相同的WindowProc函数是包装模式对话框的MDlgClass的一部分.我正在调用这样的对话框
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(id), hwnd, DialogProc);
Run Code Online (Sandbox Code Playgroud)
如果我将NULL作为hWndParent传递,则该对话框可以作为无模式对话框工作,但如果我将hwnd传递给主窗口的句柄作为hWndParent,则该对话框可以正常作为模态对话框.但是,当我关闭对话框时,它不会将控制权传递回主父窗口?Visual Studio中的调试显示它挂在WinMain中的消息泵中.
我想过使用一个hashmap来映射指针,但我宁愿用GetWindowLong来做它.这可能吗?我已经尝试将对话框指针存储在DWL_USER中,但它没有帮助.
任何帮助将不胜感激,我仍然围绕Win32.
编辑:我正在使用EndDialog销毁对话框
编辑:我将指针存储在主窗口的GWL_USERDATA区域,这是Windows不使用的,我只是在首次创建窗口时在WinClass :: WindowProc中修改它.如果我没有实例化对话框类,我知道正在正确访问指针,因为应用程序响应通过WindowProc和WM_COMMAND处理的菜单命令.
您不能将WindowProc用作DialogProc.Window Procedures在它们不处理消息时调用DefWindowProc,并在它们执行时返回有意义的结果.Dialog Procedures在它们不处理消息时返回FALSE,在它们DO时返回TRUE(除非它们处理时WM_INITDIALOG),如果它们有一个有意义的结果,它们需要从外部窗口过程返回,放置在DWL_MSGRESULT.
当您调用模式对话框函数DialogBox时,它会进入一个消息循环 - 它会将消息发送到线程中的所有窗口,以便所有窗口继续绘制和处理输入 - 当对话框关闭时(使用EndDialog),DialogBox程序应该返回.
在创建一个包装对话框的类时,通常的方法是将'this'指针传递给DialogBoxParam函数之一 - 可以直接从WM_INITDIALOG消息中提取.