views:

418

answers:

2

I'm reading Introduction to 3D Game Programming with DirectX 10 to learn some DirectX, and I was trying to do the proposed exercises (chapter 4 for the ones who have the book).

One exercise asks to disable the Alt+Enter functionality (toggle full screen mode) using IDXGIFactory::MakeWindowAssociation.

However it toggles full screen mode anyway, and I can't understand why. This is my code:

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);
+1  A: 

I think the problem is this.

Since you create the device by yourself (and not through the factory) any calls made to the factory you created won't change anything.

So either you:

a) Create the factory earlier and create the device through it

OR

b) Retrieve the factory actually used to create the device through the code below.

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);

And call the function through that factory (after the SwapChain has been created)

pIDXGIFactory->MakeWindowAssociation(mhMainWnd, DXGI_MWA_NO_ALT_ENTER);

MSDN: IDXGIFactory

Daniel Dimovski
I already tried that (I've been googling for a while); unfortunately it doesn't work. All the calls are successful but alt tab still maximizes the window.
Andreas Bonini
Strange, I tried your code, and when using the factory that was used to create the device it worked for me.Here's your code rewritten, in case something was unclear in my answer: http://pastebin.com/sz2YzdZf
Daniel Dimovski
Using the same exact code you posted on pastebin alt-enter still maximizes the window. This is the exact code I used: http://koper.wowpanda.net/directx-code.rar
Andreas Bonini
Tried out your code, it works for me when I substitute DXGI_MWA_NO_ALT_ENTER with DXGI_MWA_NO_WINDOW_CHANGES. The function seems very sketchy, and dependent on the function used to create the device and/or swapchain.
Daniel Dimovski
DXGI_WMA_NO_ALT_ENTER seems bugged. Oh well, thanks.
Andreas Bonini
+1  A: 

I have the same problem, and

b) Retrieve the factory actually used to create the device through the code below.

doesn't help me also, possible because I have many Direct3D10 windows but IDXGIFactory::MakeWindowAssociation remembers it just for one. But invoking the function on WM_SETFOCUS or WM_ACTIVATE also didn't help by unknown reason.

So the one way i found is using low-level keyboard hook: see SetWindowsHookEx with WH_KEYBOARD_LL parameter. Later you can catch Alt+Enter by VK_RETURN virtual code with condition that (VK_LMENU|VK_RMENU|VK_MENU) is already pressed. After you've recognize this situation just return 1 instead of calling CallNextHookEx function.

dev_null
And don't forget to do this only for your window, because by default hook will be installed for entire system. 1. For example you may install the hook when your process becomes active and uninstall when it deactivates (see WM_ACTIVATEAPP message). 2. Or your may check in the hook if the foreground window is your window (see GetForegroundWindow WinAPI function)
dev_null
Wouldn't calling MakeWindowAssociation() each time a new device is created work? Or create a IDXGIFactory for each?
Daniel Dimovski