c++direct2dwinappcreatewindowex

'BeginDraw' in conjunction with D2D1 causes an error


I'm trying to clear the background of a window created with CreateWindowEx with the code separated into separate classes, with the use of D2D1. Here's the code.

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
    switch (msg) {
    case WM_PAINT:
        graphics->BeginDraw();
        graphics->EndDraw();
        break;

    case WM_CREATE:
        window->onCreate();
        break;

    case WM_DESTROY:
        window->onDestroy();
        ::PostQuitMessage(0);
        break;

    default:
        return ::DefWindowProc(hwnd, msg, wparam, lparam);
    }

    return NULL;
}

^ Window.cpp

bool Graphics::init(HWND windowHandle) {
    HRESULT hRes = D2D1CreateFactory(
        D2D1_FACTORY_TYPE_SINGLE_THREADED,
        &factory
    );

    if (hRes != S_OK) return false;

    RECT wCS;
    GetClientRect(windowHandle, &wCS);

    hRes = factory->CreateHwndRenderTarget(
        D2D1::RenderTargetProperties(),
        D2D1::HwndRenderTargetProperties(windowHandle, D2D1::SizeU(wCS.right, wCS.bottom)),
        &renderTarget
    );

    if (hRes != S_OK) return -1;
    return true;
}

void Graphics::ClearScreen(float r, float g, float b) {
    renderTarget->Clear(D2D1::ColorF(r, g, b));
}

^ Graphics.cpp

void BeginDraw() { renderTarget->BeginDraw(); }
void EndDraw() { renderTarget->EndDraw(); }

^ Graphics.h

My error occurs as soon as the window opens, just before it crashes. The BeginDraw() is responsible for it, as removing it from WM_PAINT resolves the issue, but that is not a viable option.

The error:

Exception thrown: read access violation. this was nullptr.

It is specified to be on the line void BeginDraw() { ... } in Graphics.h.

Notable things (Not important):

I've been trying to find a solution to this over the past several days, but I don't know what most of the code I read means, so I apologise for my lack of knowledge.

I presume the issue is BeginDraw() is being called before the graphics have initialised, but I'm not sure how to prevent that.

Thank you for any suggestions what so ever.


Solution

  • The problem is the graphics object being used for BeginDraw is a different object to the one which was initialised. It needs to be the same object.