Разница между GetDC() и BeginPaint()

#windows #winapi #mfc

#Windows #winapi #mfc

Вопрос:

Я работаю над пользовательским интерфейсом Win32. Я хочу знать разницу между GetDC и BeginPaint. Когда использовать какой API, а когда не использовать какой API.

Ответ №1:

GetDC просто возвращает дескриптор в контекст устройства, который можно использовать в любое время и в любом месте для создания собственного рисунка. С другой стороны, BeginPaint подготавливает окно к рисованию, а также предоставляет информацию о том, что следует нарисовать (например, нужно ли перекрашивать фон и прямоугольник, который необходимо нарисовать).

Примеры того, когда использовать каждый из них? BeginPaint чаще всего встречается внутри обработчиков WM_PAINT (MSDN: приложение не должно вызывать BeginPaint, кроме как в ответ на сообщение WM_PAINT. Каждый вызов BeginPaint должен иметь соответствующий вызов функции EndPaint.). GetDC можно использовать где угодно, поэтому, если вы хотите рисовать во внешнем окне. В принципе, в любое время, когда этого нет в обработчике WM_PAINT. BeginPaint и EndPaint также оказывают некоторое влияние на курсор. Прочитайте msdn для получения более подробной информации.

Комментарии:

1. Спасибо за ценный вклад. Если я использую GetDC внутри WM_PAINT вместо BeginPaint, вызовет ли это какие-либо проблемы

2. Прочитайте ответ от Ханса Пассанта, чтобы узнать подробности о том, почему это плохая идея. Когда вы создаете новый проект Visual Studio, вы получаете BeginPaint и EndPaint уже в обработчике WM_PAINT, зачем вам использовать GetDC?

Ответ №2:

GetDC() не является заменой для Begin EndPaint(). Если вы попытаетесь, вы обнаружите, что ваш поток пользовательского интерфейса начинает сжигать 100% ядра процессора, а ваш обработчик WM_PAINT вызывается снова и снова.

Самая большая из них — BeginPaint(), она очищает область обновления окна. Значение PAINTSTRUCT.rcPaint. WM_PAINT генерируется до тех пор, пока окно имеет грязный прямоугольник, созданный вызовом InvalidateRect() либо оконным менеджером, либо вашей программой, явно вызывающей его. BeginPaint() очищает его.

Комментарии:

1. Спасибо, это объясняет загрузку процессора, которую я получал без EndPaint.

2. Верно. EndPaint по сути вызывает ValidateRect. Вы можете либо отложить до DefWindowProc (который проверяет rect), либо просто вызвать ValidateRect самостоятельно.

Ответ №3:

BeginPaint предназначен для вызова только в ответ на WM_PAINT сообщение. Полученный им контекст устройства указывает на недействительную (подлежащую перерисовке) область окна. Затем он должен быть выпущен с помощью EndPaint .

GetDC может быть вызван в любое время. Контекст устройства, полученный с его помощью, указывает на всю клиентскую область окна. Чтобы освободить его, вы должны вызвать ReleaseDC .