c++winapidirect3d

can not see the EDIT control but can use it If I use ID2D1DeviceContext to clear the window?


I can create EDIT in winapi and If I want to draw something the EDIT will be covered?

If I delete swapChain->Present1(1, 0, &parameters); it will be ok. (if I just use ID2D1HwndRenderTarget to do the same thing it is all ok.).

this is the code:

#pragma once

#include "resource.h"
#include<d2d1.h>
#include<d2d1_1.h>
#include<D2DErr.h>
#include<d3d11.h>
#include<dxgi1_2.h>
#include<Windows.h>

#pragma comment(lib,"d3d11.lib")
#pragma comment(lib,"d2d1.lib")


ID3D11Device* device = NULL;
ID3D11DeviceContext* ctx = NULL;

IDXGIDevice* dxgiDevice = NULL;
IDXGIDevice1* dxgiDevice_1 = NULL;
IDXGIFactory2* dxgiFactory = NULL;


ID2D1Factory* factory = NULL;
ID2D1Device* d2dDevice = NULL;
ID2D1DeviceContext* context = NULL;

DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
IDXGISwapChain1* swapChain = NULL;

HWND hwnd = 0;

DXGI_PRESENT_PARAMETERS parameters{};




WNDPROC editProc = NULL;
LRESULT APIENTRY EditSubClassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    if (uMsg == WM_CHAR) {
        WCHAR ch = (WCHAR)wParam;
    }
    return CallWindowProc(editProc, hwnd, uMsg, wParam, lParam);
}

void init_x(HWND h) {
    hwnd = h;
    UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_DEBUG;
    D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1,D3D_FEATURE_LEVEL_11_0,D3D_FEATURE_LEVEL_10_1,D3D_FEATURE_LEVEL_10_0 };
    D3D_FEATURE_LEVEL featureLevel;

    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    hr = CoInitialize(NULL);
    hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &device, &featureLevel, &ctx);
    IDXGIDevice1* dxgiDevice = NULL;
    hr = device->QueryInterface(__uuidof(IDXGIDevice1), (void**)&dxgiDevice);
    hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factory);
    hr = device->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
    hr = D2D1CreateDevice(dxgiDevice, nullptr, &d2dDevice);
    hr = d2dDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &context);
    swapChainDesc.Width = 0;
    swapChainDesc.Height = 0;
    swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
    swapChainDesc.Stereo = false;
    swapChainDesc.SampleDesc.Count = 1;
    swapChainDesc.SampleDesc.Quality = 0;
    swapChainDesc.BufferCount = 2;
    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.Scaling = DXGI_SCALING_NONE;
    swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
    swapChainDesc.Flags = 0;

    IDXGIAdapter* dxgiAdapter = NULL;
    hr = dxgiDevice->GetAdapter(&dxgiAdapter);
    hr = dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), (void**)&dxgiFactory);
    hr = dxgiFactory->CreateSwapChainForHwnd(device, hwnd, &swapChainDesc, nullptr, nullptr, &swapChain);
    hr = dxgiDevice->QueryInterface(__uuidof(IDXGIDevice1), (void**)&dxgiDevice_1);
    hr = dxgiDevice_1->SetMaximumFrameLatency(1);
    ID3D11Texture2D* backBuffer = NULL;
    hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBuffer);
    D2D1_BITMAP_PROPERTIES1 properties1 = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
        D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE),
        96.0f, 96.0f);
    IDXGISurface* dxgiBackBuffer = NULL;
    hr = swapChain->GetBuffer(0, __uuidof(IDXGISurface), (void**)&dxgiBackBuffer);
    ID2D1Bitmap1* renderTargetBitmap;
    hr = context->CreateBitmapFromDxgiSurface(dxgiBackBuffer, &properties1, &renderTargetBitmap);

    context->SetTarget(renderTargetBitmap);


    context->BeginDraw();
    context->Clear(D2D1::ColorF(1, 1, 0, 1));
    context->EndDraw();

    swapChain->Present1(1, 0, &parameters);

    HWND hTextBox = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", NULL, WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | WS_BORDER, static_cast<int>(15), static_cast<int>(15), static_cast<int>(130), static_cast<int>(30), hwnd, (HMENU)50, (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
    NONCLIENTMETRICS ncm{};
    ncm.cbSize = sizeof(ncm);
    SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
    editProc = (WNDPROC)SetWindowLongPtr(hTextBox, GWLP_WNDPROC, (LONG_PTR)EditSubClassProc);

}

and this is the full example https://github.com/ljzj2/testedit


Solution

  • Just make a conclusion of Rendering with Direct2D on Windows 8

    On Windows 7 and earlier, you use a ID2D1HwndRenderTarget or another render target interface to render to a window or surface. Starting with Windows 8, we do not recommend rendering by using methods that rely on interfaces like ID2D1HwndRenderTarget because they won't work with Windows Store apps. You can use a device context to render to an Hwnd if you want to make a desktop app and still take advantage of the device context's additional features. However, the device context is required to render content in a Windows Store apps with Direct2D.