I'm learning how to use Direct2D and DirectWrite. I wrote a sample application that uses these libraries to render content directly in the main (top-level) window. It works fine.
Now I'm trying to rewrite the painting code for a child window in another application. The original code uses GDI and works fine. But when I convert it to use Direct2D, nothing appears at all (the child window appears black).
I've simplified the painting code down to a simple fill of the client area.
LRESULT PlotWnd::OnPaint(UINT, WPARAM, LPARAM, BOOL &) {
ATL::CComPtr<ID2D1Factory> pD2DFactory;
HRESULT hr = ::D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory);
assert(SUCCEEDED(hr));
ATL::CComPtr<ID2D1HwndRenderTarget> pRT;
RECT rc;
GetClientRect(&rc);
D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);
hr = pD2DFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(/* D2D1_RENDER_TARGET_TYPE_SOFTWARE */),
D2D1::HwndRenderTargetProperties(m_hWnd, size), &pRT);
assert(SUCCEEDED(hr));
pRT->BeginDraw();
pRT->Clear(D2D1::ColorF(D2D1::ColorF::Beige));
hr = pRT->EndDraw();
assert(SUCCEEDED(hr));
ValidateRect(nullptr);
return 0;
}
All of the Direct2D calls succeed with S_OK
, so I'm kind of at a loss as to where to look for the problem. At this point, the only significant difference I can see between my working experiment and this program is that in this one, I'm only using Direct2D in one child window.
So my questions are: Is there an issue that I'm missing when using Direct2D in a child window? Any tips for debugging this further?
Update: I've removed statics to avoid confusion. I'm completely setting up and tearing down Direct2D with each paint. There is exactly one paint call, with a real size.
If I switch to software rendering (by using D2D1_RENDER_TARGET_TYPE_SOFTWARE
in the render target properties), the problem goes away--I get the beige fill as expected.
This led me to suspect my graphics driver, which was out of date. But I've now updated my graphics driver, and it still fails in the same manner. What else could cause hardware rendering to fail when software rendering works as expected?
Update 2: I'm still trying to reproduce this is a small, self-contained example. In the mean time, I noticed that simply starting Spy++ will sometimes cause the window to actually render to the screen (one time).
WM_ERASEBKGND
handler so it doesn't keep blanking your window? – Roger RowlandWS_CLIPCHILDREN
style set? – Roger RowlandOnPaint
first gets called with a non-zero size? Just thinking that yourGetClientRect
may be called too soon (e.g. if you create with a dummy size and then move/size the child window). – Roger Rowland