0

谁能告诉我为什么在我的窗口中没有绘制任何内容。所发生的只是它在创建窗口时绘制窗口后面的任何内容。如果代码草率,请原谅我,我找不到任何可以帮助我学习 direct2d 1.1 的东西,所以它有点乱

#include "DemoApp.h"






// Provides the application entry point.
int WINAPI WinMain(
    HINSTANCE /* hInstance */,
    HINSTANCE /* hPrevInstance */,
    LPSTR /* lpCmdLine */,
    int /* nCmdShow */
    )
{

    // Use HeapSetInformation to specify that the process should
    // terminate if the heap manager detects an error in any heap used
    // by the process.
    // The return value is ignored, because we want to continue running in the
    // unlikely event that HeapSetInformation fails.
    HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);

    if (SUCCEEDED(CoInitialize(NULL)))
    {
        {
            DemoApp app;

            if (SUCCEEDED(app.Initialize()))
            {
                app.RunMessageLoop();
            }
        }
        CoUninitialize();
    }

    return 0;
}

// DemoApp constructor
DemoApp::DemoApp() :
    m_hwnd(NULL),
    Direct2DFactory(NULL),
    Screen(NULL),
    m_pLightSlateGrayBrush(NULL),
    m_pCornflowerBlueBrush(NULL),
    dxgiDevice(NULL),
    dxgiAdapter(NULL),
    dxgiFactory(NULL),
     Direct3DDevice(NULL),
     Direct3dContext(NULL),
     Direct2DDevice(NULL),
     DXGISwapChain(NULL),
     Direct2DBackBuffer(NULL)

{
}

// DemoApp destructor
// Releases the application's resources.
DemoApp::~DemoApp()
{
    SafeRelease(&Direct2DFactory);
    SafeRelease(&Screen);
    SafeRelease(&m_pLightSlateGrayBrush);
    SafeRelease(&m_pCornflowerBlueBrush);

}


HRESULT DemoApp::LoadBitmapFromFile(ID2D1DeviceContext *pRenderTarget,
                                    IWICImagingFactory2 *pIWICFactory,
                                    PCWSTR uri,
                                    UINT destinationWidth,
                                    UINT destinationHeight,
                                    ID2D1Bitmap1 **ppBitmap
                                    )
{


    IWICBitmapDecoder *pDecoder = NULL;
    IWICBitmapFrameDecode *pSource = NULL;
    IWICStream *pStream = NULL;
    IWICFormatConverter *pConverter = NULL;
    IWICBitmapScaler *pScalar = NULL;

    HRESULT hr = pIWICFactory->CreateDecoderFromFilename(
        uri,
        NULL,
        GENERIC_READ,
        WICDecodeMetadataCacheOnLoad,
        &pDecoder
        );

    if (SUCCEEDED(hr))
    {
        hr = pDecoder->GetFrame(0, &pSource);
    }

    if (SUCCEEDED(hr))
    {
        hr = pIWICFactory->CreateFormatConverter(&pConverter);
    }

    if(SUCCEEDED(hr))
    {
        hr = pConverter->Initialize(
            pSource,
            GUID_WICPixelFormat32bppPBGRA,
            WICBitmapDitherTypeNone,
            NULL,
            0.0f,
            WICBitmapPaletteTypeMedianCut
            );
    }

    if (SUCCEEDED(hr))
    {
        hr = pRenderTarget->CreateBitmapFromWicBitmap(
            pConverter,
            NULL,
            ppBitmap
            );
    }

    SafeRelease(&pDecoder);
    SafeRelease(&pSource);
    SafeRelease(&pStream);
    SafeRelease(&pConverter);
    SafeRelease(&pScalar);

    return hr;
}

void DemoApp::OpenFilePicker()
{


}

