The MSDN page on DXGI提供了有关如何处理与桌面分辨率不同的全屏分辨率的说明。它表示在致电IDXGISwapChain::ResizeTargets()
之前致电IDXGISwapChain::SetFullscreenState()
以防止闪烁,等等。
它没有说明如何处理Alt-Enter,它在程序有机会自己调用IDXGISwapChain::SetFullscreenState()
之前调用IDXGISwapChain::ResizeTargets()
。如果在WM_SIZE
消息上调用后一种方法,则将发送另一条WM_SIZE
消息,可能导致无限循环。当按下alt-enter或alt-tab时,如何确保后者在前者之前被调用,并且模式切换一般无痛地发生?
答案 0 :(得分:7)
这将是非常棘手的......正确的处理方式是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。它还允许人们继续在第二个屏幕上工作而不会闪烁。性能方面,这是非常好的(大多数新游戏支持这种“无边界全屏”。)
可能有一颗银弹可以正确解决所有问题,但我还没有看到它。如果有一个更清洁/更好的解决方案,我会很好奇听到它。 “无边框全屏”似乎是目前的标准,但IIRC,Unity 5只允许Direct3D 11使用“无边框全屏”。
答案 1 :(得分:1)