Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.05.31;
Скачать: CL | DM;

Вниз

Как правильно отрисовать в 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 вся ветка

Текущий архив: 2009.05.31;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.014 c
15-1238293665
VirEx()
2009-03-29 06:27
2009.05.31
Скомпиленный интерпретатор


4-1188989858
Cj
2007-09-05 14:57
2009.05.31
Как получить путь к файлу...


3-1221766047
Девушка
2008-09-18 23:27
2009.05.31
Fib+ ClientDataSet + MasterDetail = Key Violation


2-1239776086
Лёша
2009-04-15 10:14
2009.05.31
Как сделать фильтр по Calculated полю?


3-1221628427
Drowsy
2008-09-17 09:13
2009.05.31
Invalid class typecast.