Troubleshooting Windows Preview Handler Issues: GDI+ and Direct2D Integration
See the question and my original answer on StackOverflowThe 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
pRenderTarget->BeginDraw();
// Draw the white background
D2D1_COLOR_F clearColor = D2D1::ColorF(1, 1, 1); // White color
pRenderTarget->Clear(clearColor);
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);
pRenderTarget->EndDraw();
// 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
)