Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как работает WM_SETTEXT ? 
V
    Опции темы
mekhanikus
Дата 10.5.2009, 15:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вольноопределяющийся
*


Профиль
Группа: Участник
Сообщений: 186
Регистрация: 16.6.2008
Где: Спасск-Дальний

Репутация: 1
Всего: 1



Может кому-то вопрос покажется странным, но всетаки.
Началось все с того, что я решил сделать subclassing стандартного STATIC'а,
написать для него собственный WM_PAINT.
Задача была, в общем то, успешно решена.
Однако, в процессе тестирования программы выявилась неприятная особенность:
в момент раздачи STATIC'ам (их много на форме) значений через WM_SETTEXT,
происходит неприятное мерцание этих самых STATIC'ов.
Насколько я понял, это происходит потому, что
"The DefWindowProc function sets and displays the window text"
причем делает это дефолтным шрифтом и цветом,
а потом все это заново перерисовывается моим WM_PAINT'ом.

Подскажите, как этого можно избежать?
Можно ли отучить DefWindowProc перерисовывать текст?
Или как самому обработать WM_SETTEXT?
PM MAIL   Вверх
andrew_121
Дата 10.5.2009, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 2
Всего: 33



Это из-за того что тело, вызывающее SendMessage() на ходится не в отдельном потоке.



--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
GremlinProg
Дата 10.5.2009, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(mekhanikus @  10.5.2009,  17:49 Найти цитируемый пост)
Можно ли отучить DefWindowProc перерисовывать текст?

можно просто блокировать на некоторое время перерисовку любого рода:
блокировать:
Код

::SendMessage(hwnd,WM_SETREDRAW,FALSE,0);

разблокировать:
Код

::SendMessage(hwnd,WM_SETREDRAW,TRUE,0);

Цитата(mekhanikus @  10.5.2009,  17:49 Найти цитируемый пост)
Или как самому обработать WM_SETTEXT?

