如何将HWND传递给另一Win32应用以实现RPC通信
Win32应用AA与BB的HWND无文件自动传递方案
一、内存共享方案:命名共享内存
完全可以把HWND放到内存的“知名位置”——命名共享内存里,这是最直接的无文件共享方式:
- AA启动后,用
CreateFileMappingW创建一个全局唯一名称的文件映射对象(比如L"Global\\AA_MainWindowHWND",加Global前缀支持跨用户会话访问,不需要的话可以去掉),内存大小设为sizeof(HWND)即可。 - 通过
MapViewOfFile获取共享内存的指针,把自身主窗口的HWND写入这块内存。 - BB启动后,用同一个名称调用
OpenFileMappingW打开映射对象,再映射到自己的地址空间,直接读取里面的HWND值。 - 注意:AA退出时要关闭映射对象和视图,避免资源泄漏;BB读取时要处理映射不存在的情况(比如AA还没启动)。
AA端写入HWND代码片段
// 创建命名共享内存 HANDLE hMapFile = CreateFileMappingW( INVALID_HANDLE_VALUE, // 使用系统页文件作为后备存储 NULL, // 默认安全属性 PAGE_READWRITE, // 读写权限 0, // 高位大小(HWND是4/8字节,填0即可) sizeof(HWND), // 共享内存大小 L"Global\\AA_MainWindowHWND"); // 全局唯一名称 if (hMapFile != NULL) { HWND* pSharedHWND = (HWND*)MapViewOfFile( hMapFile, // 映射对象句柄 FILE_MAP_WRITE, // 写入权限 0, 0, sizeof(HWND)); if (pSharedHWND != NULL) { *pSharedHWND = hMainWnd; // 写入AA的主窗口HWND UnmapViewOfFile(pSharedHWND); } // 保持映射对象句柄直到AA退出,确保BB随时能读取 }
BB端读取HWND代码片段
HWND GetAAWindowHWND() { HWND hwndAA = NULL; HANDLE hMapFile = OpenFileMappingW( FILE_MAP_READ, // 只读权限 FALSE, // 不继承句柄 L"Global\\AA_MainWindowHWND"); if (hMapFile != NULL) { HWND* pSharedHWND = (HWND*)MapViewOfFile( hMapFile, FILE_MAP_READ, 0, 0, sizeof(HWND)); if (pSharedHWND != NULL) { hwndAA = *pSharedHWND; UnmapViewOfFile(pSharedHWND); } CloseHandle(hMapFile); } return hwndAA; }
二、其他无文件共享方案
1. 窗口类名/标题查找
如果AA的主窗口有全局唯一的类名或标题,BB可以直接枚举窗口定位HWND:
- 用
FindWindowW直接匹配AA的窗口类名(比如AA注册窗口时用L"AA_MainWindowClass")或标题;如果需要更精准的筛选,用EnumWindows遍历所有顶层窗口,自定义匹配逻辑。 - 优点:零额外资源开销,实现最简单;缺点:多AA实例运行时会混淆,且类名/标题必须唯一。
示例代码(BB端):
HWND hwndAA = FindWindowW(L"AA_MainWindowClass", L"AA应用主窗口标题");
2. WM_COPYDATA + 命名事件
适合需要精准响应的场景:
- AA创建一个命名事件(
CreateEventW),BB启动后打开该事件,然后向所有顶层窗口发送WM_COPYDATA消息,附带自己的窗口HWND。 - AA收到
WM_COPYDATA后,验证请求来源是BB,再把自身HWND通过WM_COPYDATA回传给BB。 - 优点:支持多实例,能精准定位目标AA;缺点:双方都需要处理
WM_COPYDATA消息逻辑。
3. 命名管道
AA作为管道服务器,BB作为客户端连接管道,AA直接把HWND发送给BB。这种方式比共享内存更灵活,后续还能扩展双向通信,但实现复杂度稍高。
三、方案选择建议
- 仅需简单传递HWND:优先选命名共享内存或窗口查找,实现成本最低;
- 需要多实例区分、精准定位:选WM_COPYDATA+命名事件;
- 后续有扩展通信需求:考虑命名管道。
内容的提问来源于stack exchange,提问作者Dess
相关产品推荐
相关产品推荐

