Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > Раставим все точки над обновлением окна


Автор: Rapalex 3.5.2007, 15:46
Всё таки я ощутил нехватку знаний в рисовании окна. Давайте сделаем такой топик чтоб не стыдно было его закрепить всерху. Как мне кажется рисовать на обработчике события WM_PAINT вполне логично. А вот обновлять всё окно постоянно не логично, логичней оновить только тот участок в котором произошли изменения.

Для этого существует ряд функций:
Код

    Invalidate

    InvalidateRect
    InvalidateRgn

    ValidateRect
    ValidateRgn

    UpdateWindow


    RedrawWindow


Invalidate
Делает всю область окна инвалидной и всё окно будет перерисованопри следующем сообщении WM_PAINT.
В ходной параметр bErase отвечает за то что будет присланно сообщение WM_ERASEBKGND и будет окно закрашено своим цветом (это зависит от обработчика на событии WM_ERASEBKGND).

InvalidateRect и InvalidateRgn
Делает тоже что и Invalidate только инвалидейти не всё окно а только определённый прямоугольник или регион.

ValidateRect и ValidateRgn
Валидейтит прямоугольник или регион на окне, я так понял отменяет операцию Invalidate.

UpdateWindow
Посылает окну сообщение WM_PAINT.

RedrawWindow
Может многое, в том числе по разному перерисовать окно включая его не клиентскую часть.



Это почти всё что я знаю про обновление окон. И всётаки не незнаю какие функции как себя ведут во время работы программы.


RedrawWindow - вроде не прекращается до те пор пока окно не перерисуется.

InvalidateRect и InvalidateRgn - просто тупо инвалидейт и программа продолжает работать.

UpdateWindow - не прекратит работу пока окно не будет отрисовано.

Но я во всём этом я не совсем уверен уверен и хотелось бы услышать другие мнения.

В частности я вообще понять такой расклад. К примеру на нажатии левой кнопки мыши я инвалидейтю окно и больше ничего, а окно всётаки перерисовывается, в какой момент почему и ктопослал обработчик для меня это тайна.

Люди раскажите всё что знаете о тонкастях отрисовки.


Это мой самый длинный вопрос на этом форуме.

Автор: ama_kid 3.5.2007, 15:57
Цитата(Rapalex @  3.5.2007,  15:46 Найти цитируемый пост)
В частности я вообще понять такой расклад. К примеру на нажатии левой кнопки мыши я инвалидейтю окно и больше ничего, а окно всётаки перерисовывается, в какой момент почему и ктопослал обработчик для меня это тайна.

Вот что написано в MSDN по http://msdn2.microsoft.com/en-us/library/ms534893.aspx:
Цитата
The system sends a WM_PAINT message to a window whenever its update region is not empty and there are no other messages in the application queue for that window.

Т.е. если ты сделал части окна инвалидейт и дальше ничего не делаешь - система автоматом посылает WM_PAINT твоему окну из-за того, что его невалидный регион ненулевой... 

Автор: Greeen 3.5.2007, 15:58
Насколько я знаю (опять же, не уверен) Invalidate(Rect/Rgn) помечает область окна невалидной и посылает ему в очередь сообщений WM_PAINT. Чтобы немедленно перерисовать эту область необходимо вызвать еще UpdateWindow()

Автор: Rapalex 3.5.2007, 17:02
А UpdateWindow() не выполнится пока окно не перерисуется???

Автор: Rapalex 4.5.2007, 09:37
Цитата(Greeen @  3.5.2007,  15:58 Найти цитируемый пост)
посылает ему в очередь сообщений WM_PAINT. Чтобы немедленно перерисовать эту область необходимо вызвать еще UpdateWindow()


Так UpdateWindow() тоже посылает сообщение перерисовки!!! В чём разница?

Добавлено через 44 секунды
А если не вызвать UpdateWindow(), тогда когда окно перерисуется?

Автор: Greeen 4.5.2007, 10:12
The UpdateWindow function updates the client area of the specified window by sending a WM_PAINT message to the window if the window's update region is not empty.
Похоже что если область окна не отмечена как невалидная, то не перерисуется.

Добавлено через 3 минуты и 55 секунд
Цитата(Rapalex @  4.5.2007,  09:37 Найти цитируемый пост)
А если не вызвать UpdateWindow(), тогда когда окно перерисуется? 

Перерисуется, но только когда в очереди не останется больше других сообщений.

Добавлено через 5 минут и 16 секунд
Вот еще что нашел по UpdateWindow:
If there is any invalid part of the client area, UpdateWindow sends the WM_PAINT message for the specified window directly to the window procedure. 

Автор: ama_kid 4.5.2007, 11:19
Цитата(Rapalex @ 4.5.2007,  09:37)
Цитата(Greeen @  3.5.2007,  15:58 Найти цитируемый пост)
посылает ему в очередь сообщений WM_PAINT. Чтобы немедленно перерисовать эту область необходимо вызвать еще UpdateWindow()


Так UpdateWindow() тоже посылает сообщение перерисовки!!! В чём разница?

Разница  в том, что Invalidate(Rect\Rgn) не посылает WM_PAINT окну - это делает сама система, когда очередь сообщений окна очищается...
Цитата
А если не вызвать UpdateWindow(), тогда когда окно перерисуется?
Как только из его очереди извлечется WM_PAINT, в данном контексте, к примеру, - после освобождения очереди и когда система пошлет данное сообщение окну...

Лично я воспринимаю Invalidate(...) - как "подготовку материала для заказа" процесса перерисовки, а UpdateWindow - собственно как процесс "выполнения заказа перерисовки" окна, причем немедленное и безусловное выполнение... Если не вызывать UpdateWindow - система "выполнит заказ" автоматически, но только когда сочтет это удобным (когда очередь сообщений очистится)

Автор: Greeen 4.5.2007, 11:37
ama_kid, полностью согласен

Автор: Rapalex 4.5.2007, 11:38
ama_kid, понял философию, спс.

Цитата(Greeen @  4.5.2007,  10:12 Найти цитируемый пост)
If there is any invalid part of the client area, UpdateWindow sends the WM_PAINT message for the specified window directly to the window procedure. 

А где ты это нашол?

Автор: Greeen 4.5.2007, 11:59
http://msdn2.microsoft.com/en-us/library/ms534883.aspx

Автор: Rapalex 5.5.2007, 09:53
Greeen, спасибки...

А что особенного в RedrawWindow? В смысле когда надо ей пользоватся а когда инвалидейтить?

Автор: Greeen 5.5.2007, 12:19
А это по желанию. И по потребностям, т.к. у RedrawWindow гораздо больше возможностей. Вот подробности: http://msdn2.microsoft.com/en-us/library/ms534900.aspx

Автор: Rapalex 8.5.2007, 10:15
А есть ли ещё какие-нибудь функции для оновления окон?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)