-
Здравствуйте. Предпосылки моей проблемыМне нужно написать компонент, который представляет собой грид (матрицу из примоугольников). Грид содерит только статическую информацию: никакого ввода. Одной из задач является создание возможности объединения ячеек по горизонтали. Ну т.е. как в Екселе. Как я делалРассмотрим такой грид:
-----
|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. Практический. Что делать?
-
Немного ошибся в формулировке вопроса :( Надо так
1. Теоретический. Когда портится область ячейки D, то происходит инвалидация, потом WM_PAINT, причем регион клипиинга ограничивается только испорченной областью (т.е. не затрагивает ячейку С). Однако в WM_PAINT я делаю полную перерисовку области компонента и ячейки С (и как следствие области, занимаемой ячейкой D) в том числе. Почему не видно изменение ячейки D?
-
Написано слов много, а ведь в тумане все это... :( ВинАПИ, Грид, Ячейки.... почему, что, как?
-
слуш, давай по делу. вопрос сформулирован вполне четко. объясни, если сможешь, поведение системы (ОС, в смысле) в указанном случае? почему так?
я думаю, если пойму, то и проблему решу.
-
> Тимохов
Ты можешь привести упрощенный вариант кода (желательно рабочий), на котором повторяется такой глюк? Без этого очень сложно судить о твоей проблеме (она скорее всего в твоем коде).
-
> DVM © (10.05.08 23:48) [4]
Ок, попробую.
Еще раз перечитал Painting and drawing :) Я тоже начинаю приходить к мнению, что это в коде что-то такое есть, что не дает перерисовывать правильно.
Вообще изначально код был взят года 4 назад из TCustomGrid. Путем жесткой кастрации он был преобразован к текущему виду. Работает уже года 2, но только сегодня я захотел сделать span. Вот и напоролся.
В общем - попробую упростить код.
-
> .... Почему не видно изменение ячейки D?
> [3] Тимохов (10.05.08 22:54) > вопрос сформулирован вполне четко.
Согласен.... Вопрос более чем четкий. Тогда вот ответ: Потому что она не перерисовывается.)
Сорри... но присоединяюсь к [4] посту... Грид - на то он и содержит ячейки и рисует их по отдельности... стала ячейка инвалидом - перерисовали ее только.... но если она рисуется в другом месте - то нужно это учитывать...
Да видел я:
> Однако в WM_PAINT я делаю полную перерисовку области компонента > и ячейки С
...тут как запрограммируешь, так и будет.... и ничего другого не бывает....
-
> Тимохов (10.05.08 21:57) [1] > > Немного ошибся в формулировке вопроса :( > Надо так > > 1. Теоретический. Когда портится область ячейки D, то происходит > инвалидация, потом WM_PAINT, причем регион клипиинга ограничивается > только испорченной областью (т.е. не затрагивает ячейку > С). Однако в WM_PAINT я делаю полную перерисовку области > компонента и ячейки С (и как следствие области, занимаемой > ячейкой D) в том числе. Почему не видно изменение ячейки > D? >
Что-то похожее тут на форуме как-то было. То бишь был вопрос про "объединение ячеек грида". Правда там была работа со стандартным гридом, а не с собственным компонентом.
> Вообще изначально код был взят года 4 назад из TCustomGrid. > Путем жесткой кастрации он был преобразован к текущему > виду.
Вот в этом участке кода скорее всего собака и порылась.
-
Да, видимо, где-то в коде есть что-то :) Буду искать.
Потому как вроде не должно себя вести так: WM_PAINT приходит, перерисовку я делаю полную, поэтому полюбому D должен перерисовать.
-
Прошу прощения, за шум. Я все понял. Если интересно, то я разобрался в чем дело. Мой компонент - это когда-то сильно кастрированный 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 имеет какое-то отношение к клипингу. Назвали бы ее что-ли как-то удачней :)
|