Многослойное окно все еще получает сообщение 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.
Надеюсь, у вас будет такой же опыт!
Удачи. Я обнаружил, что многослойные окна плохо документированы и полны интересных предостережений и ошибок, но очень приятны, как только вы проработаете все перегибы.