// Creates the application window and device-independent
// resources.
HRESULT DemoApp::Initialize()
{
    HRESULT hr;

    // Initialize device-indpendent resources, such
    // as the Direct2D factory.
    hr = CreateDeviceIndependentResources();

    if (SUCCEEDED(hr))
    {
        // Register the window class.
        WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
        wcex.style         = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc   = DemoApp::WndProc;
        wcex.cbClsExtra    = 0;
        wcex.cbWndExtra    = sizeof(LONG_PTR);
        wcex.hInstance     = HINST_THISCOMPONENT;
        wcex.hbrBackground = NULL;
        wcex.lpszMenuName  = NULL;
        wcex.hCursor       = LoadCursor(NULL, IDI_APPLICATION);
        wcex.lpszClassName = L"D2DDemoApp";

        RegisterClassEx(&wcex);








        // Because the CreateWindow function takes its size in pixels,
        // obtain the system DPI and use it to scale the window size.


        // The factory returns the current system DPI. This is also the value it will use
        // to create its own windows.
       Direct2DFactory->GetDesktopDpi(&dpiX, &dpiY);






        // Create the window.
        m_hwnd = CreateWindow(
            L"D2DDemoApp",
            L"Direct2D Demo App",
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            static_cast<UINT>(ceil(1920.f * dpiX / 96.f)),
            static_cast<UINT>(ceil(1080.f * dpiY / 96.f)),
            NULL,
            NULL,
            HINST_THISCOMPONENT,
            this
            );
        hr = m_hwnd ? S_OK : E_FAIL;
        if (SUCCEEDED(hr))
        {
            ShowWindow(m_hwnd, SW_SHOWNORMAL);
            UpdateWindow(m_hwnd);
        }

        /*  OPENFILENAME data = {0};

        wchar_t filename[256] = {0};

        data.lpstrInitialDir = L"C:\\Users\\Billy\\Documents\\Calendarpic";
        data.lStructSize = sizeof(data);
        data.lpstrFile = filename;
        data.nMaxFile = sizeof(filename);
        data.hwndOwner = m_hwnd;
        GetOpenFileName(&data);
        IFileOpenDialog *data2;

        */



    }

    return hr;
}

// Creates resources that are not bound to a particular device.
// Their lifetime effectively extends for the duration of the
// application.
HRESULT DemoApp::CreateDeviceIndependentResources()
{
    HRESULT hr = S_OK;
    D2D1_FACTORY_OPTIONS options;
    ZeroMemory(&options, sizeof(D2D1_FACTORY_OPTIONS));
    // Create a Direct2D factory.
    hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory1), &options, reinterpret_cast<void **>(&Direct2DFactory));

    if(SUCCEEDED(hr))
    {

        hr = CoCreateInstance(
            CLSID_WICImagingFactory,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_PPV_ARGS(&ImageFactory)
            );

    }



    return hr;
}


