Как я узнаю, что дочерняя форма MDI визуально изменилась? - PullRequest
1 голос
/ 31 марта 2019

У меня есть приложение MDI WinForms, написанное на C #. Обычно видна только одна дочерняя форма MDI, а все остальные находятся в фоновом режиме. Содержание дочерних форм может иногда меняться в фоновом режиме (например, элемент управления веб-браузера может отображать страницу, которая динамически меняется каждые N секунд, элементы управления диаграммой заполняются данными с течением времени).

Я хочу показать небольшие предварительные просмотры дочерних форм, когда пользователь наводит указатель мыши или нажимает на специальную кнопку на панели инструментов основной формы. Я могу успешно использовать функцию PrintWindow, как описано здесь , чтобы делать скриншоты дочерних форм MDI. Это работает даже для неактивных дочерних форм. Единственная проблема состоит в том, что создание каждого снимка экрана может занять значительное время (около 100-120 мс), возможно, из-за сложной структуры форм, поэтому, если я делаю снимки экрана непосредственно перед тем, как я хочу показать предварительный просмотр, это создает заметную задержку особенно, когда есть много дочерних форм (например, 10-15).

Я хочу оптимизировать это и заново создавать скриншоты только тогда, когда это действительно необходимо. Вот что я имею в виду. Первоначально я бы создавал скриншоты для всех форм, сохранял их в «кэше» и показывал превью. Позже, когда мне нужно снова создать предварительный просмотр, я хотел бы как-то определить, что визуальное содержимое формы MDI изменилось (или ожидается изменение), и заново создать снимок экрана только в этом случае, а в противном случае использовать «кэшированный» снимок экрана.

Я попытался реализовать это путем переопределения функции WndProc класса дочерней формы и поиска некоторых сообщений, таких как WM_PAINT или WM_SETREDRAW. Но когда я регистрирую все сообщения, я не вижу ни WM_PAINT, ни WM_SETREDRAW, даже когда форма активна (на переднем плане) и элемент управления веб-браузера на ней постоянно обновляет свою страницу. Вероятно, эти события отправляются непосредственно в элементы управления формы, но не в саму форму.

Я не хочу обходить каждую форму и подключаться к «измененным» событиям всех элементов управления, потому что все они очень разные и не все имеют такие события уведомления.

Я полагаю, что каждый элемент управления, когда он хочет изменить свое визуальное представление, отправляет ОС уведомление о принудительном перекрашивании. Итак, есть ли способ обнаружить такое уведомление от какого-либо элемента управления внутри дочерней формы MDI?

UPDATE: Я обнаружил функцию WinAPI GetUpdateRect , которая должна возвращать прямоугольник, который необходимо перерисовать. Я подумал, что если он вернет непустой прямоугольник, это будет означать, что скриншот должен быть обновлен. Я пытался вызвать его до вызова PrintWindow, но он всегда возвращает пустой прямоугольник.

...