Форум: "WinAPI";
Текущий архив: 2009.05.31;
Скачать: [xml.tar.bz2];
ВнизКак правильно отрисовать в WM_PAINT? Найти похожие ветки
← →
Тимохов (2008-05-10 21:01) [0]Здравствуйте.
Предпосылки моей проблемы
Мне нужно написать компонент, который представляет собой грид (матрицу из примоугольников). Грид содерит только статическую информацию: никакого ввода.
Одной из задач является создание возможности объединения ячеек по горизонтали. Ну т.е. как в Екселе.
Как я делал
Рассмотрим такой грид:
-----
|A|B|
-----
|C|D|
-----
Ячейки C и D объеденены. Т.е. ячейка C является головой объединения.
Я перекрыл метод Paint и отрисовываю там свой грид.
Я не обращаю внимание на регион клипинга, т.е. рисую во всей области компонента (отрисовка тривиальная и быстрая, незачем экономить).
При отрисовке ячейки С я определяю, что она является головой объединения. Поэтому я ее отрисовываю, задавая ее область, равную объединению областей С и D. Ячейку D я вообще не отрисовываю, просто пропускаю.
Проблемы
Если в рассмотренном примере чем-то инвалидейтить область ячейки D (например, провести по ней другим окном), но не затронуть ячейку C, то ячейка D отрисовывается некорректно (либо мусор, либо затирается). Если же затронуть ячейку C, то и C и D коорректно перерисовываются.
Почему такое получается я более-менее понимаю. Т.е. теорию вопроса про инвалидацию, валидаци, клипинг, WM_PAINT и пр. я знаю неплохо - сегодня прочел соответствующий раздел. Хотя, видимо, не до конца понимаю :)
Вопросы
1. Теоретический. Когда портится область ячейки D, то происходит инвалидация, потом WM_PAINT, причем регион клипиинга ограничивается только испорченной областью (т.е. не затрагивает ячейку С). Однако в WM_PAINT я делаю полную перерисовку области компонента и ячейки С (и как следствие области, занимаемой ячейкой В) в том числе. Почему не видно изменение ячейки D?
2. Практический. Что делать?
← →
Тимохов (2008-05-10 21:57) [1]Немного ошибся в формулировке вопроса :(
Надо так
1. Теоретический. Когда портится область ячейки D, то происходит инвалидация, потом WM_PAINT, причем регион клипиинга ограничивается только испорченной областью (т.е. не затрагивает ячейку С). Однако в WM_PAINT я делаю полную перерисовку области компонента и ячейки С (и как следствие области, занимаемой ячейкой D) в том числе. Почему не видно изменение ячейки D?
← →
{RASkov} © (2008-05-10 22:17) [2]Написано слов много, а ведь в тумане все это... :(
ВинАПИ, Грид, Ячейки.... почему, что, как?
← →
Тимохов (2008-05-10 22:54) [3]слуш, давай по делу. вопрос сформулирован вполне четко.
объясни, если сможешь, поведение системы (ОС, в смысле) в указанном случае? почему так?
я думаю, если пойму, то и проблему решу.
← →
DVM © (2008-05-10 23:48) [4]
> Тимохов
Ты можешь привести упрощенный вариант кода (желательно рабочий), на котором повторяется такой глюк? Без этого очень сложно судить о твоей проблеме (она скорее всего в твоем коде).
← →
Тимохов (2008-05-10 23:54) [5]
> DVM © (10.05.08 23:48) [4]
Ок, попробую.
Еще раз перечитал Painting and drawing :) Я тоже начинаю приходить к мнению, что это в коде что-то такое есть, что не дает перерисовывать правильно.
Вообще изначально код был взят года 4 назад из TCustomGrid. Путем жесткой кастрации он был преобразован к текущему виду. Работает уже года 2, но только сегодня я захотел сделать span. Вот и напоролся.
В общем - попробую упростить код.
← →
{RASkov} © (2008-05-11 00:25) [6]> .... Почему не видно изменение ячейки D?
> [3] Тимохов (10.05.08 22:54)
> вопрос сформулирован вполне четко.
Согласен.... Вопрос более чем четкий.
Тогда вот ответ: Потому что она не перерисовывается.)
Сорри... но присоединяюсь к [4] посту...
Грид - на то он и содержит ячейки и рисует их по отдельности... стала ячейка инвалидом - перерисовали ее только.... но если она рисуется в другом месте - то нужно это учитывать...
Да видел я:
> Однако в WM_PAINT я делаю полную перерисовку области компонента
> и ячейки С
...тут как запрограммируешь, так и будет.... и ничего другого не бывает....
← →
Германн © (2008-05-11 00:50) [7]
> Тимохов (10.05.08 21:57) [1]
>
> Немного ошибся в формулировке вопроса :(
> Надо так
>
> 1. Теоретический. Когда портится область ячейки D, то происходит
> инвалидация, потом WM_PAINT, причем регион клипиинга ограничивается
> только испорченной областью (т.е. не затрагивает ячейку
> С). Однако в WM_PAINT я делаю полную перерисовку области
> компонента и ячейки С (и как следствие области, занимаемой
> ячейкой D) в том числе. Почему не видно изменение ячейки
> D?
>
Что-то похожее тут на форуме как-то было. То бишь был вопрос про "объединение ячеек грида". Правда там была работа со стандартным гридом, а не с собственным компонентом.
> Вообще изначально код был взят года 4 назад из TCustomGrid.
> Путем жесткой кастрации он был преобразован к текущему
> виду.
Вот в этом участке кода скорее всего собака и порылась.
← →
тимохов (2008-05-11 13:22) [8]Да, видимо, где-то в коде есть что-то :)
Буду искать.
Потому как вроде не должно себя вести так: WM_PAINT приходит, перерисовку я делаю полную, поэтому полюбому D должен перерисовать.
← →
тимохов (2008-05-11 13:58) [9]Прошу прощения, за шум. Я все понял.
Если интересно, то я разобрался в чем дело.
Мой компонент - это когда-то сильно кастрированный TCustomGrid.
Вчера я в него дописывал объединения ячеек. Делал это в функции DrawCells в методе TCustomGrid.Paint.
Алгоритм отрисовки я уже писал выше: видя, что ячейка С - голова объединения я присоединял к ней прямоугольник ячейки D. Потом отрисовывал C в новом прямоугольнике, а D вообще пропускал.
В функции DrawCell есть проверкаif (Where.Right > Where.Left) and RectVisible(Canvas.Handle, Where) then ...
Собсно ошибка была моя в том, что у меня Where - это область исходной ячейки С, без присоединенной D. А т.к. RectVisible возвращает True, если Where внутри региона клипинга, то, если портить только D, то отрисовки C вообще не было. Отсюда и мусор в ячейке D, так как ее область вообще не отрисовывалась.
В общем я во всем разобрался. Никаких чудес.
ЗЫ
Блин, в голову не могло, что RectVisible имеет какое-то отношение к клипингу. Назвали бы ее что-ли как-то удачней :)
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2009.05.31;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.005 c