c++ - 正确处理 Alt-Enter/Alt-Tab 全屏分辨率

标签 c++ windows directx direct3d dxgi

The MSDN page on DXGI提供有关如何处理不同于桌面分辨率的全屏分辨率的说明。它说在调用 IDXGISwapChain::SetFullscreenState() 之前先调用 IDXGISwapChain::ResizeTargets() 以防止闪烁等。

它没有说明如何处理 Alt-Enter,在程序有机会自己调用 IDXGISwapChain::ResizeTargets( )。如果在 WM_SIZE 消息上调用后一种方法,将发送另一条 WM_SIZE 消息,可能导致无限循环。如何确保在按下 alt-enter 或 alt-tab 时先于前者调用后者,并且一般情况下模式切换是无痛的?

最佳答案

这真的很棘手……正确的处理方式是 IDXGIFactory::MakeWindowAssociation ,据我所知,没有人成功使用过。无论如何,您可能都想尝试一下。

“正确”的答案是手动处理 Alt+Enter。因此,使用 MakeWindowAssociation 禁用 Alt+Enter 并亲自动手。首先,不需要捕获WM_SIZE。相反,监听 WM_ENTERSIZEMOVEWM_CAPTURECHANGEDWM_WINDOWPOSCHANGEDWM_EXITSIZEMOVE。这将使您不必处理 WM_SIZE 并仍然获得所有相关的窗口大小调整事件。 (执行此操作时,请同时阅读此问题:WM_ENTERSIZEMOVE / WM_EXITSIZEMOVE - when using menu, not always paired)

好的,假设一切顺利,按 Alt+Enter,您必须执行以下操作:使用 IDXGISwapChain::SetFullscreenState 将交换链设置为全屏然后调整你的交换链( IDXGISwapChain::ResizeBuffers )。默认情况下,您将获得一个交换链,它在调整大小之前尽可能接近窗口的当前分辨率。正确执行此操作的方法是首先枚举全屏分辨率,然后在全屏时强制使用您想要的分辨率。这听起来很丑陋,但它似乎是解决问题的最稳健的方法。

一般来说,真正的、独有的全屏模式不值得麻烦,因为当有人按 Alt+Tab 键时你总是会闪烁(如果发生模式切换你无法避免它,因为屏幕本身将不得不重新调整.) 一个更好的解决方案是使用全屏无边框窗口。您只需创建一个没有任何装饰的窗口类,使其全屏显示,然后将其放置在覆盖整个屏幕的位置即可。那么您根本不必担心 Alt+Enter 和 Alt+Tab。它还允许人们在第二个屏幕上继续工作而不会闪烁。就性能而言,这还不错(大多数新游戏支持“无边框全屏”。)

可能有一个 Elixir 可以正确解决所有这些问题,但我还没有看到。如果有更清洁/更好的解决方案,我真的很想听听。 “无边界全屏”似乎是当前的标准,IIRC,Unity 5 将只允许 Direct3D 11 的“无边界全屏”。

关于c++ - 正确处理 Alt-Enter/Alt-Tab 全屏分辨率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25369231/

相关文章:

C++11 局部命名引用返回值(xvalue)?

c++ - 在 else block 中和 if block 之后执行代码

windows - grep 在 Windows 批处理文件中

Python:在 Windows 上的 Ubuntu 上通过 Bash 运行 pygame

c++ - 如何在 DirectX11 中正确创建聚光灯?

opengl - 三角形是GPU的限制还是其他渲染路径?

c++ - 使用 `size_t` 作为计数器的类型

C++ 入门第 5 版 : Stream iterators and Sales_item

c++ - CScrollView 只滚动大面积的部分区域

C++ 3D 游戏引擎