WM_PAINT моргает

Тема в разделе "WASM.WIN32", создана пользователем murtix, 26 фев 2005.

  1. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    cresta

    я помню, как ты ругался

    Я и сейчас начну ругаться.

    Моя win'да такое окно выдает:[​IMG]
     
  2. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    М-м-м..



    И что это за окно такое?

    Откуда оно?

    Что за подпись хочет?



    Самым обычным ml+link делалось, из пакета masm v8.



    Выкинь к черту свою Win'ду



    Если сомневаешься, вот исходник, не хотел засорять, но раз у тебя подозрения, что я тут что-то решил намутить, смотри :dntknw:





    [​IMG] _1478281649__TestProject.zip
     
  3. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Попытался сделать себе такое предупреждение. Отправил сам себе этот файл, и добился получения такого предупреждения. При попытке запуска прямо из почтового клиента. Проверял в Бате и в Аутлуке.



    По-моему тебе просто надо проверить настройки безопасности, либо не запускать прямо exe файлы. Сохрани и потом запускай.



    А получать какие-то сертификаты, цифровые подписи и собирать всякого рода поручителей - мне эти мелкософтные приколы нахрен не нужны.
     
  4. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    cresta

    Если сомневаешься, вот исходник

    Это совсем другое дело.



    Попробуй убрать SetTimer и из WM_INITDIALOG и вся красота и стройность пропадет.

    Я думаю в диалогах WM_PAINT и WM_ERASEBKGND ведут себя не так как в обычных окнах.
     
  5. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257




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



    Попробую в обычном окне сделать.



    А если без таймера, то как (по какому событию) обновлять?

    Ну например тот же график обновляется с какой-то периодичностью или он один раз должен быть нарисован и всё?
     
  6. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
  7. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    cresta

    если без таймера, то как (по какому событию) обновлять?

    Если в обычном окне, то по WM_PAINT, если в диалоге, то надо подумать.



    например тот же график обновляется с какой-то периодичностью или он один раз должен быть нарисован и всё?

    Это не ко мне. Зависит от задачи.



    окно ведет себя несколько иначе

    Совсем другое дело.

    Только в WM_ERASEBKGND не надо GetDC/ReleaseDC, т.к. hdc уже есть в wParam, + на первой странице мы договорились, что в тривиальных случаях в обработчике WM_ERASEBKGND нет необходимости рисовать, достаточно вернуть не ноль.
     
  8. EGOiST

    EGOiST New Member

    Публикаций:
    0
    Регистрация:
    20 мар 2004
    Сообщения:
    7
    хмм а какие различия между окном и диалогом то?
     
  9. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257




    Тут неувязочка выходит, то, что нам подсовывают в wParam'e, отличается от того, что мы поимеем от GetDC. И окно перерисовывается совершенно по иному. В чем дело - пока не понял.

    Может ты раскусишь, примерно опишу разницу:

    1.В WM_ERASEBKGND вместо push eax (hdc от GetDC) сделай push wParam.(казалось бы тоже hdc)

    2.Сожми окно до минимума взможного и затем медленно растягивай.

    3.Чем объяснить, что старый рисунок стирается не весь??? В коде PaintProc ведь весь rect заливается по новой. Откуда старые ошмётки, которые смазывают рисунок?



    То, что подходит только GetDC (wParam и GetWindowDC не катят) - обнаружил случайно. Отчего разница? Почему на wParam'ном DC не стирается старый рисунок при помощи FillRect. Пробовал и в memDC заливать - та же ерунда.
     
  10. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    В продолжение темы о том, что за hDC нам присылают:

    По WM_PAINT BeginPaint тоже отдаёт некий hDC, и он тоже отличается от полученного GetDC. Причем отказ от BeginPaint'ского hDC в пользу GetDC'овского позволяет исключить обработку WM_ERASEBKGND.



    Такой несколько диковатый код:


    Код (Text):
    1.     .elseif eax==WM_PAINT
    2.         mov hDC,FUNC(BeginPaint,hWin,ADDR Ps)
    3.         mov hDC,FUNC(GetDC,hWin)
    4.         push hDC
    5.         push hWin
    6.         Call PaintProc
    7.         invoke ReleaseDC,hWin,eax
    8.         invoke EndPaint,hWin,ADDR Ps
    9.         mov eax,TRUE
    10.         ret




    позволяет избежать телодвижений по WM_ERASEBKGND, без мерцаний и нестертых участков прошлого рисования.
     
  11. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    EGOiST

    Например, из диалоговой процедуры не вызывают DefWindowProc.



    cresta

    то, что нам подсовывают в wParam'e, отличается от того, что мы поимеем от GetDC

    Это нормально.



    Чем объяснить, что старый рисунок стирается не весь?

    wParam в WM_ERASEBKGND и hdc из BeginPaint позволяют менять только ту часть клиентской область окна, которая открывается. hdc из GetDC позволяет изменить всю клиентскую область окна.



    позволяет избежать телодвижений по WM_ERASEBKGND

    Ты хочешь сказать что оконная процедура, из MemDC.Asm, приняла вид
    Код (Text):
    1. WndProc proc hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    2.   LOCAL Ps  : PAINTSTRUCT
    3.   LOCAL hDC : DWORD
    4.  
    5.   mov eax,uMsg
    6.   .if eax==WM_DESTROY
    7.     invoke PostQuitMessage,NULL
    8.   .elseif eax==WM_PAINT
    9.     invoke BeginPaint,hWin,ADDR Ps
    10.     mov hDC,FUNC(GetDC,hWin)
    11.     push hDC
    12.     push hWin
    13.     Call PaintProc
    14.     invoke ReleaseDC, hWnd, hDC
    15.     invoke EndPaint,hWin,ADDR Ps
    16.   .else
    17.     invoke DefWindowProc,hWin,uMsg,wParam,lParam
    18.     ret
    19.   .endif
    20.   xor eax,eax
    21.   ret
    22. WndProc endp
    и все работает ok?
     
  12. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    q_q





    Не совсем вяжется с тем, что видно на экране, Надпись ведь не съезжает в сторону, просто не стирается предыдущий рисунок.







    Вроде работает. Пробовал ресайзить, таскать поверх окна другие окна, затаскивать за край экрана и вытягивать обратно.





    [​IMG] _193420850__MemDC.zip
     
  13. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    cresta

    Вроде работает. Пробовал ресайзить

    Если уменьшать размер окна за правый нижний угол?

    Счетчик не меняется, пока виден на экране.



    Надпись ведь не съезжает в сторону

    За надписью на до наблюдать в момент появления четвертого разряда, т.е. при переходе счетчика от сотен к тысячам.
     
  14. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257




    Всё правильно, если мы сжимаем окно, то WM_PAINT не присылается, т.к. фактически перерисовывать нечего (счетчик ведь фактически считает именно кол-во wm_paint'ов). Но как только rect окна при ресайзе увеличится по любой из координат, тут же и наступит wm_paint, и счетчик увеличится. Т.е. без необходимости wm_paint не вызывается. Что очень даже удобно :) И в духе минимизации движений.
     
  15. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    cresta

    Понял.

    Ты не стандартно заполнил wc.style, я обычно заполняю его CS_VREDRAW or CS_HREDRAW.
     
  16. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Да, это есть маленькая уловка :) Иногда помогает.