向WPF应用程序消息泵注入消息
Injecting Messages into WPF Application Message Pump
我有一些预编译的WPF应用程序,我需要通过发送各种消息(例如:WM_POINTERMOVE, WM_KEYDOWN等)来控制而不重新编译它们。我尝试的控制方法是将消息注入到应用程序消息泵中。作为测试,我通过获取应用程序的windows句柄,然后使用SendMessage发送消息,尝试了其他一些Win32应用程序。
BOOL CALLBACK EnumWindowsProc(
_In_ HWND hwnd,
_In_ LPARAM lParam
)
{
LPWSTR windowName = new TCHAR[256];
GetWindowText(hwnd, windowName, 256);
std::wstring windowNameString(windowName);
int position = windowNameString.find(std::wstring(L"MyApplicationWindowName"));
if (position > -1) {
hTargetWindow = hwnd;
delete windowName;
return FALSE;//stop enumerating windows
}
delete windowName;
return TRUE;
}
.....
EnumWindows(EnumWindowsProc, NULL);;
SendMessage(hTargetWindow, MY_MESSAGE, 0, 0);
我使用EnumWindows检索了应用程序的HWND(这工作得很好)。然后我使用SendMessage和PostMessage发送我的消息。而其他应用程序响应这个WPF应用程序没有。作为另一个测试,我制作了一个WPF应用程序,并添加了一些代码,以便在它接收到特定消息时设置断点。
ComponentDispatcher.ThreadFilterMessage += (ref MSG msg, ref bool handled) =>
{
if(msg.message == MY_MESSAGE)
Debug.WriteLine("break");
};
断点永远不会被击中,这表明消息没有进入消息泵。在其他类型的应用程序中尝试同样的事情会获得成功。我注入这些信息做错了什么。
我想在这里给出一个更详细的回应,但由于时间紧迫,我在这里做一个总结。我确实找到了其他一些想做同样事情的人。
处理windows消息的WPF类执行额外的检查。如果收到了一个鼠标消息,而不是处理鼠标消息中的信息,WPF将再次调用查询鼠标光标以查看它的实际位置,它将检查它是否确实有焦点,等等(对其他一些输入消息也会进行类似的检查)。如果根据WPF类库中的注释,这些检查中的任何一个失败,则假定发生了某些条件,导致WPF错误地获取消息。通过确保WPF应用程序具有焦点,我能够使我的场景工作。
另外,我不得不做一些我不建议任何人做的事情,比如做一个代理User32.dll来覆盖一些WPF行为。这对我的目的是有效的,但只适用于单一的操作系统版本。幸运的是,我的目标机器不会连接到互联网,需要执行它的任务一年左右,不会收到任何操作系统更新在它的隔离环境;Windows更新可以很容易地杀死这个解决方案。
不幸的是,为了接收Windows消息,您需要显式地覆盖WPF应用程序中的WndProc
方法,如下所示。
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
source.AddHook(new HwndSourceHook(WndProc));
显然,如果不重新编译源代码,你就无法做到这一点,所以你需要另一种方法。
我之前建议EasyHook从原始方法处理程序注入重定向到您选择的一些代码。正如评论中正确指出的那样,这并不能解决问题,因为原始应用程序仍然无法接收Windows消息。欢迎使用UI自动化的建议
- boost::进程间消息队列引发错误
- 在线编译器中的分段C++没有打印消息
- C++错误消息*成员参考.**初学者*
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 如何通过参数抛出错误消息
- 从服务器传输到客户端的消息不会出现
- ROS2 动态消息模板
- C++秘密消息学校作业
- glad 导致 glfwSwapBuffers 返回错误消息
- C++入门 5 版:类消息和文件夹
- FindPackageHandleStandardArgs.cmake:137 的 CMake 错误(消息):找不到 Boost (缺少:正则表达式)(找到合适的版本"1.72.0",
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 如何接受 [ENTER] 键作为无效输入并发送错误消息
- 无法使用加载库卸载注入的 dll (C++)
- 由于无效的 ValidateRgn() 子窗口不会收到WM_PAINT消息
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- 将 dll 文件注入 UWP
- 如何将 Firebase 与基于 Linux 的客户端应用配合使用,以便与服务器进行双向消息通信
- 向WPF应用程序消息泵注入消息