Search code examples
c++mfcstatusbar

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


Is there any benefits in using this code:

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;

Or this code:

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

Or:

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

Solution

  • The first and second code samples are identical. The documentation for CWnd::GetFont explains, how it is implemented:

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

    The third code snippet is different from the previous ones in that it queries the control for a device context. What CWnd::GetDC returns depends how the particular window class was registered. In the most common case, it will return the "common device context":

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

    In other words, in this case the device context you are retrieving may or may not have the desired font selected into it. As a general rule you should not rely on there being any particular graphics object selected into it.

    None of the operations are inherently expensive. You should profile your code to find out, where it spends most of its time. The code posted likely isn't going to show up.