субклассить Static и перехватывать WM_SETTEXT ( и WM_GETTEXT, если все еще нужно встроенное рисование static'а ) в процедуре окна,
какие тут могут быть проблемы?
ты ведь первое уже делаешь:
Цитата(mekhanikus @  10.5.2009,  17:49 Найти цитируемый пост)
Началось все с того, что я решил сделать subclassing стандартного STATIC'а,

проблема моргания контролов уже неоднократно обсуждалась, достаточно поискать по форуму WM_PAINT


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
J0ker
Дата 10.5.2009, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: -1
Всего: 14



вам нужно заблокировать WM_ERASEBKGND - это он мерцает



--------------------
user posted image
PM MAIL   Вверх
mekhanikus
Дата 11.5.2009, 07:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вольноопределяющийся
*


Профиль
Группа: Участник
Сообщений: 186
Регистрация: 16.6.2008
Где: Спасск-Дальний

Репутация: 1
Всего: 1



Цитата(GremlinProg @ 10.5.2009,  18:55)

можно просто блокировать на некоторое время перерисовку любого рода:


Надо будет покурить в эту сторону.

Цитата(GremlinProg @ 10.5.2009,  18:55)

субклассить Static и перехватывать WM_SETTEXT ( и WM_GETTEXT, если все еще нужно встроенное рисование static'а ) в процедуре окна,
какие тут могут быть проблемы?


Представте себе - проблема (для меня  smile ).
Не смог найти куда засунуть текст, полученый в WM_SETTEXT.
Пожалуйста пните в нужном направлении.

Добавлено через 12 минут и 46 секунд
Цитата(J0ker @ 10.5.2009,  19:53)
вам нужно заблокировать WM_ERASEBKGND - это он мерцает

Пробовал, не помогает.
Причина, имхо, именно в реакции DefWindowProc на WM_SETTEXT.
PM MAIL   Вверх
J0ker
Дата 11.5.2009, 09:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: -1
Всего: 14



Цитата(mekhanikus @  11.5.2009,  07:03 Найти цитируемый пост)
Пробовал, не помогает.
Причина, имхо, именно в реакции DefWindowProc на WM_SETTEXT

такого попросту быть не может
если вы перекрываете отрисовку и блокируете WM_ERACEBKGND то больше никто ничего не рисует
если мерцание происходит в момент, когда ваш код перерисовывает контрол, то значит надо рисовать в буфер а потом копировать посредством BitBlt


--------------------
user posted image
PM MAIL   Вверх
Earnest
Дата 11.5.2009, 09:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



J0ker, не стоит быть столь категоричным, когда речь идет о старых контролах виндоус. Насчет статика утверждать не берусь, но вот комбобокс точно рисуется не только на WM_PAINT...
Из вышесказанного, конечно, не следует, что аффтар все правильно сделал. Но такое вполне может быть (что отрисовка на  settext идет не через стандартный WM_PAINT). С другой стороны, если сделать контрол полностью OwnerDraw, то должно помочь - тогда действительно все под контролем.


--------------------
...
PM   Вверх
J0ker
Дата 11.5.2009, 09:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: -1
Всего: 14



Цитата(mekhanikus @  10.5.2009,  15:49 Найти цитируемый пост)
Насколько я понял, это происходит потому, что
"The DefWindowProc function sets and displays the window text"
причем делает это дефолтным шрифтом и цветом,
а потом все это заново перерисовывается моим WM_PAINT'ом

вы неправильно понимаете процесс
если что либо меняется для контрола, что требует его перерисовки, то контролу посылается WM_PAINT - если вы его (правильно) перехватили, то больше никто ничего в клиентской области рисовать не будет (за исключением, как я говорил выше, WM_ERACEBKGND)


--------------------
user posted image
PM MAIL   Вверх
Earnest
Дата 11.5.2009, 09:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Цитата(J0ker @  11.5.2009,  10:22 Найти цитируемый пост)
если что либо меняется для контрола, что требует его перерисовки, то контролу посылается WM_PAINT 

Как уже сказано, это не обязательно так, для некоторых старых контролов. Во всяком случае, комбобоксу не получается кастомизировать отрисовку без полного OwnerDraw, только перехватом WM_PAINT, а они со статиком ровестники, еще из Win 3 приползли, так что  там костыль на костыле, и вполне возможна "оптимизация" отрисовки. 



--------------------
...
PM   Вверх
J0ker
Дата 11.5.2009, 09:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: -1
Всего: 14



Цитата(Earnest @  11.5.2009,  09:18 Найти цитируемый пост)
J0ker, не стоит быть столь категоричным, когда речь идет о старых контролах виндоус

стоит
все контролы - это обычные окна

Цитата(Earnest @  11.5.2009,  09:18 Найти цитируемый пост)
но вот комбобокс точно рисуется не только на WM_PAINT

что значит "рисуется на"??? WM_PAINT - мессадж, дающий команду на перерисовку клиентской области - других нет - все, что рисуется в клиентской области рисуется в ответ на WM_PAINT
я так подозреваю, что вы имеете ввиду owner-drawn контролы - но это уже из другой оперы

Цитата(Earnest @  11.5.2009,  09:18 Найти цитируемый пост)
Но такое вполне может быть (что отрисовка на  settext идет не через стандартный WM_PAINT)

не может

Цитата(Earnest @  11.5.2009,  09:18 Найти цитируемый пост)
С другой стороны, если сделать контрол полностью OwnerDraw, то должно помочь - тогда действительно все под контролем. 

под контролем родительского окна
Цитата

The WM_DRAWITEM message is sent to the parent window of an owner-drawn button, combo box, list box, or menu when a visual aspect of the button, combo box, list box, or menu has changed.

это что называется "через <--->"

ЗЫЖ я столь категоричен не от упрямства, а от опыта  smile

Добавлено @ 09:43
Цитата(Earnest @  11.5.2009,  09:32 Найти цитируемый пост)
Как уже сказано, это не обязательно так, для некоторых старых контролов. Во всяком случае, комбобоксу не получается кастомизировать отрисовку без полного OwnerDraw, только перехватом WM_PAINT

как уже сказано - получается
не поручусь за выпадающий список, но все остальное перерисовывается на ура:
http://www.codeproject.com/KB/combobox/Com...x?display=Print

Это сообщение отредактировал(а) GremlinProg - 12.5.2009, 01:49


--------------------
user posted image
PM MAIL   Вверх
J0ker
Дата 11.5.2009, 09:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: -1
Всего: 14



да, заыл сказать, что листбокс - разговор отдельный


--------------------
user posted image
PM MAIL   Вверх
mekhanikus
Дата 11.5.2009, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вольноопределяющийся
*


Профиль
Группа: Участник
Сообщений: 186
Регистрация: 16.6.2008
Где: Спасск-Дальний

Репутация: 1
Всего: 1



Цитата(J0ker @ 11.5.2009,  09:06)
такого попросту быть не может
если вы перекрываете отрисовку и блокируете WM_ERACEBKGND то больше никто ничего не рисует

Оказывается может.
Сначала, чтоб проверить, получился ли у меня сабклассинг,
я сделал пустой WM_PAINT, который возвращает 0.
(знаю, что это не правильно, но, вопрос не в этом).
После запуска программы сабкассированные статики остались пустыми (что и требовалось доказать).
Однако, после раздачи значений через WM_SETTTEXT они появились.

Добавлено через 8 минут и 32 секунды
А кто, всетаки, скажет, где хранится этот самый текст окна (WindowText)?
Если б я это узнал, то сам бы обработал WM_SETTEXT, без лишней отрисовки.
PM MAIL   Вверх
GremlinProg
Дата 11.5.2009, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(J0ker @  11.5.2009,  11:41 Найти цитируемый пост)
я так подозреваю, что вы имеете ввиду owner-drawn контролы - но это уже из другой оперы

а что подозревать, когда Earnest, так и пишет:
Цитата(Earnest @  11.5.2009,  11:18 Найти цитируемый пост)
если сделать контрол полностью OwnerDraw, то должно помочь

Цитата(J0ker @  11.5.2009,  11:41 Найти цитируемый пост)
не поручусь за выпадающий список

а выпадающий список не контрол?
и почему не поручишься, только что ведь утверждал, что все рисуются только в ответ на WM_PAINT )
Цитата(J0ker @  11.5.2009,  11:22 Найти цитируемый пост)
если что либо меняется для контрола, что требует его перерисовки, то контролу посылается WM_PAINT - если вы его (правильно) перехватили, то больше никто ничего в клиентской области рисовать не будет

это ты зря, бывают моменты, когда отрисовка идет, к примеру при захвате мыши (EDIT, RICHEDIT), т.е. она конечно на WM_PAINT тоже идет, но вот именно при "таскании" курсора по тексту, текущее выделение рисуется "на лету", перерисовка окна тут не происходит, накладно

Добавлено через 7 минут и 38 секунд
Цитата(mekhanikus @  11.5.2009,  13:08 Найти цитируемый пост)
А кто, всетаки, скажет, где хранится этот самый текст окна (WindowText)?

это черный ящик, и дорога к нему закрыта
Цитата(mekhanikus @  11.5.2009,  13:08 Найти цитируемый пост)
сам бы обработал WM_SETTEXT, без лишней отрисовки.

обрабатывай сам, просто текст храни в своем буфере, чтобы при отрисовке обращаться только к нему


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
J0ker
Дата 11.5.2009, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: -1
Всего: 14



Цитата(GremlinProg @  11.5.2009,  11:17 Найти цитируемый пост)
а выпадающий список не контрол?

специфическая его часть

Цитата(GremlinProg @  11.5.2009,  11:17 Найти цитируемый пост)
и почему не поручишься, только что ведь утверждал, что все рисуются только в ответ на WM_PAINT )

