在双显示器设置中,监视器A的全屏模式在将窗口从监视器B移动到监视器B时中断
Fullscreen mode on monitor A in dual-monitor setup breaks when moving windows from monitor B onto it
我正在构建一个Win7/8/10 x64 Direct3D11桌面应用程序,允许用户在窗口和全屏模式之间切换(适当的专用全屏模式,而不仅仅是最大化窗口*)。在双显示器设置下,我遇到了一些问题。
切换本身是使用IDXGISwapChain::SetFullscreenState
手动执行的,并按预期工作:容纳最大份额窗口区域的监视器(我们称之为监视器A)进入专用全屏模式,而另一个监视器(监视器B)保持原样,允许用户与B上的窗口以及A上的全屏应用程序进行正常交互。
然而,如果B上的窗口被拖拽或调整大小,使其跨越到a上,则应用程序的全屏状态受到干扰:有时它只是恢复到窗口模式(使应用程序的内部跟踪变量不同步),有时它停留在准全屏模式,似乎拒绝进一步的模式切换,等等。如果在应用程序进入全屏模式之前,一个与a和B重叠的窗口获得焦点,也会发生同样的事情。
有什么方法可以防止这种情况吗?
我希望操作系统能尊重我的应用程序专用的全屏模式,并保持它在一个健壮的状态,即使其他窗口被拖到显示器上。我想要的行为类似于有一个"总是在顶部,最大化的无边框窗口"在它的代替,即有其他窗口只是"消失在它后面",不影响我的全屏窗口的状态。
我尝试了一些变通方法,如响应WM_KILLFOCUS
,并暂时将我的应用程序切换为"最大化无边界窗口",直到它再次接收WM_SETFOCUS
,但WM_KILLFOCUS
消息有一个延迟,在此期间,用户有时间将另一个窗口拖到然后仍处于全屏模式的区域,从而使我回到第一。
*我想要这个功能,而不是简单地使用一个最大化的无边界窗口(这也是一个支持的模式,顺便说一句)的原因是它允许更低的鼠标移动到渲染延迟,垂直同步控制(ON/OFF)等。简而言之,所有这些对这个应用程序的性质都很重要(它不是一个游戏)。
虽然不理想(理想的是有一种方法让操作系统本身正确处理这个问题),但我已经找到了一个合理的解决方案,我想我现在可以接受。它是问题("……")中提到的概念的一种变体。比如响应WM_KILLFOCUS
并暂时将我的应用程序切换到最大化无边界窗口…"),但没有严重的延迟问题:
当应用程序进入专用全屏模式时,它也通过调用 当收到这样的 这工作得很好,因为当你不与应用程序交互时,你并不真正关心它的响应性。这里最大的不便是在这些焦点转移时发生的模式切换闪烁,但考虑到替代方案,我发现为我想要完成的任务付出的代价是可以接受的(但无论如何-我会非常对更好的解决方案感兴趣)。SetCapture
来捕获鼠标。这不会影响用户与监视器B上的其他窗口交互的能力,但是它将确保任何这样的取消/激活交互-例如在另一个应用程序中单击鼠标-将在失去焦点之前向我的应用程序发送WM_LBUTTONDOWN
。重要的是,这是立即发生的,不像WM_KILLFOCUS
消息具有明显的延迟。WM_LBUTTONDOWN
消息时(在全屏时),应用程序检查点击是否发生在其屏幕区域之外。如果是这样,这意味着它即将失去焦点,从而使自己暴露于最初问题中提出的所有复杂情况。因此,它暂时退出专用的全屏模式,并以(视觉上相同的)无边界最大化窗口"取代"它。当应用程序恢复焦点时,它将返回专用全屏。
编辑1:值得注意的是,由于除了通过鼠标点击之外,还有其他方法可以使应用程序失去焦点,因此WM_KILLFOCUS
也被处理。
编辑2:我最近意识到处理
WM_BUTTONDOWN
消息是多余的。SetCapture
单独将确保WM_KILLFOCUS
消息被足够快地接收。
- 如何在Qt窗口小部件中使用QStringView(或QStringRef)
- 问:如何使用C++中的按钮从窗口打开窗口
- SDL 窗口不会弹出
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 如何在cpp文件之间切换窗口?在Qt中
- QuadTree只在窗口的右上角绘制
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 如何在C++中找到active directory中禁用和锁定的窗口帐户
- 处理闪烁窗口事件
- 如何通过按下第三个窗口中的按钮,将QString从一个窗口获取到另一个窗口
- 获取窗口监视器的唯一标识符
- 获取特定监视器的处理程序以在其中放置弹出窗口
- 限制辅助监视器中的窗口最大大小
- 错误的计数器路径,pdhAddCounter;窗口中的性能监视器
- 管理多个监视器上的多个窗口
- Qt 4.8调整窗口全分辨率监视器
- 在双显示器设置中,监视器A的全屏模式在将窗口从监视器B移动到监视器B时中断
- Win32 C++正在第二个监视器中创建窗口
- 在多个监视器上设置控制台窗口信息
- 每监视器dpi感知:黑色窗口故障与NVIDIA Optimus