zoukankan      html  css  js  c++  java
  • Directx11教程(12) 禁止alt+enter全屏窗口

           在D3D11应用程序中,我们按下alt+enter键,会切换到全屏模式。有时候,我们在WM_SIZE中有一些代码,全屏时,会使得程序崩溃,比如之前教程的代码,就是如此。

         下面我们在D3DClass.cpp 中,增加代码,禁止alt+enter键全屏。有两种方法可以做到这个功能,下面我们分别贴出代码:

    第一种方法:

        D3DClass.cpp中修改Initialize函数,调用MakeWindowAssociation时候,使用SwapChain的内部接口工厂。

    注意:D3D11CreateDeviceAndSwapChain创建设备和交换链时候,内部会使用自己的接口工厂。

    具体代码如下:

    //Initialize函数包含完成D3D设置的所有代码。
    bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen,
        float screenDepth, float screenNear)
        { 
       …

       //在debug模式下,使得创建的设备支持debug.
        UINT createDeviceFlags = 0;
    #if defined(DEBUG) || defined(_DEBUG) 
        createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
    #endif

        // 创建交换链,设备以及设备上下文.
        result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL,createDeviceFlags, &featureLevel, 1,
            D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext);
        if(FAILED(result))
            {
            HR(result);
            return false;
            }

        //得到 D3D11CreateDeviceAndSwapChain函数内部使用接口工厂
        IDXGIDevice * pDXGIDevice;
        result = m_device->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice);

        if(FAILED(result))
            {
            HR(result);
            return false;
            }

        IDXGIAdapter * pDXGIAdapter;
        result = pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter);
        if(FAILED(result))
            {
            HR(result);
            return false;
            }

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

        //禁止alt+enter全屏
        pIDXGIFactory->MakeWindowAssociation(hwnd,DXGI_MWA_NO_WINDOW_CHANGES|DXGI_MWA_NO_ALT_ENTER  );

       // 得到交换链中的后缓冲指针.
        result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr);
        if(FAILED(result))
            {
            HR(result);
            return false;
            }

        return true;


        }


    第二种方法,我们分开创建device和swapchain

    代码如下:

    //Initialize函数包含完成D3D设置的所有代码。
    bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen,
    float screenDepth, float screenNear)
    {

    //不设置标志
    swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH ;

    // 设置feature level为D3D11
    // 如果显卡不支持D3D11,我们能够通过设置这个参数,使用D3D10,或者9.

    featureLevel = D3D_FEATURE_LEVEL_11_0;

    //在debug模式下,使得创建的设备支持debug.
    UINT createDeviceFlags = 0;
    #if defined(DEBUG) || defined(_DEBUG)
    createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
    #endif

    //分开创建device和交换链,可以屏蔽dxgi自动的hook alt+enter
    //注意的两点:如果用第一个参数用NULL,第二个参数为D3D_DRIVER_TYPE_HARDWARE,则后面创建swapchain
    //会fail,如果直接用adapter,不改变第二个参数,则会提示创建设备失败,adapter无效。

    result = D3D11CreateDevice(adapter,D3D_DRIVER_TYPE_UNKNOWN, NULL,createDeviceFlags, &featureLevel, 1,
        D3D11_SDK_VERSION, &m_device, NULL, &m_deviceContext );

    if(FAILED(result))
        {
        HR(result);
        return false;
        }

    //创建交换链
    result = factory->CreateSwapChain(m_device,&swapChainDesc, &m_swapChain);
    if(FAILED(result))
        {
        HR(result);
        return false;
        }

    //禁止DXGI监视消息队列,捕捉ALT+ENTER,在全屏和窗口模式之间切换
    factory->MakeWindowAssociation(hwnd,DXGI_MWA_NO_WINDOW_CHANGES|DXGI_MWA_NO_ALT_ENTER  );

    // 释放显示模式列表
    delete [] displayModeList;
    displayModeList = 0;

    //释放适配器输出.
    adapterOutput->Release();
    adapterOutput = 0;

    //释放适配器
    adapter->Release();
    adapter = 0;

    // 释放接口工厂.
    factory->Release();
    factory = 0;

    // 得到交换链中的后缓冲指针.
    result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr);
    if(FAILED(result))
    {
    HR(result);
    return false;
    }

    // 用后缓冲创建渲染目标视图.


    }

    详细代码,请看工程文件myTutorialD3D11_11和myTutorialD3D11_12

    代码下载:

    https://files.cnblogs.com/mikewolf2002/myTutorialD3D11.zip

  • 相关阅读:
    WCF Server Console
    Restart IIS With Powershell
    RestartService (recursively)
    Copy Files
    Stopping and Starting Dependent Services
    多线程同步控制 ManualResetEvent AutoResetEvent MSDN
    DTD 简介
    Using Powershell to Copy Files to Remote Computers
    Starting and Stopping Services (IIS 6.0)
    java中的NAN和INFINITY
  • 原文地址:https://www.cnblogs.com/mikewolf2002/p/2406840.html
Copyright © 2011-2022 走看看