WinUI3:如何从对应的HWND还原WinUI3窗口
解决WinUI3窗口通过ID找回的问题
要实现仅通过ID找回WinUI3窗口,核心是建立ID与WinUI3 Window实例的直接关联,或是通过HWND作为中转存储Window实例的指针。以下是两种可行方案:
方案一:通过HWND中转存储Window实例指针
利用WinAPI的SetProp/GetProp,在HWND上存储WinUI3 Window的底层ABI指针,这样通过ID找到HWND后,就能直接还原Window对象。
1. 创建窗口时建立关联
// 创建WinUI3窗口 winrt::Windows::UI::Xaml::Window uWindow; HWND hWnd = nullptr; // 获取窗口HWND winrt::check_hresult(uWindow.try_as<::IWindowNative>()->get_WindowHandle(&hWnd)); // 设置ID到HWND的映射(你已实现的部分) SetPropW(hWnd, L"WindowID", reinterpret_cast<HANDLE>(L"MyTargetWindow")); // 存储WinUI3 Window的ABI指针到HWND SetPropW(hWnd, L"WinUI3WindowInstance", reinterpret_cast<HANDLE>(winrt::get_abi(uWindow)));
2. 通过ID找回WinUI3窗口
假设你已经通过枚举窗口+GetPropW拿到了目标HWND,执行以下代码还原Window对象:
// 从HWND取出Window的ABI指针 auto windowAbiPtr = reinterpret_cast<winrt::Windows::UI::Xaml::IWindow*>(GetPropW(hWnd, L"WinUI3WindowInstance")); if (windowAbiPtr != nullptr) { // 转换为WinUI3 Window实例 winrt::Windows::UI::Xaml::Window targetWindow = winrt::Windows::UI::Xaml::Window{ windowAbiPtr }; // 示例:激活窗口 targetWindow.Activate(); }
3. 窗口销毁时清理资源
在窗口关闭事件中移除属性,避免内存泄漏:
RemovePropW(hWnd, L"WindowID"); RemovePropW(hWnd, L"WinUI3WindowInstance");
方案二:直接维护ID与Window实例的映射表
如果不需要通过HWND中转,可以用全局映射表直接存储ID和WinUI3 Window实例的关联,这种方式更简洁。
1. 定义全局映射表
#include <unordered_map> #include <winrt/Windows.UI.Xaml.h> // 全局或单例模式下的映射表,键为窗口ID,值为WinUI3 Window实例 std::unordered_map<std::wstring, winrt::Windows::UI::Xaml::Window> g_WindowIdMap;
2. 创建窗口时添加到映射
winrt::Windows::UI::Xaml::Window uWindow; // 将ID与窗口实例绑定 g_WindowIdMap[L"MyTargetWindow"] = uWindow;
3. 通过ID直接获取窗口
auto it = g_WindowIdMap.find(L"MyTargetWindow"); if (it != g_WindowIdMap.end()) { winrt::Windows::UI::Xaml::Window targetWindow = it->second; // 执行窗口操作,比如激活 targetWindow.Activate(); }
4. 窗口销毁时移除映射
在窗口关闭事件中从映射表删除对应条目,避免悬空引用:
g_WindowIdMap.erase(L"MyTargetWindow");
内容的提问来源于stack exchange,提问作者Harshith
相关产品推荐
相关产品推荐

