【问题标题】:Disable alt-enter in a Direct3D (DirectX) application在 Direct3D (DirectX) 应用程序中禁用 alt-enter
【发布时间】:2010-02-28 23:50:43
【问题描述】:

我正在阅读Introduction to 3D Game Programming with DirectX 10 以学习一些 DirectX,并且我正在尝试进行建议的练习(对于拥有这本书的人来说,第 4 章)。

一个练习要求使用 IDXGIFactory::MakeWindowAssociation 禁用 Alt+Enter 功能(切换全屏模式)。

但是无论如何它都会切换全屏模式,我不明白为什么。这是我的代码:

HR(D3D10CreateDevice(
        0,                 //default adapter
        md3dDriverType,
        0,                 // no software device
        createDeviceFlags, 
        D3D10_SDK_VERSION,
        &md3dDevice) );

IDXGIFactory *factory;
HR(CreateDXGIFactory(__uuidof(IDXGIFactory), (void **)&factory));
HR(factory->CreateSwapChain(md3dDevice, &sd, &mSwapChain));
factory->MakeWindowAssociation(mhMainWnd, DXGI_MWA_NO_ALT_ENTER);
ReleaseCOM(factory);

【问题讨论】:

  • MakeWindowAssociation 返回一个 HRESULT,因此将 HR() 包裹在该调用周围,以查看它是否因某种原因而失败。 (只是一个旁注,我认为它实际上并没有失败)
  • @Danial:已经尝试过了,没有运气。不过,我要开始赏金了。

标签: c++ directx direct3d directx-10


【解决方案1】:

我认为问题是这样的。

由于您自己(而不是通过工厂)创建设备,因此对您创建的工厂的任何调用都不会改变任何内容。

所以无论你是:

a) 提前创建工厂,通过它创建设备

b) 通过以下代码检索实际用于创建设备的工厂。

IDXGIDevice * pDXGIDevice;
HR( md3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice) );

IDXGIAdapter * pDXGIAdapter;
HR( pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter) );

IDXGIFactory * pIDXGIFactory;
pDXGIAdapter->GetParent(__uuidof(IDXGIFactory), (void **)&pIDXGIFactory);

并通过该工厂调用函数(在创建 SwapChain 之后)

pIDXGIFactory->MakeWindowAssociation(mhMainWnd, DXGI_MWA_NO_ALT_ENTER);

MSDN: IDXGIFactory

【讨论】:

  • 我已经尝试过了(我已经在谷歌上搜索了一段时间);不幸的是,它不起作用。所有调用均成功,但 alt 选项卡仍将窗口最大化。
  • 奇怪,我试过你的代码,当使用用于创建设备的工厂时,它对我有用。这是您重写的代码,以防我的回答不清楚:pastebin.com/sz2YzdZf
  • 使用您在 pastebin alt-enter 上发布的完全相同的代码仍然可以最大化窗口。这是我使用的确切代码:koper.wowpanda.net/directx-code.rar
  • 试用了您的代码,当我将 DXGI_MWA_NO_ALT_ENTER 替换为 DXGI_MWA_NO_WINDOW_CHANGES 时,它对我有用。该函数看起来很粗略,并且依赖于用于创建设备和/或交换链的函数。
【解决方案2】:

我也有同样的问题,

b) 通过以下代码检索实际用于创建设备的工厂。

对我也没有帮助,可能是因为我有很多 Direct3D10 窗口,但 IDXGIFactory::MakeWindowAssociation 只记住一个。但是在 WM_SETFOCUS 或 WM_ACTIVATE 上调用函数也没有帮助,原因不明。

所以我发现的一种方法是使用低级键盘挂钩:请参阅SetWindowsHookEx 和 WH_KEYBOARD_LL 参数。稍后您可以在 (VK_LMENU|VK_RMENU|VK_MENU) 已按下的条件下通过 VK_RETURN 虚拟代码捕获 Alt+Enter。识别出这种情况后直接返回 1 而不是调用 CallNextHookEx 函数。

【讨论】:

  • 不要忘记只为您的窗口执行此操作,因为默认情况下将为整个系统安装挂钩。 1. 例如,您可以在进程激活时安装挂钩,并在进程停用时卸载(参见 WM_ACTIVATEAPP 消息)。 2.如果前景窗口是你的窗口,或者你可以检查钩子(见GetForegroundWindow WinAPI函数)
  • 不会在每次创建新设备时调用 MakeWindowAssociation() 工作吗?或者为每个创建一个 IDXGIFactory?
猜你喜欢
  • 2010-12-08
  • 2011-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-25
  • 1970-01-01
  • 2022-01-17
相关资源
最近更新 更多