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

  • 相关阅读:
    PHP流程控制考察点
    PHP运算符考察点
    PHP的魔术常量
    android窗体溢出WindowManager$BadTokenException: Unable to add window -- token null is not for an applica
    android网络访问异常java.lang.SecurityException: Permission denied (missing INTERNET permission?)
    快速排序算法思想
    播放Assets下的指定音频时,变成播放所有音频了
    python-01-Python环境搭建
    eclipse安装svn
    DOM children方法
  • 原文地址:https://www.cnblogs.com/mikewolf2002/p/2406840.html
Copyright © 2011-2022 走看看