Многослойное окно все еще получает сообщение WM_PAINT после вызова UpdateLayeredWindow - PullRequest
0 голосов
/ 08 июня 2009

В моем приложении есть несколько многоуровневых окон, которые используют UpdateLayeredWindow() для обработки их визуального представления. Согласно статье MSDN о многослойных окнах , «при использовании UpdateLayeredWindow() приложению не нужно отвечать на WM_PAINT или другие сообщения рисования». У них были одни и те же обработчики сообщений, что и у неуровневых окон, поэтому я решил, что просто рано вернусь из обработки WM_PAINT, если целью является многоуровневое окно.

Конечно, это вызвало одну серьезную проблему: если одно из многоуровневых окон получило сообщение WM_PAINT, входная очередь в конечном итоге будет заполнена бесконечным потоком WM_PAINT сообщений. Этот конечный результат имеет смысл, так как окно никогда не будет проверено, и поэтому оно будет думать, что ему нужно рисовать (я не должен возвращаться из обработчика без проверки или BeginPaint() ing и т. Д.), Но что не имеет смысл, поэтому он получил сообщение в первую очередь, поскольку он не влияет на окно, которое использовало UpdateLayeredWindow().

Это даже не произойдет надежно - просто время от времени, и не каждый раз, когда пиксели окна нуждаются в перерисовке. Разумность была восстановлена ​​путем возврата к DefWindowProc(), когда многослойное окно получило сообщение WM_PAINT, но я чувствую, что происходит что-то, чего я не понимаю. И учитывая, как редко эта проблема проявлялась, я боюсь, что это может быть просто скрытие еще более тонкой проблемы. Ожидается ли поведение окна, использующего UpdateLayeredWindow(), для получения случайного сообщения WM_PAINT? Имеет ли это значение, если я правильно с этим обращаюсь?

Дополнительная информация, если необходимо: окно вызывает UpdateLayeredWindow() сразу после создания, а затем остается само по себе (оно больше не вызывает, поскольку не изменяется). Использование C ++ и Win32 API, без MFC.

1 Ответ

1 голос
/ 08 июня 2009

Ранее я сталкивался с подобными проблемами, хотя моя память сейчас может быть немного ржавой.

Прежде всего, сохраните DefWindowProc. Когда в документах говорится, что вам не нужно отвечать, я бы взял это, чтобы означать полное игнорирование сообщения, а не предотвращение обработки по умолчанию.

Я лично испытал это по двум различным причинам. Одним из них было окно, которое фактически отправляло сообщения WM_PAINT (зло! Будьте осторожны!). Другой (IIRC) возник в результате определенных вызовов RedrawWindow. В обоих случаях я связал проблему с плохо написанным кодом, находящимся вне моего контроля, и никогда не возникало никаких ситуаций из-за простой передачи его в DefWindowProc.

Надеюсь, у вас будет такой же опыт!

Удачи. Я обнаружил, что многослойные окна плохо документированы и полны интересных предостережений и ошибок, но очень приятны, когда вы проработаете все изгибы.

...