След от таскаемых окошек

Тема в разделе "WASM.WIN32", создана пользователем Ivan_d, 9 янв 2007.

  1. Ivan_d

    Ivan_d New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2007
    Сообщения:
    27
    Вопрос к корифеям программирования под Винду

    Имеется следующая ситуация:
    Существует простейшее окошко, с обработчиком событий WndProc(), которы по сообщению WM_PAINT обновляет клиентскую часть окна (допустим закрашивает ее в черный цвет), а все остальные сообщения перенаправляет стандартной функции DefWindowProc().

    Запускаем все это дело, появляется черное окно. Теперь беру любое другое окошко (калькулятор, или малеьнкое окошко от FlashGet'а, которое всегда висит в углу) и начинаю его услиленно таскать по клиентской области своего окна. И что же я вижу? За этим таскаемым окошком остается белый след, который, естественно, тут же закрашивается черным (WndProc()/WM_PAINT), но сам факт, что система при перетаскивании обьекта по поверхности моего окна, предыдущее положение этого обьекта очищает в белый цвет! T.e. этот белый цвет рисуется не моей WndProc() и не DefWindowProc()

    Беру для эксперимента любые чужие программы и смотрю, как ведут в таких ситуациях они:

    * EmuZWin - при таскании поверх клиентской зоны белого следа нет, след есть только при задевании рамки окна (т.е. зоны обновления DefWindowProc())
    * VirtualDubMod - след есть
    * Spectaculator - след есть
    * Консольное окно - следа нет, даже при задевании рамок окна
    * MediaPlayerClassic - след есть

    Кто в курсе? Что это за бадяга?
    Возможно это зависит от каких либо свойств окна, но каких?
     
  2. dermatolog

    dermatolog Member

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    406
    Адрес:
    Екатеринбург
    Смотри в сторону WM_ERASEBKGND
     
  3. Ivan_d

    Ivan_d New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2007
    Сообщения:
    27
    Смотрел
    Реакция на него отключена давно.

    Пробовал отключать ВООБЩЕ все, а след есть
     
  4. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.347
  5. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Ivan_d
    А зря :)
     
  6. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    При регистрации класса используй ноль в кисти для фона, или как правильно советует Quantum корректно обрабатывай WM_ERASEBKGND

    ЗЫ: BeginPain заливает окно кистью из свойств класса и от этого не только следы, но и мерцания наблюдаются ;)
     
  7. Ivan_d

    Ivan_d New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2007
    Сообщения:
    27
    CS_SAVEBITS не используется

    >> Реакция на него отключена давно.
    > А зря :)

    Почему зря?

    Кисть при регистрации пробовал абсолютно любую - все равно есть след, либо цветом кисти, либо, если NULL, то белым цветом
     
  8. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Ivan_d
    Именно поэтому заметен след от таскания. Либо задавайте классу чёрную кисть и уберите обработчик WM_ERASEBKGND, либо в обработчике WM_ERASEBKGND сами заливайте фон чёрным цветом и возвращайте TRUE (кисть класса в данном случае значения не имеет).
     
  9. Ivan_d

    Ivan_d New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2007
    Сообщения:
    27
    Обьясняю подробно суть проблемы:

    Если отключить всякие реакции WndProc() на сообщения, а так же ничего не передавать функции DefWndowProc(), а на все отвечать return 1, то мы получим следующее:

    Нетаскаемое (естественно, раз отключена обработка) и не обновляемое окно, но(!), если по поверхности этого окна таскать чужое окошко (например маленькое окно от FlashGet, которое всегда тусуется в углу экрана), то на системной части моего окна это таскаемое окошко будет оставлять свои следы, а на пользовательской части моего окна эти следы будут закрашиваться системой в цвет, определенный в классе моего окна. Если же цвет в классе определен, как NULL, то закрашиваться будет белым цветом.

    Вопрос - как сделать так, чтобы система НИ ВО ЧТО не закрашивала следы чужих окошек на клиетской части моего окна?
     
  10. kero

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

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    1 _d против 100 мудрецов ? :)

    WS_EX_LAYERED, однако.
     
  11. Ivan_d

    Ivan_d New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2007
    Сообщения:
    27
    Пробовал - это не то, это просто 'дырка' будет в клиетской части
     
  12. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Ivan_d
    На WM_PAINT нужно отвечать return 0. Это касается и других сообщений, которые нельзя просто игнорировать (поэтому и существует DefWindowProc).

    Обрабатывать WM_PAINT, где просто вызывать ValidateRect или DefWindowProc и возвращать 0. Также обрабатывать WM_ERASEBKGND - просто возвращать TRUE. Кстати, зачем Вам на клиентской области окна понадобились следы от других окон? Изначально, вроде бы, появления следов необходимо было избежать...
     
  13. Ivan_d

    Ivan_d New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2007
    Сообщения:
    27
    Да, на WM_PAINT я отвечаю нулем.
    на WM_ERASEBKGND отвечаю 1.

    Зачем? Обьясняю - пока нет четкого следа на клиентской области окна, это значит, что система его затирает, тратя на это время.
     
  14. Ivan_d

    Ivan_d New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2007
    Сообщения:
    27
    Чтобы не быть голословным, приведу графический пример:

    Скриншот

    В данном примере:
    Рефреш системной части окна отключен (на WM_NCPAINT отвечаю 0)
    Рефреш клиетской части окна я тоже не делаю
    На WM_ERASEBKGND отвечаю 1

    Как видно из скриншота, на системной части окна остаются следы маленького окошка от FlashGet'a, а на клиетской они же закрашиваются системой в белый цвет. А мне нужно, чтобы система их НЕ ЗАКРАШИВАЛА,а ничего не делала!
     
  15. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Похоже, что в процессе перетаскивания приходит сообщение WM_PRINT - это только гипотеза. Попробуйте отключить и его. И покажите наконец исходник :)
     
  16. Ivan_d

    Ivan_d New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2007
    Сообщения:
    27
    Попробую завтра может выцепить из исходинка (он огромен) те кусочки, что за это отвечают и запостить сюда.

    Что же касается всех сообщений, то я их в виде текстовых строк вывожу для отладочных целей в отдельное консольное окошечко.
    Вот что приходит при перетаскивании:

    WM_NCPAINT - сейчас ничего не делааю, отвечаю 0
    WM_ERASEBKGND - ничего не делаю, отвечаю 1
    WM_SYNCPAINT - сейчас ничего не делаю, отвечаю 0
    WM_PAINT - сейчас ничего не делаю, отвечаю 0
    и такие пакеты, пока таскаю мелкое окошко поверх своего

    а в спокойном режиме, или когда таскаю не задевая мое окно
    идет только WM_PAINT, который я посылаю сам, для обновления окна каждый фрейм.
     
  17. Ivan_d

    Ivan_d New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2007
    Сообщения:
    27
    Проблема решилась!

    Добрый человек подсказал, что нужно кисть указывать не NULL (как указано в доке), a (HBRUSH)GetStockObject(NULL_BRUSH)

    Всем пасиба!
     
  18. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    при регистрации класса?
     
  19. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Ivan_d
    WM_PAINT - сейчас ничего не делаю, отвечаю 0

    Неверно.
    Если никакого своего кода нет - надо вызывать DefWindowProc().
    Если свой код есть - надо его заключать в BeginPaint()/EndPaint().

    Также не надо посылать самому WM_PAINT.
    Если надо немедленно отрисоваться:

    Код (Text):
    1. InvalidateRect (hWnd, NULL, FALSE);
    2. UpdateWindow (hWnd); // This will call your WM_PAINT handler
     
  20. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Ivan_d
    Использование прозрачной кисти просто не оставляет видимых следов рисования, но вовсе не значит, что система не тратит время на заполнение дыр прозрачной кистью.