![]() |
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]() ![]() ![]() |
|
devmstr |
|
|||
![]() Developer ![]() ![]() Профиль Группа: Участник Сообщений: 879 Регистрация: 28.4.2004 Где: Ukraine Репутация: нет Всего: 11 |
Почему изображение при изменении размеров мигает???
-------------------- Think different ©Steve Jobs ![]() |
|||
|
||||
MacTep |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1292 Регистрация: 4.8.2003 Где: г. Самара Репутация: нет Всего: 4 |
Попробуй убрать из обработки сообщения WM_SIZE строчку
Эта функция изменяет размер действительной части экрана и поэтому происходит мигание. Я думаю так... -------------------- (A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :) |
|||
|
||||
Fixin |
|
|||
![]() Ёжик ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1357 Регистрация: 6.1.2004 Репутация: 8 Всего: 18 |
LOL. Это функция принудительной перерисовки области окна. Так как указатель на прямоугольник нулевой, то перерисовываем все окно. Добавлено @ 19:59 Но убрать надо, или задавать перерисовываемую область. |
|||
|
||||
Nastya |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 27.3.2002 Где: Мариуполь Репутация: 3 Всего: 44 |
А лучше еще выводить с CompatibleDC, и накладывать сверху.
Где-то это на форуме уже обсуждалось -------------------- Что бы понять рекурсию, надо понять рекурсию "Профессионал - это человек сделавший все возможные ошибки в очень узкой области". Н.Бор |
|||
|
||||
Alastis |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 251 Регистрация: 15.11.2004 Где: Казахстан, Астана Репутация: нет Всего: 10 |
уберешь ты или оставишь InvalidateRect ничего не изменится
![]() нужно обработать WM_ERASEBKGND. Просто поставь заглушку:
-------------------- Прости, что я говорю, когда ты меня перебиваешь. |
|||
|
||||
Nastya |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 27.3.2002 Где: Мариуполь Репутация: 3 Всего: 44 |
После чего все начинает просто дико глючить, летали, знаем ![]() -------------------- Что бы понять рекурсию, надо понять рекурсию "Профессионал - это человек сделавший все возможные ошибки в очень узкой области". Н.Бор |
|||
|
||||
MacTep |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1292 Регистрация: 4.8.2003 Где: г. Самара Репутация: нет Всего: 4 |
Ну и как же тогда решить эту проблему?
![]() -------------------- (A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :) |
|||
|
||||
Fixin |
|
|||
![]() Ёжик ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1357 Регистрация: 6.1.2004 Репутация: 8 Всего: 18 |
|
|||
|
||||
Fixin |
|
|||
![]() Ёжик ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1357 Регистрация: 6.1.2004 Репутация: 8 Всего: 18 |
Сделай статический элемент без текста и замени ему главную процедуру на свою, чтоб рисовать в этом статике. Может, не будет перерисовываться статик, если изменение размера окна его не затронет.
Но вопрос интересный сейчас поэксперементирую. |
|||
|
||||
Fixin |
|
|||
![]() Ёжик ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1357 Регистрация: 6.1.2004 Репутация: 8 Всего: 18 |
Вот что надо делать:
Добавлено @ 22:54 Все гениальное - просто, как глупость. Добавлено @ 22:55 По умолчанию, или по случайному распределению памяти, ставится перерисрвка. |
|||
|
||||
MacTep |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1292 Регистрация: 4.8.2003 Где: г. Самара Репутация: нет Всего: 4 |
![]() -------------------- (A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :) |
|||
|
||||
Plamiv |
|
|||
Новичок Профиль Группа: Участник Сообщений: 2 Регистрация: 19.4.2006 Где: г. Брест Репутация: нет Всего: нет |
Возникла похожая проблема:
Почему изображение при прокрутке скролом мигает??? Код идентичен представленному выше. Может тоже есть что-то простое и гениальное? |
|||
|
||||
zhgutov |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 120 Регистрация: 14.12.2004 Репутация: 1 Всего: 2 |
Плюс двойная буферизация. При этом можно использовать InvalidateRect (HWND, RECT*, false); Должен получиться ожидаемый результат... Это сообщение отредактировал(а) zhgutov - 26.4.2006, 15:04 --------------------
Приполз. Увидел. Укусил. |
|||
|
||||
GremlinProg |
|
||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
Хм... как много всего, но последний пост был наиболее ближе к правильному.
Изображение начинает моргать в двух случаях 1. Перерисовка контрола происходит в несколько итераций, т.е. при изменении каких-либо параметров вы вызываете InvalidateRect, после чего UpdateWindow, а потом так еще 1-2 раза. И это, как вы уже догадываетесь не правильно. Даже если времени на рисование уходит не много, не пытайтесь так перестраховываться. 2. zhgutov, совершенно верно, только InvalidateRect тут ни при чем. Все дело в WM_ERASEBKGND, как заметил Alastis, только это не заглушка. Поясню: двойной буфер хорош тем, что в него можно рисовать сколько-угодно и как угодно, пусть даже не оптимально, а потом разом показать, т.е. скопировать битмап этого буфера, или только его часть в битмап девайса контрола. Но это не решит проблему, потому что WM_ERASEBKGND закрасит часть девайса цветом заднего фона контрола, а затем вы выводите реальную картинку. Вот в этот момент как раз и происходит маленький моргунчик. Заметьте, даже при двойной буферизации. Чтобы этого не происходило, нужно конечно перекрыть WM_ERASEBKGND. Для этого нужно написать че-то типо этого в обработчике:
Но это еще не все. Забудьте о функциях BeginPaint и EndPaint, если вы не хотите, чтобы так же не моргала неклиентская часть всех окон: функция BeginPaint вызывает перерисовку неклиентской части всех дочерних контролов, и так как это происходит автоматически, то вы не сможете сюда вставить двойной буфер, моргунчик останется(виндовоз просто перечислит все N дочерних окон и произведет N прорисовок на одном девайсе, т.е. если это девайс контрола, то моргание будет видно). Тройная связка: GetUpdateRect(GetUpdateRgn) - GetDC - ValidateRect(ValidateRgn) выполняют то же самое, что и BeginPaint, с небольшим отличием: GetUpdateRgn возвращает аж целый регион коррекции, в отличии от жалкой BeginPaint, которая возвращает только прямоугольник. Если вы не знаете что делает каждая из этих функций, то обратитесь на форум за помощью, здесь я не буду выкладывать их описание. Выполнить прорисовку неклиентской части дочернего контрола можно разными способами, я сам для этого использую сообщения WM_PRINT и WM_PRINTCLIENT. Сейчас я покажу кусок своей системы, но не обольщайтесь, сам по себе, отдельно он работать не будет, вам самим придется делать его под себя, потому что я не использую MFC или WTL, но и не WinMain, просто свою систему классов. Почитайте как я реализовал двойной буфер на WM_PRINT и WM_PRINTCLIENT и сделайте свой вариант.
В каком то разделе винграда я уже обещал выложить нечто подобное, будем считать, что я свое обещание выполнил ). -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||
|
|||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
Да, кстати, есть еще один простой способ заставить не моргать контролы при прорисовке. Я использую его редко, только если нужно быстро написать програмку, без всяческих ухищрений. Думаю этот способ вам подойдет, но после нескольких экспериментов вы сами увидите его недостатки.
Добавьте к набору флагов dwExStyle, функции CreateWindowEx дополнительный флаг WS_EX_COMPOSITED -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Эта проблема решается проще - всего лишь флаг WS_CLIPCHILDREN родительскому окну, и дети не включаются в перерисовку. Что касается BeginPaint-EndPaint, то эта парочка делает по-крайней мере одну полезную вещь, которую без нее нужно делать руками (как ты и делаешь) - валидэйтит регион, для которого пришел WM_PAINT. А вовсе не приводит к перерисовке дочерних окон. Кроме того, при использовании вне-экранного буфера WM_ERASEBKGND обычно совсем затыкают (или просто можно поставить нулевую кисть классу окна при регистрации), и просто красят фон прямо во время отрисовки (если надо). А посылать для этого WM_ERASEBKGND с "левым" dc как-то криво, согласись. Кроме того, использовать сообщение WM_PRINT не по назначению тоже не очень хорошо. Тем более всего-то надо функцию свою написать. Т.е. что я хочу сказать - с точки зрения изучения "как оно все устроено" - ты разобрался прекрасно и твой код весьма полезен (в учебных целях). Но писать так в реальном проекте - боже упаси. -------------------- ... |
|||
|
||||
GremlinProg |
|
||||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
Весьма поспешное заявление, даже неудобно говорить это Ко-модератор'у. Я пишу только о том, что уже давно проверено. Не мне учить вас как проверить моё утверждение. Не нужно так громко заявлять, тем более наскоро пробежавшись по тексту. О перерисовке целых контролов я и не говорил, перечитайте, пожалуйста пост.
WM_PAINT с "левым" dc тоже как-то криво, только это не я придумал, есть стандарт, вам не мешало бы его почитать.
Вы, видимо считаете, что WM_PRINT предназначен только для вывода на принтер? MSDN вас простит ). -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||||
|
|||||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
...да, да, WS_CLIPCHILDREN отсекает дочерние компоненты при прорисовке, но! Отсекает для родителя, т.е. папа не будет на них рисовать, BeginPaint просто перерисует НЕКлиентскую часть дочек и отсечет регионы их окон из папы, клиента дочек, он конечно же не тронет. Вы можете проверить, когда вызывается WM_NCPAINT, и убедиться в этом. Причем регион, который в дальнейшем выбирается в контекст устройства папы передается в WPARAM'етре. Это как раз и обуславливает такую, мягко говоря, непоследовательную прорисовку неклиентской области окна. WS_CLIPCHILDREN проблему не решит!
-------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Ну-ну, зачем же так агрессивно, как будто я на любимый мозоль наступила
![]() Я достаточно внимательно посмотрела твой код. Насчет неклиентской области дочерних окон и WS_CLIPCHILDREN ты, наверно, прав, но мне редко встречались контролы, где это имело бы значение... Что касается BeginPaint - повторюсь - эта функция ничего не перерисовывает! Да, она посылает ERASEBKGND, а также устанавливает регион отсечения, о чем и написано в MSDN... Кроме того, она избавляет тебя от возни с кареткой и пр., что иначе нужно делать вручную. Подкорректировать регион отсечения (исключить из него неклиентскую часть дочерних окон, если приспичило) можно в любой момент - например, на ERASEBKGND (если оно в принципе приходит), а можно и прямо в WM_PAINT. Как-то я это делала на NCPAINT... Что касается WM_PRINT, то стандартно оно из WM_PAINT не вызывается, и согласно MSDN используется для вывода "most commonly in a printer device". Хотя и необязательно, тут ты прав. Я хотела сказать лишь то, что неразумно посылать самому себе сообщения, упаковывать флаги и параметры, если это сообщение ты же сам и обрабатываешь. Проще функцию написать\вызвать. Уж не говоря о том что это несколько быстрее. -------------------- ... |
|||
|
||||
GremlinProg |
|
||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
Есть один момент, вернее два, но один проще описать: давненько, когда я еще заморачивался с разными прибамбасами GDI, мне на глаза попалась такая вот задачка: допустим есть Edit, или Rich Edit - стандартно настроенные и нужно например за текстом показать ролик, или сделать анимированную подсветку части текста, причем, естественно, прибегать к формированию собственного текстового компонента было некогда. А сделать надо было корректно, без заплаток типа TRANSPARENT. Так вот решение оказалось довольно простым. Код который я выложил позволяет наследовать прорисовку анцестора, не родителя как до операции, так и после неё, причем дважды копировать девайс не нужно, ну и без морганий, соответственно. Просто сообщение WM_PRINT знают все системные компоненты, вернее его почти ни кто не обрабатывает, поэтому система ведет себя одинаково для всех контролов. Хм, это кстати единственный способ, который я тогда нашел.
Хотите - верьте, хотите - проверьте, повторять не буду. Дареному коню в зубы не глядят. Наступайте на грабли, на которые наступало уже несколько поколений программистов, я показал вам где эти грабли лежат, а остальное - дело техники. Мозоль - не мозоль, но субординацию надо соблюдать! Доверяй но проверяй, и не кричите, ради бога, пока не проверите! -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||
|
|||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
по поводу WM_ERASEBKGND, все таки правильнее оставить его реализацию закраски заднего фона, собственно, сообщение предназначено только для этого, не нужно так прямо его сразу отвергать. Он нужен для простых компонент, в которые не всегда хочется лезти, ведь намного проще установить один раз кисть для класса, чем вводить обработку сообщения. Это просто правило сохранения стандарта.
-------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Не буду с тобой спорить, все как-то беспредметно.
Я ведь не говорила, что твой код неправильный. Он просто избыточен и излишне усложнен, и пытается решить все возможные проблемы сразу. В каждом конкретном контексте возможно свое, гораздо более простое решение. Насчет ERASEBCKGND - на мой взгляд проще вызвать PatBlt или даже FillRect, поскольку вся прорисовка идет во вне-экранный буфер. Это мое мнение подтверждается многочисленными реализациями нестандартных контролов хотя бы на том же codeproject. В конце концов у каждого свой опыт. Интересно, что ты хотел этим сказать? Кто тут из нас двоих начальник? ![]() -------------------- ... |
|||
|
||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
На сколько я понял, у вас слишком большие амбиции, впрочем, флейм здесь неуместен. Если хотите пообщаться флудите в соответствующем этому месте. Я сильно сомневаюсь, что ваша репутация от этого возрастет, а мне до плюсиков нет дела, я - практик. Мое первое сообщение вы подвергли беспочвенной критике, тем самым вы сами себя спровоцировали на безграмотность. Так же сомневаюсь, что среди молодых к вам после этой темы будет доверие. И что теперь толку от ярлыка, который вы сами себе навесили. Начальник не тот кто главнее, а тот, кому можно доверить управление над подчиненными. Мои люди мне доверяют! А по поводу кода, я думаю найдется не мало сообразительных людей, которые подтвердят мои слова. Теория должна опираться на практику.
вы хотя бы раз взгянули, что выполняет DefWindowProc в ответ на это сообщение. Когда посмотрите, задайте себе вопрос: кто говорит о избыточности? Вы ради самовосхваления дезинформируете молодое поколение. Очень плохо. Рекурсия - то что вы называете "...избыточен и излишне усложнен..." используется в иерархии наследования классов. Если бы вы внимательно читали мой первый пост, то я об этом сразу и сказал, поэтому она оправдана. Вы ведь даже не понимаете о назначении большинства методов, а судите. Я не намерен более развивать тему, поскольку самых главных вопросов я так и не услышал, если у остальных они появятся, обащайтесь ко мне непосредственно по аське. Вопрос исчерпан окончательно! -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
v2v |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1620 Регистрация: 20.9.2006 Где: Киев Репутация: нет Всего: 56 |
Из всего вышесказаного лучше всего помогает
Но при этом при перерисовке проц забивается на 100 % (это если хорошо потягать окошко) ... как от этого лечиться?? |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Системное программирование и WinAPI" | |
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |