【发布时间】:2014-01-23 10:39:20
【问题描述】:
我正在学习如何使用 Direct2D 和 DirectWrite。我编写了一个示例应用程序,它使用这些库直接在主(顶级)窗口中呈现内容。它工作正常。
现在我正在尝试为另一个应用程序中的子窗口重写绘画代码。原始代码使用 GDI 并且工作正常。但是当我将它转换为使用 Direct2D 时,什么都没有出现(子窗口显示为黑色)。
我已将绘制代码简化为客户区的简单填充。
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;
}
所有的 Direct2D 调用都以S_OK 成功,所以我有点不知道在哪里寻找问题。在这一点上,我可以看到我的工作实验和这个程序之间的唯一显着区别是,在这个程序中,我只在一个子窗口中使用 Direct2D。
所以我的问题是:在子窗口中使用 Direct2D 时是否存在我遗漏的问题?有什么提示可以进一步调试吗?
更新:我删除了静态参数以避免混淆。我正在用每一种颜料完全设置和拆除 Direct2D。只有一个绘制调用,具有真实大小。
如果我切换到软件渲染(通过在渲染目标属性中使用D2D1_RENDER_TARGET_TYPE_SOFTWARE),问题就消失了——我得到了预期的米色填充。
这让我怀疑我的显卡驱动程序已经过时了。但是我现在更新了我的图形驱动程序,但它仍然以同样的方式失败。当软件渲染按预期工作时,还有什么可能导致硬件渲染失败?
更新 2:我仍在尝试重现这是一个小型、独立的示例。同时,我注意到简单地启动 Spy++有时会导致窗口实际呈现到屏幕上(一次)。
【问题讨论】:
-
您是否覆盖了
WM_ERASEBKGND处理程序,这样它就不会一直让您的窗口空白? -
@Roger Rowland:是的,我的 WM_ERASKBKGND 处理程序什么都不做。如果我让它填充任意颜色,那么我会看到该颜色而不是 Direct2D Clear 命令所期望的米色填充。
-
好的,只是运行一些“显而易见”的东西——父窗口是否设置了
WS_CLIPCHILDREN样式? -
是的,两个祖先都有 WS_CLIPCHILDREN(用 Spy++ 确认)。
-
您是否验证过
OnPaint首先以非零大小调用?只是认为您的GetClientRect可能被调用得太快(例如,如果您使用虚拟大小创建然后移动/调整子窗口大小)。