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_ENTERSIZEMOVE
、WM_CAPTURECHANGED
、WM_WINDOWPOSCHANGED
和 WM_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/