Почему Windows посылает сообщение WM_PAINT?

Тема в разделе "WASM.BEGINNERS", создана пользователем amvoz, 4 янв 2009.

  1. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Еще раз повторяю: в данном случае не ты определяешь когда будет перерисована область окна, а система! Когда она просит тебя перерисовать область окна ты ее должен перерисовать, а как ты ее рисуешь - систему не касается, будь то вывод текста, квадратиков или чего нибудь еще.
    Под 'данным случаем' имеется ввиду именно такой случай, когда система указывает что делать. Она говорит - нарисуй содержимое окна (и присылает сообщение WM_PAINT), и ты рисуешь. Она может сказать - в твоем окне нажали левую кнопку мыши (в процедуру прийдет сообщение WM_LBUTTONDOWN), среагируй на это как-нибудь! И ты можешь среагировать - опять же вывести текст, или проиграть звук, или вообще сделать выход из программы, но для этого нужно ввести в процедуру соответствующий обработчик.
    Еще раз: вместо DrawText может быть что угодно, сообщение WM_PAINT все равно прийдет, что означает, что пора выполнить его обработку - в твоем коде обработка заключается в вызове DrawText, но на этом месте может быть практически все что угодно.
    Теперь я себя ощущаю идиотом, потому что все это написал с мобильника.
     
  2. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    653
    Ввиду хронического непонимания друг друга делаю вывод, что Windows устроена таким образом, что периодически шлёт всем окнам сообщения WM_PAINT, кои окнами либо игнорируются, либо окна как-то на них реагируют в зависимости от функции-обработчика окна.
    Тему можно закрывать, спасибо всем неравнодушным к чужой проблеме.
     
  3. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    Не периодически, а тогда, когда в этом есть необходимость.

    P.S. Не тупи, рано тебе делать выводы о внутреннем устройстве виндовс.
     
  4. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    653
    А как Windows определяет есть необходимость или нет?
    Что в моей программе такого, что Windows определила: твоей программе периодически необходимо слать сообщение WM_PAINT? Я прошу лищь указать на строчку в тексте прораммы или директиву какую-нибудь показать и всё. Или эта тайна за семью печатями? Такое впечатление, будто я на святая святых позарился.

    Итак: что?

    Из сообщений KeSqueer я понял, что мой случай характеризуется, как данный. А данный это тот, при котором "система указывает что делать" а "система указывает что делать" в данном случае. А даннный, этот тот (см. предыдущее предложение).
    И я же ещё и туплю. Нормально. Ну, дело ваше всех.
     
  5. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Ну вот примеры
    1) Когда ты перетаскиваешь своё окно частично за экран видна только его часть, остальное не прорисовано. Если ты попытаешься вытащить окно обратно получишь WM_PAINT.
    2) При перетаскивании других окон над своим получишь WM_PAINT.
    3) При изменении размеров окна снова WM_PAINT.

    Дело в том что окна не хранятся в системе как битмапы (так памяти не напасёшься), а перерисовываются по мере необходимости.

    Если обработчик WM_PAINT не будет завершён вызовом ValidateRect система будет постоянно отсылать WM_PAINT.

    При необходимости ты сам можешь послать WM_PAINT через SendMessage или InvalidateRect.
     
  6. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    653
    ...На второй круг обсуждение уже пошло...
    По первым трём пунктам. Уже писали мне это. И я в ответ писал, что я ни один из этих трёх пунктов не делаю.
    Просто программа нарисовывает окно и всё. И я не пытаюбсь его изменить. Не перетаскиваю и поверх его ничего не затаскиваю. Моё окно статично, понимаете?
    Просто сижу и всё. А Windows раз- и послала сообщение WM_PAINT программе. С чего бы это? А потом текст нарисовался.
     
  7. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    Обычно используется BeginPaint/EndPaint, а не ValidateRect
     
  8. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Partner
    Зачем эти тормозные BeginPaint/EndPaint? DC содержится в wparam (а уменя обычно ещё и в отдельной переменной), область перерисовки rcPaint - GetUpdateRect, что ещё нужно?

    Об этом написано в OpenGL SuperBible.

    amvoz
    В WindowsXP где-то в реестре по-моему есть флажок "Автоматическое обновление рабочего стола". Погугли как его отключить.
     
  9. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    murder
    BeginPaint/EndPaint - это не обязательно, но удобно

    1. Прячется каретка (если она есть), иначе это нужно делать самому.
    2. Отрисовывается background. (если определена дефолтная кисть для класа окна)
    3. Устанавливает область перерисовки (аналогично GetUpdateRect,)
     
  10. kero

    kero Модератор SOURCES & 2LZ

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    Что-что?
    Это вы о WM_PAINT?
    А может, код какой покажите, чтоб с ValidateRect да с hDC из wParam?
    А то ведь банальное top-level окно получает WM_PAINT с wParam=lParam=0 :)
     
  11. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    kero
     
  12. kero

    kero Модератор SOURCES & 2LZ

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    murder
    После этого как-то нет доверия и к остальному. Так что приговоры вроде
    - следовало бы подкрепить реальным кодом, а не "аргументами" вроде
    А может, вы вовсе и не WM_PAINT имели ввиду, а, скажем, WM_ERASEBKGND ? :)
     
  13. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Я ещё хочу попробовать. :) Иногда получается работать с людьми нетривиальной пробиваемости. :)
    amvoz
    Вообще-то пунктов не только три. Их много. Решающий пункт в Вашем случае, когда система шлёт WM_PAINT, - это создание окна. Вы создали окно? Вот и шлёт Вам система WM_PAINT. Если какое-нибудь приложение выполнит InvalidateRect (NULL, NULL, TRUE), то опять таки всем окнам будет послано WM_PAINT. Но(!) это абсолютно не означает, что система шлёт это сообщение, как Вы говорите, периодически.
    Возражения?
     
  14. Blackbeam

    Blackbeam New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2008
    Сообщения:
    960
    Bitfry писал, что в отладчике видно, что текст отрисовывается до того, как окно получает сообщение WM_PAINT. Никто точно не знает, как текст вообще отрисовывается и где хранится эта картинка, были разные мнения на этот счёт...
    Пытался менять строку и посылать WM_PAINT с помощью SendMessage... облом, а InvalidateRect думаете сработает?

    tut05 с человеческим лицом... обратите внимание, что хэндл шрифта - глобальная переменная, иначе он не устанавливается... такая же ф. бывает иногда с некоторыми структурами, не знаю почему...
     
  15. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    653
    Да какие у меня могут быть возражения? Только, наверное, Вы хотели сказать не "создали окно", а "нарисовали окно", ибо сообщение номер F поступает в программу после вызова функции ShowWindow...
    Стоп...
    А! Я разобрался! Вот отрывок текста программы!

    invoke ShowWindow, hwnd,SW_SHOWNORMAL
    invoke UpdateWindow, hwnd

    А во строчка отсюда
    http://www.wasm.ru/article.php?article=1001004
    "Вызовите Invalidaterect или UpdateWindow, чтобы Windows послала сообщение WM_PAINT вашему окну."

    Всё! По функции ShowWindow вызывается UpdateWindow, благодаря которой и посылается WM_PAINT!
    Вот теперь всё! Ну, вот, собственно... Именно о тыкании в эту строчку носом я и просил.
    Теперь тему точно можно закрывать. Всем спасибо и до свидания.
     
  16. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    653
    А я наблюдаю и пишу, что после... Испробуем интереса ради?
     
  17. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Blackbeam
    Волшебство.

    amvoz
    Как определил, что после?
     
  18. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    653
    Вот так.
    Загружаем программку, о котрой веду речь в OllyDbg, ставим бряк на 0041119 (по этому адресу находится первая команда функции-обработчика сообщений). Жмём на F9 24 раза. Ровно 24. После этого смотрим на стек и видим значение F (второй аргумент оконной функции). Текста в окошке, которое будет на мониторе нет.
    А в 25-ый раз когда Вы нажмёте на F9, появится текст.

    То есть сперва оконная функция через стек получит оговорённое собщение, а потом уже только отрисуется текст.
     
  19. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    amvoz
    Да нет. Сказал именно то, что хотел сказать. Правда стоит дополнить, что окно, разумеется, должно быть видимым. Т.е. если Вы создадите окно с установленным стилем WS_VISIBLE, то окну автоматически будет послано WM_PAINT. Соответственно в этом случае ShowWindow+UpdateWindow не нужны.
    Через стек - это, конечно, грубо сказано, но... разумеется потом. Вы же вызываете DrawText в обработчике этого сообщения. Вот он и отрисовывается только после обработки сообщения.
     
  20. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    amvoz
    Сказали же уже, окно создал - создал, тогда получи WM_PAINT. Что-то снова не ясно?
    Обычно сначала изучают программирование окон, и после лезут в отладчик. Тут же не написав ни одной проги лезут ломать.