Многослойное окно все еще получает сообщение WM_PAINT после вызова UpdateLayeredWindow

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

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

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

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

1 ответ

Решение

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

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

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

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

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

Другие вопросы по тегам