我可以在油漆周期之外使用直流电吗?我的窗口的 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 未使用。
为什么
我的真正目标是尝试针对 HDC 保留持久 GDI+ 图形对象,以便我可以使用依赖于持久 DC 的 GDI+ 的一些性能更好的功能。
在 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 将用于特定窗口。
注意:我没有使用双缓冲,因为我想成为一名优秀的开发人员,并做正确的事。* 有时这意味着你的双缓冲是不好的。