加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

windows – Win32:窗口在整个生命周期内都有相同的HDC吗?

发布时间:2020-12-13 21:28:12 所属栏目:Windows 来源:网络整理
导读:我可以在油漆循环外使用DC吗? 我的窗户的DC是否保证永久有效? 我想弄清楚我的控件的设备上下文(DC)有效多长时间. 我知道我可以打电话: GetDC(hWnd); 获取我的控件窗口的设备上下文,但这是允许的吗? 当Windows向我发送WM_PAINT消息时,我应该调用BeginPain
我可以在油漆循环外使用DC吗?
我的窗户的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处理期间,德尔福认为wParam是一个DC,并继续在其上绘画.而MSDN表示WM_PAINT消息的wParam未使用.

为什么

我对HDC的真正目标是is to try to keep a persistent GDI+ Graphics object,这样我就可以使用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);
   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);
   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);
   EndPaint(h_hwnd,ps);
}

除了现在我相信只要应用程序正在运行,程序初始化后获得的DC i对于我的窗口将是相同的DC.这意味着它可以通过以下方式存活:

>快速用户切换
>组合启用/禁用
>主题转换
>主题禁用

我发现MSDN中没有任何内容可以保证只要窗口存在就会将相同的DC用于特定窗口.

注意:我没有使用双缓冲,because i want to be a good developer,and do the right thing.有时这意味着双缓冲很糟糕.

有一些例外,但一般情况下,每次调用GetDC或BeginPaint时都可能会得到不同的DC.因此,您不应该尝试在DC中保存状态. (如果你必须为了性能而这样做,你可以为一类窗口或特定的窗口实例创建特殊的DC,但它听起来并不像你真正需要或想要的那样.)

但是,大多数情况下,这些DC都是兼容的.它们将代表相同的图形模式,因此即使您获得不同的DC,兼容的位图也应该可以工作.

有一些Windows消息可以告诉您图形模式何时发生变化,如WM_DISPLAYCHANGE和WM_PALETTECHANGED.您可以监听这些,并重新创建缓存的位图.由于这些是罕见事件,因此您不必担心在此时重新创建缓存位图会对性能产生影响.

您还可以获取主题更改等内容的通知.那些不改变图形模式 – 它们是更高级别的概念 – 所以你的缓存位图应该仍然与你得到的任何DC兼容.但是如果你想在主题改变时改变位图,你也可以监听WM_THEMECHANGED.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读