потому, что не рабботал с этой частью
но не вижу причин, почему она должна быть исключением - так шо 99% - на WM_PAINT или WM_NCPAINT

Цитата(GremlinProg @  11.5.2009,  11:17 Найти цитируемый пост)
это ты зря, бывают моменты, когда отрисовка идет, к примеру при захвате мыши (EDIT, RICHEDIT), т.е. она конечно на WM_PAINT тоже идет, но вот именно при "таскании" курсора по тексту, текущее выделение рисуется "на лету", перерисовка окна тут не происходит, накладно

не вижу противоречия с моим высказыванием



--------------------
user posted image
PM MAIL   Вверх
GremlinProg
Дата 11.5.2009, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(J0ker @  11.5.2009,  19:23 Найти цитируемый пост)
специфическая его часть

ну надо же, а я думал это обычный контрол, как и все
а это оказывается какой-то хитрый специфический трюк винды
не расстраивай меня J0ker,
может ты еще будешь настаивать что и меню это не контрол, а какой-то очередной специфический трюк?
я совсем тогда разочаруюсь )
Цитата(J0ker @  11.5.2009,  19:23 Найти цитируемый пост)
потому, что не рабботал с этой частью

тогда и не нужно так категорично настаивать
рисовать может кто угодно, где угодно и когда угодно
другой вопрос - какие могут быть причины, чтобы не рисовать чего-либо на WM_PAINT
Цитата(J0ker @  11.5.2009,  19:23 Найти цитируемый пост)
не вижу противоречия с моим высказыванием

ну это уже совсем ни в какие ворота:
Цитата(J0ker @  11.5.2009,  11:22 Найти цитируемый пост)
вы неправильно понимаете процесс
если что либо меняется для контрола, что требует его перерисовки, то контролу посылается WM_PAINT - если вы его (правильно) перехватили, то больше никто ничего в клиентской области рисовать не будет (за исключением, как я говорил выше, WM_ERACEBKGND)

от свои слов же не будешь отказываться
я просто привел буквально самый очевидный пример, когда WM_PAINT добровольно вообще не посылается в контрол, пока не будет отпущена мышь
как же нет противоречий-то?

ps: конечно WM_PAINT ни кто ни кому не посылает (он генерируется в момент простоя, когда область перерисовки не пуста), это просто допустимый оборот речи в этом топике для краткости


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1373 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.