我正在尝试编写一个程序,它接收来自另一个程序的视觉输出(我们称之为P2)并将其显示在3d世界的屏幕上。
图像捕获流程如下:
P2 -> BitBlt -> OpenGL Texture -> 3d World
我希望用户能够使用十字准线环顾四周并点击P2中的元素,十字准线将在我程序的视口中间静止不动。然而,在我的实现中,似乎我需要有2个游标 - 一个用于控制我的3D世界中的摄像头,另一个用于控制P2 - 我不认为这是微不足道的。
此外,由于窗口仅更新其可见部分,并且我希望P2以尽可能高的分辨率不断更新,因此在第二个虚拟桌面上安装P2是有意义的。这使得交互问题更加困难。
我可以想到的一些解决方案:
制作合成窗口管理器
将实际光标放在P2上但获取光标位置的变化并使用此方法在3d世界中移动相机
如果他们有所帮助,我愿意接受其他捕获方法的建议。 一个例子是挂钩P2的DirectX或OpenGL输出,如有必要,可以在不活动时欺骗它。这可能会使P2最小化,但不能解决输入问题。
也许可以挂钩P2的输入功能?这甚至会被建议吗?
以下是一些图片来说明我的程序。
我已实现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);
在WM_INPUT
收到WndProc
消息并处理输入后,我运行此代码:
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());
}
}
我发现WS_EX_NOACTIVATE
停止切换到第二个桌面,但是当P2在同一个桌面上时,P2会被带到前台。
答案 0 :(得分:0)
我认为你可以使用WIN32API模拟点击并捕获窗口内容,我已经看到它在不同的3D“窗口”环境中完成,而且我已经看到它在Termina Server这样的东西中完成。
所以也许当“他们点击你,你向前点击”(进行坐标转换时)?
供您细读的一些链接: