为什么我的代码不切换到全屏模式?

问题描述 投票:0回答:1

[基本上,我是通过使用DXGI_SWAP_CHAIN_DESCGetCurrentProcess处设置伪造的HWND,但是如果我在下一个字段中选择了false,那为什么还要紧呢?

我的问题是,为什么我的程序在笔记本电脑上不显示蓝屏或黑屏。这是纯C语言中的代码:

#define COBJMACROS
#include <Windows.h>
#include <d3d11.h>
#include <dxgi.h>
#include <stdbool.h>

#ifdef _DEBUG
#define D3DFLAGS D3D11_CREATE_DEVICE_DEBUG
#endif

#define STRINGIFY(x) L#x
#define TOSTRING(x) STRINGIFY(x)

__declspec(thread) HRESULT lasthresult;

#define DIAG MessageBox(0,TOSTRING(__LINE__),L"", MB_ICONERROR), exit(lasthresult)

#define CHECK_HRESULT(fname, ...) ((lasthresult=fname(__VA_ARGS__)) != S_OK ? DIAG : 0)

#define CHECK_HRESULT_INTERFACE(This, fname, ...) ((lasthresult=(This)->lpVtbl->fname(This, __VA_ARGS__)) != S_OK ? DIAG : 0)

((WinMain))()
{
    IDXGIFactory1* pFact; IDXGIAdapter* pAdapter;
    IDXGIOutput* pOutput; UINT numModes; DXGI_MODE_DESC* pOurMode = 0;
        CHECK_HRESULT(CreateDXGIFactory1, &IID_IDXGIFactory1, &pFact);
        CHECK_HRESULT_INTERFACE(pFact, EnumAdapters, 0, &pAdapter);
        CHECK_HRESULT_INTERFACE(pAdapter, EnumOutputs, 0, &pOutput);

        CHECK_HRESULT_INTERFACE(pOutput, GetDisplayModeList, DXGI_FORMAT_R8G8B8A8_UNORM, 0, &numModes, 0);

        DXGI_MODE_DESC* displayDescs = _alloca(numModes * sizeof * displayDescs);

        CHECK_HRESULT_INTERFACE(pOutput, GetDisplayModeList, DXGI_FORMAT_R8G8B8A8_UNORM, 0, &numModes, displayDescs);

        for (UINT mode = 0; mode < numModes; ++mode)
            if (displayDescs[mode].Width == 1920 && displayDescs[mode].Height == 1080) pOurMode = displayDescs + mode;
        if (pOurMode == 0) DIAG;

        IDXGISwapChain* pchain; ID3D11Device* pdevice; ID3D11DeviceContext* pcontext;
        CHECK_HRESULT(D3D11CreateDeviceAndSwapChain, pAdapter, D3D_DRIVER_TYPE_UNKNOWN, 0, D3DFLAGS, 0, 0, D3D11_SDK_VERSION, (DXGI_SWAP_CHAIN_DESC[1]) {
            *pOurMode, { 1,0 }, DXGI_USAGE_BACK_BUFFER, 2, GetCurrentProcess(), false, DXGI_SWAP_EFFECT_DISCARD, 0,
        },& pchain, &pdevice, 0, &pcontext);
        ID3D11Texture2D* pBackBuffer; ID3D11RenderTargetView* g_pRenderTargetView;
        //CHECK_HRESULT_INTERFACE(pchain, GetBuffer, 0, &IID_ID3D11Texture2D, &pBackBuffer);
        const D3D11_TEXTURE2D_DESC textDesc[1] = { {.Width = 1920, .Height = 1080, .MipLevels = 1, .ArraySize = 1,
            .Format = DXGI_FORMAT_R8G8B8A8_UNORM, .SampleDesc.Count = 1, .Usage = D3D11_USAGE_DEFAULT, .BindFlags = D3D11_BIND_RENDER_TARGET, .CPUAccessFlags = D3D11_CPU_ACCESS_WRITE,} };
        CHECK_HRESULT_INTERFACE(pdevice, CreateTexture2D, textDesc, 0, &pBackBuffer);
        CHECK_HRESULT_INTERFACE(pdevice, CreateRenderTargetView, pBackBuffer, 0, &g_pRenderTargetView);
        //ID3D11DeviceContext_OMSetRenderTargets(pcontext, 1, &g_pRenderTargetView, 0);
        const D3D11_VIEWPORT viewports[1] = { {.Width = 1920, .Height = 1080, .MinDepth = 0.0f, .MaxDepth = 1.0f,} };
        ID3D11DeviceContext_RSSetViewports(pcontext, 1, viewports);
        const float deepblue[] = { 0.0f, 0.0f, 0.0f, 1.0f };
        ID3D11DeviceContext_ClearRenderTargetView(pcontext, g_pRenderTargetView, deepblue);

        Sleep(1000);
}
c directx directx-11
1个回答
0
投票

GetCurrentProcess返回当前过程对象的伪句柄,并且(在当前Windows版本中)为整数值-1。它不指向任何内容,在需要进程句柄的任何上下文(GetProcessTimesGetProcessMitigationPolicy等)之外没有任何意义。重要的是,这不是窗口句柄,并且绝不能转换为窗口句柄。甚至进程的完全限定句柄也不能转换为窗口句柄-这两个对象由Windows操作系统的不同部分管理。

进程句柄是由Windows操作系统的核心组件NT内核创建和管理的。它们代表了内核执行进程切换,管理句柄表和组织线程所需的所有属性。没有内核,无法创建进程句柄。

窗口句柄由用户空间中的User32 DLL创建和管理。用户模式组件和NT内核之间存在一些合作,但是它非常有限-大多数交互发生在User32.dll和Win32k.sys之间。窗口句柄可以不与内核交互而存在,但是可能确实处于内核模式(这是实现定义)中的某些状态。

这意味着您已经破坏了DXGI_SWAP_CHAIN_DESC结构的合同之一-您的窗口句柄(HWND)无效。因为没有窗口句柄,所以DXGI不会显示任何内容,也不会显示任何内容给用户。即使您的交换链仅在全屏模式下使用,窗口句柄也是required

要解决此问题,请使用CreateWindowCreateWindowEx创建一个窗口,并将函数返回的HWND传递给交换链描述符。

© www.soinside.com 2019 - 2024. All rights reserved.