// Creates resources that are bound to a particular
// Direct3D device. These resources need to be recreated
// if the Direct3D device dissapears, such as when the display
// changes, the window is remoted, etc.
HRESULT DemoApp::CreateDeviceResources()
{
    HRESULT hr = S_OK;

    if (!Screen)
    {


        RECT rc;
        GetClientRect(m_hwnd, &rc);

        D2D1_SIZE_U size = D2D1::SizeU(
            rc.right - rc.left,
            rc.bottom - rc.top
            );

        // Create a Direct2D render target.
        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_9_3,
            D3D_FEATURE_LEVEL_9_2,
            D3D_FEATURE_LEVEL_9_1
        };

        UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;

        ID3D11Device *device;
        ID3D11DeviceContext *context;
        D3D_FEATURE_LEVEL returnedFeatureLevel;


           hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, creationFlags, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION,
                &device, &returnedFeatureLevel, &context);


        if(SUCCEEDED(hr))
        {
           hr = device->QueryInterface(__uuidof(ID3D11Device1), (void **)&Direct3DDevice);

        }

        if(SUCCEEDED(hr))
        {
           hr = context->QueryInterface(__uuidof(ID3D11DeviceContext1), (void **)&Direct3dContext);
        }

        if(SUCCEEDED(hr))
        {
            hr = Direct3DDevice->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice);

        }

        if(SUCCEEDED(hr))
        {
            hr = Direct2DFactory->CreateDevice(dxgiDevice, &Direct2DDevice);

        }

        if(SUCCEEDED(hr))
        {
            hr = Direct2DDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &Screen);
        }

        if(SUCCEEDED(hr))
        {
           hr = dxgiDevice->GetAdapter(&dxgiAdapter);
        }

        if(SUCCEEDED(hr))
        {
           hr = dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory));
        }   

        DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};

        swapChainDesc.Width = 0;
        swapChainDesc.Height = 0;
        swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
        swapChainDesc.Stereo = false;
        swapChainDesc.SampleDesc.Count = 1;
        swapChainDesc.SampleDesc.Quality = 0;
        swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        swapChainDesc.BufferCount = 2;
        swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
        swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
        swapChainDesc.Flags = 0;

        if(SUCCEEDED(hr))
        {

           hr = dxgiFactory->CreateSwapChainForHwnd(Direct3DDevice, m_hwnd, &swapChainDesc, nullptr, nullptr, &DXGISwapChain);
        }

        if(SUCCEEDED(hr))
        {

          hr = DXGISwapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer));
        }   



        if (SUCCEEDED(hr))
        {
            hr = CreateGridPatterBrush(Screen,&pGridPatternBitmapBrush);
        }


        D2D1_BITMAP_PROPERTIES1 bitmapProperties =    D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
            D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE), dpiX, dpiY);





        if (SUCCEEDED(hr))
        {
            // Create a gray brush.
            hr = Screen->CreateSolidColorBrush(
                D2D1::ColorF(D2D1::ColorF::LightSlateGray),
                &m_pLightSlateGrayBrush
                );
        }
        if (SUCCEEDED(hr))
        {
            // Create a blue brush.
            hr = Screen->CreateSolidColorBrush(
                D2D1::ColorF(D2D1::ColorF::CornflowerBlue),
                &m_pCornflowerBlueBrush
                );
        }

        if(SUCCEEDED(hr))
        {


            hr = LoadBitmapFromFile(Screen,
                ImageFactory,
                L"C:\\Users\\Billy\\Documents\\Calendarpic\\CalendarBaseAqua.bmp",
                1920,
                1080,
                &pBitmap
                );
        }  

          if (SUCCEEDED(hr))
        {
            hr = CreateGridPatterBrush(Screen, &pGridPatternBitmapBrush);
        }
           Screen->SetTarget(Direct2DBackBuffer);  
          SafeRelease(&dxgiBackBuffer);
       SafeRelease(&dxgiFactory);
       SafeRelease(&dxgiAdapter);
       SafeRelease(&dxgiDevice);
       SafeRelease(&context);
       SafeRelease(&device);
    }

    return hr;
}

HRESULT DemoApp::CreateGridPatterBrush(
    ID2D1DeviceContext *pRenderTarget,
    ID2D1BitmapBrush **ppBitmapBrush
    )
{
    // Create a compatible render target.

    ID2D1BitmapRenderTarget *pCompatibleRenderTarget = NULL;
    HRESULT hr = pRenderTarget->CreateCompatibleRenderTarget(
        D2D1::SizeF(1920.0f, 1080.0f),
        &pCompatibleRenderTarget
        );
    if (SUCCEEDED(hr))
    {
        // Draw a pattern.
        ID2D1SolidColorBrush *pGridBrush = NULL;
        hr = pCompatibleRenderTarget->CreateSolidColorBrush(
            D2D1::ColorF(D2D1::ColorF(0.93f, 0.94f, 0.96f, 1.0f)),
            &pGridBrush
            );
        if (SUCCEEDED(hr))
        {
            pCompatibleRenderTarget->BeginDraw();
            pCompatibleRenderTarget->FillRectangle(D2D1::RectF(0.0f, 0.0f, 10.0f, 1.0f), pGridBrush);
            pCompatibleRenderTarget->FillRectangle(D2D1::RectF(0.0f, 0.1f, 1.0f, 10.0f), pGridBrush);
            pCompatibleRenderTarget->EndDraw();

            // Retrieve the bitmap from the render target.
            ID2D1Bitmap *pGridBitmap = NULL;
            hr = pCompatibleRenderTarget->GetBitmap(&pGridBitmap);
            if (SUCCEEDED(hr))
            {
                // Choose the tiling mode for the bitmap brush.
                D2D1_BITMAP_BRUSH_PROPERTIES brushProperties =
                    D2D1::BitmapBrushProperties(D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP);

                // Create the bitmap brush.
                hr = Screen->CreateBitmapBrush(pGridBitmap, brushProperties, ppBitmapBrush);

                pGridBitmap->Release();
            }

            pGridBrush->Release();
        }

        pCompatibleRenderTarget->Release();
    }

    return hr;
}

