See the question and my original answer on StackOverflow

The number one problem is your call to PostQuitMessage(0). It will stop the message pump that the parent window and your window uses, so it will stop the previewing process.

So, the first time you click an .abcd file everything works. The second time, the system asks your first instance to unload, and then you stop the message pump, and the file cannot be previewed. But the system is resilient and the next time, it will work again, etc.

So you really must stop calling PostQuitMessage(0).

As for artifacts you mention, you shouldn't mix GDI+ and Direct2D like you do. Everything you can do in GDI+ you should be able to do with pure Direct2D code.

For example here is the red ellipse drawn with Direct2D (zero GDI+ code):

// Begin drawing with Direct2D

// Draw the white background
D2D1_COLOR_F clearColor = D2D1::ColorF(1, 1, 1); // White color

int radius = 50;
int centerX = pRenderTarget->GetSize().width / 2;
int centerY = pRenderTarget->GetSize().height / 2;
D2D1_ELLIPSE ellipse = D2D1::Ellipse(D2D1::Point2F(centerX, centerY), radius, radius);
pRenderTarget->FillEllipse(ellipse, pRedBrush);

// End drawing with Direct2D

Presuming you have created a pRedBrush after the render target creation, something like this:

pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(1, 0, 0), &pRedBrush);

And you get antialiasing for free.

If you really want to use GDI+ and HDC, then read this Direct2D and GDI Interoperability Overview and create an ID2D1DCRenderTarget instead of an ID2D1HwndRenderTarget.

Other remarks:

  • The ID2D1Factory can be cached in per-process
  • When you destroy the window, release the associated Direct2D render target (and other resources created on it) first. In Unload in this code.
  • You should check for all errors (for example the result to EndDraw)