使用 GetDC 方法而不是其他方法是否有性能改进?

Is there a performance improvements over using the GetDC approach instead of the others?

使用此代码有什么好处吗:

CClientDC dc(nullptr);
HFONT hFont = (HFONT)m_StatusBar.SendMessage(WM_GETFONT);
HGDIOBJ hOldFont = nullptr;
if (hFont != nullptr)
    hOldFont = dc.SelectObject(hFont);
cxNewWidth = dc.GetTextExtent(strCalendar).cx + kStatusBarIconWidth;

或此代码:

CClientDC dc(nullptr);
CFont *pFont = m_StatusBar.GetFont();
if (pFont != nullptr)
    dc.SelectObject(pFont);
cxNewWidth = dc.GetTextExtent(strCalendar).cx + kStatusBarIconWidth;

或者:

CDC *pDC = m_StatusBar.GetDC();
cxNewWidth = pDC->GetTextExtent(strCalendar).cx + kStatusBarIconWidth;

第一个和第二个代码示例相同。 CWnd::GetFont 的文档解释了它是如何实现的:

Sends the WM_GETFONT message to the window to retrieve the current font.

第三个代码片段与前面的代码片段的不同之处在于它向控件查询设备上下文。 CWnd::GetDC return 取决于特定 window class 的注册方式。在最常见的情况下,它将 return "common device context":

For common device contexts, GetDC assigns default attributes to the context each time it is retrieved.

换句话说,在这种情况下,您正在检索的设备上下文可能会或可能不会选择所需的字体。作为一般规则,您不应依赖于其中选择的任何特定图形对象。

None 的操作本质上是昂贵的。您应该分析您的代码以找出它花费大部分时间的地方。发布的代码可能不会显示。

如果要检索 m_StatusBar 的客户端 DC,则

CClientDC dc(m_StatusBar); 

是正确的做法。这样您就已经在 DC 中选择了正确大小的位图,您应该也可以保存 GetFont()。 使用 ClientDC(nullptr); 检索某些顶级 window 的 DC,然后选择 m_StatusBar 的字体对我来说似乎是错误的。

对于性能: GetDC() 方法在每次调用时分配一个新的 DC。因此,您必须为每个 GetDC() 调用提供 ReleaseDC()。 CClientDC 对象只是将 GetDC()ReleaseDC() 包装在 class 构造函数和析构函数中。一方面这更方便,另一方面,ClientDC 方法的性能比直接使用 GetDC()ReleaseDC() 稍微差一点,因为 [=27= 的创建和销毁] 实例。然而,这是微不足道的。