// Discards device-dependent resources. These resources must be
// recreated when the Direct3D device is lost.
void DemoApp::DiscardDeviceResources()
{
    SafeRelease(&Screen);
    SafeRelease(&m_pLightSlateGrayBrush);
    SafeRelease(&m_pCornflowerBlueBrush);
    SafeRelease(&Direct2DBackBuffer);
    SafeRelease(&DXGISwapChain);      
    SafeRelease(&Direct2DDevice);
    SafeRelease(&Direct3dContext);
    SafeRelease(&Direct3DDevice);
}

// Runs the main window message loop.
void DemoApp::RunMessageLoop()
{
    MSG msg;

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

// This method discards device-specific
// resources if the Direct3D device dissapears during execution and
// recreates the resources the next time it's invoked.
HRESULT DemoApp::OnRender()
{
    HRESULT hr = S_OK;

    hr = CreateDeviceResources();

    if (SUCCEEDED(hr))
    {
        Screen->BeginDraw();

        Screen->SetTransform(D2D1::Matrix3x2F::Identity());

        Screen->Clear(D2D1::ColorF(D2D1::ColorF::White));

        D2D1_SIZE_F rtSize = Screen->GetSize();

        Screen->DrawBitmap(pBitmap,
            D2D1::RectF(0.0f, 0.0f, 1920, 1080));

        // Draw a grid background.
        int width = static_cast<int>(rtSize.width);
        int height = static_cast<int>(rtSize.height);



        hr = Screen->EndDraw();

        DXGI_PRESENT_PARAMETERS parameters = { 0 };
        parameters.DirtyRectsCount = 0;
        parameters.pDirtyRects = nullptr;
        parameters.pScrollRect = nullptr;
        parameters.pScrollOffset = nullptr;
        hr = DXGISwapChain->Present1(1, 0, &parameters);
    }

    if (hr == D2DERR_RECREATE_TARGET)
    {
        hr = S_OK;
        DiscardDeviceResources();
    }

    return hr;
}


//  If the application receives a WM_SIZE message, this method
//  resizes the render target appropriately.
void DemoApp::OnResize(UINT width, UINT height)
{
    if (Screen)
    {
        // Note: This method can fail, but it's okay to ignore the
        // error here, because the error will be returned again
        // the next time EndDraw is called.

    }
}

// Handles window messages.
LRESULT CALLBACK DemoApp::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    LRESULT result = 0;

    if (message == WM_CREATE)
    {
        LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
        DemoApp *pDemoApp = (DemoApp *)pcs->lpCreateParams;

        ::SetWindowLongPtrW(
            hwnd,
            GWLP_USERDATA,
            PtrToUlong(pDemoApp)
            );

        result = 1;
    }
    else
    {
        DemoApp *pDemoApp = reinterpret_cast<DemoApp *>(static_cast<LONG_PTR>(
            ::GetWindowLongPtrW(
                hwnd,
                GWLP_USERDATA
                )));

        bool wasHandled = false;

        if (pDemoApp)
        {
            switch (message)
            {
            case WM_SIZE:
                {
                    UINT width = LOWORD(lParam);
                    UINT height = HIWORD(lParam);

                }
                result = 0;
                wasHandled = true;
                break;

            case WM_DISPLAYCHANGE:
                {
                    InvalidateRect(hwnd, NULL, FALSE);
                }
                result = 0;
                wasHandled = true;
                break;

            case WM_PAINT:
                {
                    pDemoApp->OnRender();
                    ValidateRect(hwnd, NULL);
                }
                result = 0;
                wasHandled = true;
                break;

            case WM_DESTROY:
                {
                    PostQuitMessage(0);
                }
                result = 1;
                wasHandled = true;
                break;
            }
        }

        if (!wasHandled)
        {
            result = DefWindowProc(hwnd, message, wParam, lParam);
        }
    }

    return result;
}
4

0 回答 0