DirectX SwapChain с высотой и шириной, не равной 0, работает с прозрачным окном ошибочно - PullRequest
0 голосов
/ 30 октября 2019

У меня есть окно, в котором я удалил кадр, просто возвращая 0 из WM_NCCACLSIZE. Я вообще не хочу границы или тени. Затем я использовал SetWindowCompositionAttribute, чтобы размыть окно. Когда я устанавливаю нестандартный размер в моей цепочке подкачки DirectX, он действует очень хаотично. Способ решить эту проблему - вернуть кадр клиента. Это делает это проводное поведение, если кадр клиента удален. Кто-нибудь знает, как это сделать без рамки?

Нормальное поведение, но я хочу, чтобы оно работало без стандартной рамки: enter image description here

Это ошибочныете, я не мог их снимать с экрана: enter image description here enter image description here

Код:

WINCOMPATTRDATA compositionData{ 19, &accentPolicy, sizeof ACCENTPOLICY };
    const auto pSetWindowCompositionAttribute{ GetProcAddress(GetModuleHandleW(L"user32.dll"), "SetWindowCompositionAttribute") };
    if (!reinterpret_cast<BOOL(WINAPI*)(HWND, WINCOMPATTRDATA*)>(pSetWindowCompositionAttribute)(hwnd, &compositionData))
        throw std::runtime_error{ "Unable to setup the user interface.\n" };
    const D3D_FEATURE_LEVEL featureLevels[]{
        D3D_FEATURE_LEVEL_12_1, D3D_FEATURE_LEVEL_12_0, D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0,
        D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0
    };
    D3D_FEATURE_LEVEL featureLevel;
    RECT clientRect;
    GetClientRect(hwnd, &clientRect);
    DXGI_SWAP_CHAIN_DESC1 swapChain{ 0 };
    swapChain.SampleDesc.Count = 1;
    swapChain.Width = 200;
    swapChain.Height = static_cast<UINT>(clientRect.bottom - (clientRect.bottom * .65f));
    swapChain.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
    swapChain.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChain.BufferCount = 2;
    swapChain.Scaling = DXGI_SCALING_NONE;
    swapChain.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
    if (FAILED(D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT, featureLevels,
        6, D3D11_SDK_VERSION, &RootDevice3D, &featureLevel, nullptr)))
        throw std::runtime_error{ "Unable to create Direct3D Device.\n" };
    ComPtr<IDXGIDevice> dxDevice;
    RootDevice3D->QueryInterface(dxDevice.GetAddressOf());
    if (FAILED(D2D1CreateDevice(dxDevice.Get(),
        D2D1::CreationProperties(D2D1_THREADING_MODE_SINGLE_THREADED, D2D1_DEBUG_LEVEL_NONE,
            D2D1_DEVICE_CONTEXT_OPTIONS_NONE), &RootDevice)))
        throw std::runtime_error{ "Unable to create Direct2D Device.\n" };
    if (FAILED(RootDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &RootContext)))
        throw std::runtime_error{ "Unable to create Direct2D Device Context.\n" };
    ComPtr<IDXGIAdapter> dxAdapter;
    ComPtr<IDXGIFactory2> dxFactory;
    dxDevice.Get()->GetAdapter(dxAdapter.GetAddressOf());
    dxAdapter.Get()->GetParent(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(dxFactory.GetAddressOf()));
    if (FAILED(dxFactory->CreateSwapChainForHwnd(dxDevice.Get(), hwnd, &swapChain, nullptr, nullptr, &SwapChain)))
        throw std::runtime_error{ "Unable to create swap chain.\n" };
    ComPtr<IDXGISurface> dxSurface;
    ComPtr<ID2D1Bitmap1> rootBitmap;
    SwapChain->GetBuffer(0, __uuidof(IDXGISurface), reinterpret_cast<void**>(dxSurface.GetAddressOf()));
    RootContext->CreateBitmapFromDxgiSurface(dxSurface.Get(),
                                             D2D1::BitmapProperties1(
                                                 D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
                                                 D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM,
                                                                   D2D1_ALPHA_MODE_IGNORE)),
                                             rootBitmap.GetAddressOf());
    RootContext->SetTarget(rootBitmap.Get());

Этот код заставляет его работать как впервая картинка:

case WM_NCCALCSIZE:
    return DefWindowProcW(hwnd, msg, wparam, lparam);

Это код для ошибочных фотографий:

case WM_NCCALCSIZE:
        if (static_cast<bool>(wparam))
            return 0;
...