WinAPI: пропуск BeginPaint & EndPaint в WM_PAINT приводит к 100% использованию процессора

0

При обработке сообщения WM_PAINT я опускал вызовы BeginPaint и EndPaint, а загрузка процессора достигала 100%. Почему это?

Я также использую рабочие потоки... но они делают что-то другое и, похоже, не влияют на этот вопрос.

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

Извините, если я похож на идиот - я новичок в WinAPI, C++ и просто в мире логики вообще...

благодаря

  • 0
    Если вы новичок в C ++, есть ли какая-то особая причина, по которой вы вообще используете WinAPI? В настоящее время относительно мало причин использовать его напрямую, кроме как для поддержки существующих программ, построенных на его основе.
  • 1
    Я ожидаю, что Begin / Endpaint используются для указания ОС, что сообщение WM_PAINT действительно обработано. Поэтому, если вы не используете эти вызовы, ОС продолжает сообщать вашему приложению, что ему нужно что-то нарисовать ...
Показать ещё 1 комментарий
Теги:
winapi
wm-paint

3 ответа

8
Лучший ответ

Это совершенно нормально. Windows генерирует сообщение WM_PAINT, когда область обновления окна не пуста. То, что вы должны сделать, это снова пометить его пустым. Вы делаете это, например, путем вызова Begin/EndPaint().

Если вы этого не сделаете, то Windows немедленно генерирует еще одно сообщение WM_PAINT, все еще пытаясь освободить область обновления. Ваша нить будет записывать 100% -ное ядро, просто обрабатывая сообщения WM_PAINT и фактически не выполняя работу. Возможно, вы на самом деле рисуете, Windows просто не знает, что вы нарисовали, и не пытается угадать.

Использование Begin/EndPaint() - это очень разумный способ выполнить эту работу. Это не единственный способ, вы также можете вызвать ValidateRect() или ValidateRgn(). Пока вы "новичок в winapi", я очень рекомендую вам сделать это обычным способом.

  • 0
    Понятно, но что, если бы я использовал, скажем, OpenGL вместо обычного способа GDI? Нужно ли мне вызывать функции glWhatEver между BeginPaint () / EndPaint ()? (У меня есть некоторые основания в OpenGL, так что портирование этого на C ++, по крайней мере, несколько достижимо)
  • 0
    Множество уроков по opengl, нет смысла заново изобретать это для себя.
3

Не уверен, что это так, но startpaint и endpaint также проверяют обратную область окна, если вы их не используете, тогда окна не знают, что вы перерисовали эту область. Вы можете вызвать функцию ValidateRect, чтобы сообщить о том, что окно было перерисовано,

Не уверен, что это поможет в вашем случае, вы можете узнать больше о

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

1

GDI выдает сообщение WM_PAINT для обновления части окна. BeginPaint/EndPaint() сообщает gdi, что обработчик выполняет эту работу. В случае отсутствия BeginPaint() для указанной области, пока окно не будет обновлено (кем-либо), будут созданы сообщения WM_PAINT. Именно по этой причине вам нужен BeginPaint/EndPaint() в обработчике WM_PAINT и в отсутствие которого вы видите высокую загрузку процессора.

GetDC() не является заменой Begin + EndPaint() из-за причины, упомянутой в моем предыдущем абзаце.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню