Здравствуйте Garvold, Вы писали:
G> Свалился тут на меня один громоздкий проект с большим колличеством графики, но ,из-за отсутствия должного опыта в работе с графикой, я увяз в нём как в болоте :-( G> G> Люди добрые, кто в этой области шарит , поведайте пожалуйста как правильно перерисовывать графические объекты (Rect,Rgn,Text и т.д.) при использование зума, скрола, драг-н-дропа ну и прочих передвижений, так, что бы они не мигали...
G> Я отдаю себе отчёт, что такого рода информация может оказаться очень объёмной, G>но я был бы рад любому намёку, подсказке или , может быть, линку на какой-нибудь материал по этой теме.
G> Заранее благодарен.
Я могу только несколько общих советов дать.
1. Сначала рисовать всё в память (CreateCompatibleDC & Co), а потом выводить результат на экран.
2. Можно перехватывать сообщение WM_ERASEBKGND и не делать в обработчике ничего, а главное — не вызывать стандартный обработчик. Можно вместо этого поставить фону окна прозрачную кисть (GetStockObject(NULL_BRUSH) или HOLLOW_BRUSH). Но учти, что при этом фон окна не будет восстанавливаться автоматически.
3. При прокрутке использовать ScrollDC или ScrollWindow
4. При рисовании в OnPaint рисовать только то, что нужно. Т.е. использовать информацию из поля m_ps CPaintDC.
P.S. В Программисте #2001_8 ,была статья на эту тему. Но она ... как бы это по мягче сказать.. Короче, если не ошибаюсь, я уже посоветовал больше чем там. Но, возможно, я что-то не упомянул. Статья очень маленькая, можно прочитать даже у прилавка магазина. В online на www.programme.ru её нет.
Здравствуйте Garvold, Вы писали:
SH>>А перетаскивать только рамку нельзя? Рамку можно рисовать XOR-ом.
G> XOR — это, я так понимаю, что-то из GDI+ ? (короче я не сталкивался)
Нет. Это такое условное название для одного из режимов рисования линий (в том числе) на DC. Пиксели цвета текущего pen'а просто копируются. А в этом режиме проводится операция XOR (в С обозначается ^) между пикселем pen'а и пикселем DC. Основной смысл в том, что:
1. Что бы не было нарисовано на DC, белая линия скорее всего будет видима (исключение — серый цвет 128, 128, 128).
2. Для стирания линии достаточно ещё раз нарисовать такую же линию в том же месте и в том же режиме. Это верно т.к. (A XOR B) XOR B == A
Режимы задаются функцей SetROP2, то что я говорил — параметр R2_XORPEN
G> А я рисую контур фигур линиями , но для перерисовки нужной области знаю только InvalidateRgn (ну или InvalidateRct)
G> Как я могу перерисовать только контур ?
Не обязательно перерисовывать всё в OnPaint. Есть функция GetDC, которая позволяет рисовать что угодно в любом месте программы.
Здравствуйте Аноним, Вы писали:
А> Да, и ещё одна странность: Если многократно симулировать перерисовку какого-то одного прямоугольника, через какое-то время он теряет и заливку и содержание (просто становится белым прямоугольником)
Действительно, странно.. Но идея есть. Если я правильно догадался, то у тебя есть родительское окно, на нём дочерние и вот в дочернем этот самый прямоугольник. И, ко всему, у родительского окна белый фон и отсутствует стиль WS_CLIPCHILDREN. Тогда (наверное), возможна ситуация, когда родительское окно перересует этот прямоугольник (просто зальёт своим фоном), а дочернее ещё нет.
Если я угадал правильно, то:
1. Поставь WS_CLIPCHILDREN
2. Если дочернее окно занимает всю клиентскую область родительского, поставь родительскому пустую кисть. Это должно положительно сказаться на производительности.
Здравствуйте Garvold, Вы писали:
G>Спасибо огроменное !!!! Вроде всё заработало как надо...
G>Последний вопрос: G> Когда я увеличиваю изображение, текст, в процессе увеличения, жутко искажается (буквы становятся какими-то кривыми и некрасивыми)
Увеличиваю это StretchBlt? Тогда ничего не поделаешь, красиво будет (теоретически, я не пробовал) только при увиличении в целое количество раз.
Есть два альтернативных варианта:
1. Увиличивать размер шрифта и отрисовывать заново. Если шрифт TrueType, наверное получится неплохо.
2. Использовать метофайлы. Я с ними работал совсем чить-чуть, поэтому незнаю, насколько хорошо будет увиличиваться текст. Зато знаю, что метафайл с битмапами плохо поддаётся масштабированию (знаю — сильно сказано. В моём единсвенном эксперементе под XP система отказалась изменять размер метафайла с битмапом. Причём не просто отказалась, а ругнулась как-то.). Но попробовать стоит.
Метафайлы, конечно, рисуются медленнее чем BitBlt. Но, если тебе нужно часто изменять размер можно совместить эти два подхода. Т.е. из метафайла в memory DC, из него BitBlt на экран.
В MSDN искать по CreateEnhMetaFile. Есть ли MFC-реализация не знаю, но с API MFC уживается без проблем. Использовать обычные (не Enhanced) метафайлы не имеет смысла, т.к. они хуже.
Здравствуйте Garvold, Вы писали:
G>Я, наверное, уже всех задолбал со своими вопросами, но....
G>Когда я меняю размеры своего главного окна (а в нём у меня плавает три вьюера) , G>дергается рамка вместе с менюшками и тулбарами. ON_SIZE для вьюеров я обработал, а вот для главного фрэйма — чего-то не ладится
В смысле не ладится? WM_SIZE не обрабатывается или что?
Но вообще-то это нормальное явление. Я сейчас попробовал — и у IE и у MSDN и у VC дергается (я, конечно, не знаю насколько сильно дёргается у тебя, но у этих вполне заметно). Наверное в обработчике WM_SIZE происходит что-то не очень быстрое. Вряд ли это связано с рисованием, скорее с пересчётом координат и перемещением дочерних окон.
Не уверен, что имеет смысл оптимизировать этот процесс (если это вообще возможно) т.к. вряд ли пользователь будет постоянно изменять размер окна.
Свалился тут на меня один громоздкий проект с большим колличеством графики, но ,из-за отсутствия должного опыта в работе с графикой, я увяз в нём как в болоте :-(
Люди добрые, кто в этой области шарит , поведайте пожалуйста как правильно перерисовывать графические объекты (Rect,Rgn,Text и т.д.) при использование зума, скрола, драг-н-дропа ну и прочих передвижений, так, что бы они не мигали...
Я отдаю себе отчёт, что такого рода информация может оказаться очень объёмной,
но я был бы рад любому намёку, подсказке или , может быть, линку на какой-нибудь материал по этой теме.
Здравствуйте Garvold, Вы писали:
G> Свалился тут на меня один громоздкий проект с большим колличеством графики, но ,из-за отсутствия должного опыта в работе с графикой, я увяз в нём как в болоте G> G> Люди добрые, кто в этой области шарит , поведайте пожалуйста как правильно перерисовывать графические объекты (Rect,Rgn,Text и т.д.) при использование зума, скрола, драг-н-дропа ну и прочих передвижений, так, что бы они не мигали...
G> Я отдаю себе отчёт, что такого рода информация может оказаться очень объёмной, G>но я был бы рад любому намёку, подсказке или , может быть, линку на какой-нибудь материал по этой теме.
G> Заранее благодарен.
ИМХО, тут два основных момента:
1. Рисовать не на экране, а в совместимом контексте, который в оперативной памяти.
2. Перерисовывать только необходимую область, а не все окно.
Re[2]: Проблема перерисовок .....
От:
Аноним
Дата:
04.08.02 10:32
Оценка:
Здравствуйте KaSA, Вы писали:
KSA>ИМХО, тут два основных момента:
KSA>1. Рисовать не на экране, а в совместимом контексте, который в оперативной памяти. KSA>2. Перерисовывать только необходимую область, а не все окно.
Большое спасибо за столь быстрый ответ !
Дело в том , что, вроде, я так и делаю...
Но при перетаскивание, например прямоугольника, мигает его внутренняя область
(я , в свою очередь, перерисовываю только сам прямоугольник...)
Да, забыл сказать, что заливка фона — чёрная
Здравствуйте Аноним, Вы писали:
А>Здравствуйте KaSA, Вы писали:
KSA>>ИМХО, тут два основных момента:
KSA>>1. Рисовать не на экране, а в совместимом контексте, который в оперативной памяти. KSA>>2. Перерисовывать только необходимую область, а не все окно.
А> Большое спасибо за столь быстрый ответ ! А>Дело в том , что, вроде, я так и делаю...
А>Но при перетаскивание, например прямоугольника, мигает его внутренняя область А>(я , в свою очередь, перерисовываю только сам прямоугольник...) А>Да, забыл сказать, что заливка фона — чёрная
Кисть окна обнулить надо и самому бекграунд отрисовывать.
Здравствуйте Аноним, Вы писали:
А>Но при перетаскивание, например прямоугольника, мигает его внутренняя область А>(я , в свою очередь, перерисовываю только сам прямоугольник...) А>Да, забыл сказать, что заливка фона — чёрная
А перетаскивать только рамку нельзя? Рамку можно рисовать XOR-ом.
Делай что должно, и будь что будет
Re[2]: Проблема перерисовок .....
От:
Аноним
Дата:
04.08.02 11:11
Оценка:
Здравствуйте SergH
Огромное спасибо за информацию...
Пойду попробую, хотя, я делаю почти то же самое, что вы подсказали, но кистью для фона окна я ещё не игрался..
Да, и ещё одна странность: Если многократно симулировать перерисовку какого-то одного прямоугольника, через какое-то время он теряет и заливку и содержание (просто становится белым прямоугольником)
Здравствуйте SergH, Вы писали:
SH>Здравствуйте Аноним, Вы писали:
А>>Но при перетаскивание, например прямоугольника, мигает его внутренняя область А>>(я , в свою очередь, перерисовываю только сам прямоугольник...) А>>Да, забыл сказать, что заливка фона — чёрная
SH>А перетаскивать только рамку нельзя? Рамку можно рисовать XOR-ом.
XOR — это, я так понимаю, что-то из GDI+ ? (короче я не сталкивался)
А я рисую контур фигур линиями , но для перерисовки нужной области знаю только InvalidateRgn (ну или InvalidateRct)
Я, наверное, уже всех задолбал со своими вопросами, но....
Когда я меняю размеры своего главного окна (а в нём у меня плавает три вьюера) ,
дергается рамка вместе с менюшками и тулбарами. ON_SIZE для вьюеров я обработал, а вот для главного фрэйма — чего-то не ладится
Здравствуйте Аноним, Вы писали:
А>Здравствуйте SergH
А>Огромное спасибо за информацию... А>Пойду попробую, хотя, я делаю почти то же самое, что вы подсказали, но кистью для фона окна я ещё не игрался..
А> Да, и ещё одна странность: Если многократно симулировать перерисовку какого-то одного прямоугольника, через какое-то время он теряет и заливку и содержание (просто становится белым прямоугольником)
Ты уверен, что после перерисовки ты все перья и кисточки восстанавливаешь?