【发布时间】:2011-01-05 16:01:47
【问题描述】:
我可以在油漆周期之外使用直流电吗? 我的窗口的 DC 是否保证永久有效?
我正在尝试计算我的控件的设备上下文 (DC) 的有效期。
我知道我可以打电话:
GetDC(hWnd);
获取我的控件窗口的设备上下文,但这是否允许?
当 Windows 向我发送 WM_PAINT 消息时,我应该调用 BeginPaint/EndPaint 以正确确认我已绘制它,并在内部清除无效区域:
BeginPaint(hWnd, {out}paintStruct);
try
//Do my painting
finally
EndPaint(hWnd, paintStruct);
end;
但是调用 BeginPaint 也会在 PAINTSTRUCT 结构中返回一个 DC。这是我应该作画的 DC。
我在文档中找不到任何内容表明 BeginPaint() 返回的 DC 与我从 GetDC() 获得的 DC 相同。
尤其是现在,在桌面合成时代,在我在 BeginPaint 之外获得的 DC 上绘画是否有效?
似乎有两种方法可以让我在绘画周期中使用 DC 进行绘画:
dc = GetDC(hWnd);
BeginPaint(&paintStruct);
有第三种方法,但它似乎是我开发的 Borland Delphi 的一个错误。
在WM_PAINT 处理期间,Delphi 认为 wParam 是一个 DC,并继续在其上进行绘制。而 MSDN 说 WM_PAINT 消息的 wParam 未使用。
为什么
我的真正目标is to try to keep a persistent GDI+ Graphics object 对抗 HDC,这样我就可以使用 GDI+ 的一些性能更好的功能,这些功能依赖于持久性 DC。
在 WM_PAINT 消息处理期间,我想在画布上绘制 GDI+ 图像。下面的nieve版本很慢:
WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(m_hwnd, ps);
Graphics g = new Graphics(ps.hdc);
g.DrawImage(m_someBitmap, 0, 0);
g.Destroy();
EndPaint(h_hwnd, ps);
}
GDI 包含一个执行速度更快的位图,一个 CachedBitmap。但是不加思索地使用它不会带来性能优势:
WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(m_hwnd, ps);
Graphics g = new Graphics(ps.hdc);
CachedBitmap bm = new CachedBitmap(m_someBitmap, g);
g.DrawCachedBitmap(m_bm, 0, 0);
bm.Destroy();
g.Destroy();
EndPaint(h_hwnd, ps);
}
性能提升来自于创建 CachedBitmap 一次,所以程序初始化:
m_graphics = new Graphics(GetDC(m_hwnd));
m_cachedBitmap = new CachedBitmap(b_someBitmap, m_graphcis);
现在在绘制周期:
WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(m_hwnd, ps);
m_graphics.DrawCachedBitmap(m_cachedBitmap, 0, 0);
EndPaint(h_hwnd, ps);
}
除了现在我相信只要应用程序正在运行,我在程序初始化后获得的 DC 将与我的窗口相同。这意味着它可以通过:
- 快速用户切换
- 组合启用/禁用
- 主题切换
- 主题禁用
我在 MSDN 中找不到任何东西可以保证只要特定窗口存在,相同的 DC 就会用于该窗口。
注意:我没有使用双缓冲,because i want to be a good developer, and do the right thing。 * 有时这意味着双缓冲不好。
【问题讨论】: