c++ - 如何将鼠标点击和拖动发送到后台的另一个程序?

标签 c++ windows opengl screen-capture

我正在尝试编写一个程序,从另一个程序(我们称之为 P2)获取视觉输出并将其显示在 3d 世界的屏幕上。

图像捕获的流程如下:

P2 -> BitBlt -> OpenGL Texture -> 3d World

我希望用户能够环顾四周并使用十字准线单击 P2 中的元素,十字准线将固定在我的程序视口(viewport)中间。但是,在我的实现中,我似乎需要 2 个光标 - 一个用于控制 3d 世界中的相机,一个用于控制 P2 - 我认为这很重要。

此外,由于窗口只更新它可见的部分,而且我希望 P2 以尽可能高的分辨率不断更新,因此在第二个虚拟桌面上安装 P2 是有意义的。这使得交互问题变得更加困难。

我能想到的一些有缺点的解决方案:

  • 制作合成窗口管理器

    • 听起来工作量很大,而且我还没有找到任何关于如何完成这项工作的文档。
  • 将实际光标放在 P2 上,但获取光标位置的变化并使用它在 3d 世界中移动相机

    • 这不是从平面坐标到球坐标的线性变换。此外,我不确定光标是否可以位于与当前桌面不同的桌面上。

如果有帮助,我愿意接受替代捕获方法的建议。 一个例子是 Hook P2 的 DirectX 或 OpenGL 输出,如有必要,在它未处于事件状态时欺骗它进行渲染。这可能会使 P2 最小化,但不会解决输入问题。

或许可以hook P2的输入函数?这甚至会被建议吗?

这里有一些图片来说明我的程序。

Chrome - Straight On Chrome - To The Side


更新:

我已经实现了 SendNotifyMessage() 并发现当我向应用程序发送 WM_LBUTTONDOWN 消息时它变成了前台窗口。我在 P2 上设置了 WS_EX_NOACTIVATE 来阻止这种行为,但它仍然会窃取焦点。然后我需要 Sleep(),大概直到 P2 处理消息,然后使用 SetForegroundWindow()。请注意,SetFocus()SetActiveWindow() 不会导致我的程序重新获得焦点(因此焦点可能是错误的词)。是否有任何方法可以在保持 SendNotifyMessage() 异步的同时消除这种延迟?

此外,在尝试使用 PostMessage() 时,我发现坐标转换不正确。但是,它在 SendNotifyMessage() 中运行良好。是什么导致了这种行为?

相关代码

在获得我想要捕获的窗口的句柄后,我运行这个:

prevWndStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
SetWindowLong(hwnd, GWL_EXSTYLE, prevWndStyle | WS_EX_NOACTIVATE);

在我的 WndProc 中接收到 WM_INPUT 消息并处理输入后,我运行此代码:

if (raw->data.mouse.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) {
    int hitX, hitY;
    if (gls->Click(vec3(0.0f, 0.0f, 1.0f), 0, hitX, hitY)) {
        LPARAM lParam = MAKELPARAM(hitX, hitY);
        SendNotifyMessage(gls->ic.GetHWND(), WM_MOUSEMOVE, 0, lParam);
        SendNotifyMessage(gls->ic.GetHWND(), WM_LBUTTONDOWN, MK_LBUTTON, lParam);
        SendNotifyMessage(gls->ic.GetHWND(), WM_LBUTTONUP, 0, lParam);

        // I want to get rid of these
        Sleep(100);
        SetForegroundWindow(gls->aw.GetHWND());
    }
}

更新2

我发现 WS_EX_NOACTIVATE 会停止切换到第二个桌面,但是当 P2 在同一个桌面上时,P2 会被带到前台。

最佳答案

我认为您可以使用 WIN32API 来模拟点击并捕获窗口内容,我以前在不同的 3d“窗口”环境中看到过它,而且我在 Termina Server 之类的东西中也看到过它。

所以也许当“他们点击你,你向前传递点击”时(同时进行坐标转换)?

供您细读的一些链接:

https://msdn.microsoft.com/en-us/library/windows/desktop/gg153548%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

http://www.cplusplus.com/forum/windows/24162/

关于c++ - 如何将鼠标点击和拖动发送到后台的另一个程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46815498/

相关文章:

c++ - 为什么在不同的连接(新的 InternetOpen 和新的 InternetConnect)上两次调用 HttpSendRequest 会带来不同的结果?

opengl - 图形管道的哪些部分是使用 CPU 和 GPU 完成的?

opengl - 在 OpenGL 中沿折线路径创建管

c++ - 避免在字符串中进行 if-else 分支以进行类型调度

c++ - CMake 不在子模块 B 中包含子模块 A 的头目录

c++ - 内核模式到用户模式的通信

c++ - 如何正确地使用四元数进行旋转

c++ - 条件变量 wait_until timeout_time 过去了吗?

c++ - 套接字发送/接收问题 : second client message never reaches server

c++ - CreateRemoteThread - ERROR_ACCES_DENIED