c++ - 将消息注入(inject) WPF 应用程序消息泵

标签 c++ wpf winapi

我有一些预编译的 WPF 应用程序,我需要通过发送各种消息(例如:WM_POINTERMOVE、WM_KEYDOWN 等)来控制它们而无需重新编译它们。我尝试的控制方法是将消息注入(inject)应用程序消息泵。作为测试,我通过获取应用程序的窗口句柄,然后使用 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(效果很好)。然后我使用 SendMessagePostMessage 发送消息。而其他应用程序不会响应此 WPF 应用程序。作为另一个测试,我创建了一个 WPF 应用程序并添加了一些代码,以便在它收到特定消息时设置断点。

ComponentDispatcher.ThreadFilterMessage += (ref MSG msg, ref bool handled) =>
{
    if(msg.message == MY_MESSAGE)
        Debug.WriteLine("break");
};

断点永远不会被击中,表明消息没有进入消息泵。在其他类型的应用程序中尝试同样的事情会取得成功。注入(inject)这些消息我做错了什么。

最佳答案

我想在这里做一个更详细的回复,但时间有限,我在这里做一个总结。我确实找到了其他几个想要做同样事情的人。

处理 Windows 消息的 WPF 类会进行额外的检查。如果接收到鼠标消息而不是处理鼠标消息中的信息,WPF 将再次调用以查询鼠标光标以查看其实际位置,它将检查它是否真的具有焦点,等等(类似的检查是为其他一些输入消息完成)。根据 WPF 类库中的注释,如果这些检查中的任何一个失败,则假定发生了导致 WPF 错误地获取消息的某些情况。通过确保 WPF 应用程序具有焦点,我能够让事情适用于我的场景。

此外,我还必须做一些我不建议任何人做的事情,例如创建一个代理 User32.dll 来覆盖某些 WPF 行为。这适用于我的目的,但仅适用于单个操作系统版本。幸运的是,我的目标机器不会连接到 Internet 并且需要执行它一年左右的任务并且不会在它的隔离环境中接收任何操作系统更新; Windows 更新可以轻松终止此解决方案

关于c++ - 将消息注入(inject) WPF 应用程序消息泵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39499578/

相关文章:

c++ - 为什么名称的声明点在其初始值设定项之前?

c++ - 访问冲突读取位置 0xfeef002A

c++ - 如何确保销毁父实例成员?

c++ - 显式 DLL 1 函数失败

c++ - 如何使用 <windows.h> C++ 获取当前目录名称

c++ - 将模板参数安全地转换为 long

c# - 如何创建一个 UI 来模拟 WPF 中的 RAM 分区?

c# - 一个 XmlDataProvider WPF 的多个 XPath

c# - WPF:如何使 View 动态化?

c++ - Win32 应用程序 LNK2001 : unresolved external symbol _main