将 Win32/WinAPI 应用程序移植到 wxWidgets
Port Win32/WinAPI application to wxWidgets
我目前正在使用Windows 10,MSVC v142(VS2019(和wxWidgets 3.1.3。我有一个旧的Windows C++应用程序,它使用WinAPI作为其GUI功能,即Windows消息循环,使用"CreateWindow",并且必须"手动"创建所有窗口过程和事件处理。
我想通过使用 wxWidgets 逐步替换 UI 来改进此应用程序,这样我就不必从头开始。我会在wxWidgets中实现新的,独立的UI功能(例如特定的对话框(,然后回到过去,用wxWidgets实现替换所有旧的UI代码,而不必在此过程中破坏应用程序。
以下是我的应用当前设置方式的框架:
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// Handling window messages, e.g menus, buttons, etc.
}
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char* lpCmdLine, int nCmdShow)
{
// Initialize resources, register main window class using MainWndProc, etc.
// ...
HWND mainwnd = CreateWindow(/* CreateWindow args... */);
do
{
MSG msg = {};
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// Per-frame application logic
// ...
} while (msg.message != WM_QUIT);
// Clean up resources
// ...
return 0;
}
我需要如何修改它,以便所有 WinAPI 对象继续运行,但现在我也可以使用 wxWidgets 创建窗口?我之前尝试通过从wxApp
派生的自定义类初始化 wxWidgets 来替换上面的消息循环,但我的应用程序在清理代码期间不断崩溃(有时甚至无法达到(。
编辑:我设法让它工作,更新的骨架可以在下面找到。
// Main WinAPI window procedure
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
// Code to handle other messages
// ...
case WM_CLOSE:
// Closing this window should shut down the app
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
class MyApp : public wxApp
{
public:
virtual bool OnInit() override
{
if(!Old_Init())
{
// Perform cleanup in case something goes wrong
Old_Exit();
return false;
}
// Wrap the WinAPI window in a dummy wxWindow
m_dummyMainWindow = new wxWindow();
m_dummyMainWindow->SetHWND(m_mainWnd);
return true;
}
int OnExit() override
{
// Unset the dummy window HWND and delete it (is this necessary?)
m_dummyMainWindow->SetHWND(NULL);
delete m_dummyMainWindow;
// Clean up everything else
return Old_Exit();
}
private:
bool Old_Init()
{
// Perform the old initialization
// ...
m_mainWnd = CreateWindow(/* CreateWindow args... */);
if(m_mainWnd)
{
return true;
}
else
{
return false;
}
}
int Old_Exit()
{
// Perform the old cleanup (previously done after exiting the Windows message loop)
// ...
return 0;
}
HWND m_mainWnd;
wxWindow* m_dummyMainWindow;
};
wxIMPLEMENT_APP_NO_MAIN(MyApp);
// App entrypoint
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char* lpCmdLine, int nCmdShow)
{
if (wxEntry())
{
// Exit if something goes wrong (this might not be the correct way to do it?)
wxExit();
}
return 0;
}
这似乎确实有效,所有旧的 UI 元素都像以前一样工作,但我不能 100% 确定这是一个稳定的解决方案。我的调试器警告我有关内存泄漏的信息,当我激活 UI 元素(例如打开和关闭对话框(时,内存泄漏的数量似乎会增加。我怀疑 WinAPI 资源可能无法正确清理。我错过了什么吗?
EDIT2:我做了更多的调试,我的原始应用程序中的代码(即没有wxWidgets(也会导致这些"内存泄漏",我无法在最小的工作示例中复制它,所以我怀疑这个问题与wxWidgets完全无关。因此,我相信上述方法应该可以解决我的问题,但我不介意第二种意见。
我建议查看 MFC 示例,以查看接近您想要执行的操作的工作示例。 当然,MFC 与 Win32 API 并不完全相同,但它仍然应该是一个很好的起点。
值得注意的是,它显示了当您运行自己的消息时如何将消息传递给wx事件循环(这部分在include/wx/msw/mfc.h
wxMFCApp
类中(。当然,如果可以切换到运行wx事件循环,那就更简单了。
您可能还会发现,您可以使用AssociateHandle()
将您创建HWND
包装到wxWindow
中,并通过覆盖MSWHandleMessage()
甚至仅直接使用wxNativeWindow
来处理其消息,这很有帮助。
祝你好运!
- 将 Win32/WinAPI 应用程序移植到 wxWidgets
- 使用 Visual Studio 2019 构建 Hello World wxwidgets 应用程序时出错
- Visual Studio中的wxwidgets应用程序给出错误"LNK2019 unresolved external symbol"
- 如何使用CLion和MSVC编译器工具链编译wxWidgets Hello World应用程序而没有错误?
- Visual C++ wxWidgets应用程序仅适用于我的PC
- CodeBlocks:如何使用wxWidgets库DLL构建C++应用程序
- wxWidgets 应用程序中的 SOCI 数据类型
- wxWidgets 应用程序中的重叠 IO
- wxWidgets UI应用程序在C++中使用4个或多个wxBoxSizer对象时出现分段错误
- 使用 wxWidgets(使用 pthreads)创建共享 ilbrary 应用程序
- 输入关闭wxWidgets应用程序时wx面板添加
- 在 c++static 库和 c++ 应用程序中设置 wxwidgets 路径的差异
- WxWidgets 应用程序运行失败
- C++wxWidgets应用程序未编译
- 在框架中使用OpenGL上下文编写简单的wxWidgets应用程序
- wxWidgets应用程序在尝试启动新对话框时冻结
- 无法将 wxWidgets 应用程序与代码::块/MinGW 链接
- 不能在wxWidgets应用程序中包含std::线程头
- 如何静态编译wxwidgets应用程序
- 我需要什么硬件/软件移植我的c++ /wxWidgets应用程序到MAC