Есть ли улучшения производительности по сравнению с использованием подхода GetD C вместо других? - PullRequest
0 голосов
/ 19 апреля 2020

Есть ли какие-либо преимущества в использовании этого кода:

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;

Ответы [ 2 ]

3 голосов
/ 19 апреля 2020

Первый и второй примеры кода идентичны. Документация для CWnd :: GetFont объясняет, как это реализовано:

Отправляет сообщение WM_GETFONT в окно для получения текущего шрифта.

Третий фрагмент кода отличается от предыдущих тем, что он запрашивает у элемента управления контекст устройства. Что CWnd :: GetD C возвращает, зависит от того, как был зарегистрирован конкретный класс окна. В наиболее распространенном случае он возвращает «общий контекст устройства» :

Для общих контекстов устройства GetDC назначает атрибуты по умолчанию для контекста при каждом получении .

Другими словами, в этом случае контекст устройства, который вы извлекаете, может иметь или не иметь желаемый шрифт, выбранный в нем. Как правило, вам не следует полагаться на то, что в него был выбран какой-либо конкретный графический объект.

Ни одна из операций не является дорогостоящей. Вы должны профилировать свой код, чтобы узнать, где он проводит большую часть своего времени. Размещенный код, скорее всего, не появится.

0 голосов
/ 21 апреля 2020

Если вы хотите получить клиент D C из m_StatusBar, то

CClientDC dc(m_StatusBar); 

- правильный способ сделать это. Таким образом, у вас уже есть правильный размер растрового изображения, выбранный в D C, и вы, вероятно, также сможете сохранить GetFont (). Извлечение D C из некоторого окна верхнего уровня с использованием ClientDC(nullptr); и последующий выбор шрифта m_StatusBar в нем кажется мне неправильным.

Для производительности: подход GetDC() выделяет новый D C каждый раз, когда это называется. Поэтому вы должны указать ReleaseDC() для каждого из вызовов GetDC(). Объект CClientD C просто оборачивает GetDC() и ReleaseDC() в конструктор класса и деструктор. С одной стороны, это более удобно, с другой стороны, производительность подхода ClientD C немного хуже, чем использование GetDC() и ReleaseDC() напрямую из-за создания и уничтожения экземпляра класса. Однако это ничтожно мало.

...