Возможно ли, что окно не будет обновляться сразу и что оно вместо этого будет накапливать все вызовы перерисовки и ждать «позже», когда вызывается WM_PAINT?
Нет, это не кейс.
Что вы описали, в основном, как работает , и вот что произойдет, если вы просто позвонили InvalidateRect
. Клиентская область окна была бы просто отмечена как «недействительная», и сообщение WM_PAINT
было бы отправлено, если в очереди не будет сообщений, ожидающих обработки очереди. Единственное, что ваше описание ошибочно, заключается в том, что призывы рисования/перерисовки не «накапливаются». Если вы позвоните по номеру InvalidateRect
20 раз, вы получите сообщение только 1 WM_PAINT
. Идея этой «ленивой» стратегии живописи заключается в том, что живопись - это низкоприоритетная, но дорогостоящая операция, и эта «нетерпеливая» живопись приведет к кучке потраченных впустую циклов - вы можете нарисовать что-то, что только будет перекрашено через несколько микросекунд позже.
Но тот факт, что вы позвонили UpdateWindow
, меняет все это. Эта инструкция заставляет перерисовать сразу. Как the documentation говорит:
Функция UpdateWindow обновляет клиентскую область указанного окна, отправив сообщение WM_PAINT
к окну, если область обновления окна не является пустым. Функция отправляет сообщение WM_PAINT
непосредственно в оконную процедуру указанного окна, минуя очередь приложения. Если область обновления пуста, сообщение не отправляется.
Первоначальный звонок в InvalidateRect
помечен как клиентская область окна как недействительный, создавая непустую область обновления для окна. Последующий вызов UpdateWindow
заметил, что это окно нуждается в перекраске, и принудительно перерисовал сразу, отправив процедуру окна сообщение WM_PAINT
напрямую, минуя обычную очередь сообщений.
Как правило, нет причин для звонка UpdateWindow
. Пусть диспетчер окон обрабатывает отправку писем, когда он определяет, что это подходящее время для перерисовки. Единственный раз, когда вам понадобится позвонить UpdateWindow
, - это если вы делаете что-то вроде дорогостоящего вычисления в ответ на другое сообщение. Это блокирует поток пользовательского интерфейса, не обрабатывая любые другие сообщения, включая сообщения WM_PAINT
. Это плохой вещь по многим причинам. Один из них заключается в том, что он не позволяет вашему окну перекрашиваться.Еще одна серьезная проблема заключается в том, что это приводит к тому, что ваше приложение перестает отвечать на запросы пользователей, поскольку оно перестает отвечать на входные сообщения. Если вам нужно сделать некоторые трудоемкие вычисления, сделайте это на фоновом потоке.
Но там есть несколько случаев, когда вы можете позвонить по номеру UpdateWindow
. Я использовал его несколько раз, и он работает точно так, как описано выше. Я понятия не имею, почему у вас возникают проблемы с его работой; вы забыли включить образец кода, который воспроизводит проблему в вашем вопросе.
это не похоже, чтобы сделать это, когда я ставлю InvalidateRect затем UpdateWindow внутри WM_COMMAND
Это абсолютно не важно, что это делается в обработчике WM_COMMAND
сообщения. Вы можете делать это где угодно. Важно то, что вы сначала заставляете часть клиентской области окна стать недействительной (что вы делаете с InvalidateRect
), а затем принудительно перерисовываете перерисовку этой недопустимой области (которую вы выполняете с UpdateWindow
).
Если бы я должен был предположить, как к вашей проблеме, было бы, что ваш перекрашивать является получение сразу срабатывает, окно является получение перекрасили, но к тому времени, вы получите, чтобы увидеть его, еще перекрасить уже и ваши изменения окрашиваются. Это может указывать на ошибку в вашей логике обработки WM_PAINT
, но, как я уже сказал, мы не можем ее видеть, так что это всего лишь предположение.
С вашей нынешней формулировкой вы привлекаете только тех, кто знает подкраски и порядок наизусть. Если вы хотите, чтобы у других была попытка попробовать, вы можете прочитать [ask] и предоставить [mcve], который, я думаю, возможен в строке или 10 кода. – CodeCaster
Если вы читаете, как работает живопись, вы поймете, почему именно так, так как она спроектирована так, что картина возникает, когда очередь сообщений пуста, а сообщения WM_PAINT синтезируются для любых недопустимых регионов. –
@DavidHeffernan: [UpdateWindow] (https://msdn.microsoft.com/en-us/library/dd145167.aspx) * «[...] отправляет сообщение WM_PAINT непосредственно в оконную процедуру указанного окна, * * в обход очереди приложений **. * – IInspectable