Search code examples
c++windowswinapidirect2d

Creating D2D1 Factory and Hwnd Render Target


I successfully created an empty window that would open and sit there until I closed it. Next, I wanted to try using Direct 2-D to draw something simple to that window. I created a class that would initialize Direct 2-D and then draw to the window, but after I added this class, my window would no longer open. After fiddling around with it a bit, it is now opening but then freezing and I get a message saying "a problem occurred causing the program to misbehave," and a button to "close program."

The window went from not opening to opening and then giving me the error after I added the return false if not s_ok seen below

//creating factory
HRESULT d2dFactHRes = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &Direct2DFactory);
    if (!S_OK)
        return false;

    //creating render target.
    HRESULT RenTargHRes = Direct2DFactory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, D2D1::PixelFormat(), 0.0F, 0.0F, D2D1_RENDER_TARGET_USAGE_NONE, D2D1_FEATURE_LEVEL_DEFAULT), D2D1_HWND_RENDER_TARGET_PROPERTIES(), &pRT);
    if (!S_OK)
        return false;

I put a break point to try and check the return value of the EndDraw() function, and when I started the debugger, I got an error saying "unhandled exception occured at 0x00E4264F, an access violation occurred while reading 0x00000000 from location 0xC0000005"

I think this error occurred in the BeginDraw function before it got to the break point.

void Graphics::BeginDraw()
{
    pRT->BeginDraw(); //pRT is pointer to render target.
}

I have no idea what this means. I assume something wasn't in memory that it was trying to read?

I'd appreciate any advice. Thanks.


Solution

  • The issue is that (presumably) your initialization code never runs to completion. It's the if (!S_OK) return false; statement that bails out early, right after creating the device factory. S_OK is defined as 0, !0 is always true (as your compiler warned you, in vain).

    The net effect is, that pRT never gets a pointer assigned, and the first time you dereference it, the system pops up the access violation dialog.

    What you need to do instead is evaluate the return values (HRESULT's). In COM programming it is common to use the SUCCEEDED, and FAILED macros, e.g.:

    if ( FAILED( d2dFactHRes ) )
        return false;