我可以在喷涂周期之外使用DC吗?
我的 window 的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的真实目标is to try to keep a persistent GDI+ Graphics object,以便我可以使用GDI +的一些性能更好的功能,这些功能取决于拥有持久的DC。

    在WM_PAINT消息处理期间,我想在 Canvas 上绘制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将与我的窗口的DC相同。这意味着它可以通过以下方式生存:
  • 快速用户切换
  • 合成已启用/已禁用
  • 主题切换
  • 主题禁用

  • 我在MSDN中找不到任何保证只要窗口存在的窗口就可以用于同一窗口的DC。

    注意:我没有使用双缓冲because i want to be a good developer, and do the right thing*
    有时,这意味着双重缓冲是不好的。

    最佳答案

    有异常(exception),但是通常,每次调用GetDCBeginPaint时,您可能会获得不同的DC。因此,您不应尝试将状态保存在DC中。 (如果您必须执行此操作以提高性能,则可以为一类窗口或特定窗口实例创建特殊的DC,但这听起来并不是您真正需要或想要的。)

    但是,大多数情况下,这些DC将是兼容的。它们将代表相同的图形模式,因此即使您获得了不同的DC,兼容的位图也应能正常工作。

    有Windows消息会告诉您图形模式何时更改,例如WM_DISPLAYCHANGEWM_PALETTECHANGED。您可以监听这些内容,然后重新创建缓存的位图。由于这些事件很少见,因此您不必担心此时重新创建缓存的位图对性能的影响。

    您还可以收到有关主题更改之类的通知。那些不会改变图形模式-它们是一个更高层次的概念-因此您缓存的位图仍应与您获得的任何DC兼容。但是,如果您想在主题更改时更改位图,则也可以收听WM_THEMECHANGED

    关于windows - Win32 : Does a window have the same HDC for its entire lifetime?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2074294/

    10-09 23:56
    查看更多