Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Рисовать в ячейках KOLecmListEdit [Delphi, Windows]


Rusya ©   (2007-04-26 16:57:00) 

В одном столбце KOLecmListEdit в каждой ячейке вместе с текстом надо отрисовать значок (битма из ресурса). Назначаю обработчик OnDrawCell, и в нем пишу:
function TForm1.ListEditDrawCell(Sender: PObj; DC: HDC; const Rect: TRect;
 ACol, ARow: Integer; DrawAction: TDrawAction; ItemState: TDrawState): Boolean;
var
 R: TRect;  Glyph: PBitmap;
begin
 Result := false;
 if (ACol = 2 { столбец с рисунками } ) and (odaEntire in DrawAction) then
 begin
  if ((ARow = ListEdit.LVCurItem) and ( lvoRowSelect in ListEdit.LVOptions) ) then
   ListEdit.Canvas.Brush.Color := $F3E6CD // Hilight ECMListEdit color
  else
   ListEdit.Canvas.Brush.Color := clWindow;

   ListEdit.Canvas.FillRect( Rect );
   Glyph:= NewDIBBitmap( 16, 16, pf24bit );
   with Glyph^ do
   begin
    LoadFromResourceName( hInstance, '#100' );
    DrawTransparent(DC, Rect.Left + 2, Rect.Top + 2, clFuchsia);
    Free;
   end;

   R := Rect;
   Inc(R.Left, 24);
   Inc(R.Top, 2);
   ListEdit.Canvas.DrawText( ListEdit.LVItems[ARow, ACol], R, 0 );
   ListEdit.Canvas.Brush.Color := clWindow;
   Result := true;
 end;
end;

Отрисовывается сначала нормально, но при прокрутке списка или при щелчке на элементах списка появляются артефакты на уже отрисованных картинках в ячейках. Как победить эту проблему? Ведь список должен сам перерисовываться и при прокрутке, и при смене текущего элемента?


Rusya   (2007-04-30 22:48:00) [1]

Все понятно, разобрался.


Vladimir Kladov   (2007-04-30 22:05:00) [2]

Чего читать? DC - это дескриптор устройства для рисования. Можно рисовать функциями только API и не заводить объект канвы, сокращая размер кода.


Rusya   (2007-04-30 19:03:00) [3]


> Vladimir Kladov   (30.04.07 16:55) [11]
> Если используется DC, то не надо использовать Canvas.Handle
> и другие функции канвы. Потому что это может испортить дескриптор
> и DC уже не будет соответствовать тому, что передан при
> входе в обработчик. DC только для случае, когда кроме самого
> DC ничего не нужно.

Я так понимаю - в обработчике "или-или",- можно использовать или только DC, или только Canvas.Handle?

И в процедуру DC передается, чтобы с него читать можно было только?
Если так, то почему на него и писать нельзя?


Vladimir Kladov   (2007-04-30 16:55:00) [4]

Если используется DC, то не надо использовать Canvas.Handle и другие функции канвы. Потому что это может испортить дескриптор и DC уже не будет соответствовать тому, что передан при входе в обработчик. DC только для случае, когда кроме самого DC ничего не нужно.


Dimaxx   (2007-04-30 12:06:00) [5]

Возможно на время обработки события создается копия канвы и именно ее хэндл передается в обработчик. Это-то и приводит к глюкам...


Dimaxx   (2007-04-30 12:04:00) [6]

Я тоже не понимаю почему работает вариант ListEdit.Canvas.Handle, а не работает DC. Ведь по идее DC берется из ListEdit.Canvas.Handle.


Rusya   (2007-04-28 22:22:00) [7]


> > Dimaxx ©   (28.04.07 11:29) [3]> Попробуй еще вместо DC везде
> > использовать ListEdit.Canvas.Handle - помню была трабла с отрисовкой
> > именно из-за этого. Применил хэндл канвы - все стало ок.

> Сейчас попробую.

Все стало на свои места. Вместо DC написал ListEdit.Canvas.Handle,
т.е. вместо DrawTransparent(DC, Rect.Left + 2, Rect.Top + 2, clFuchsia);получилось DrawTransparent( ListEdit.Canvas.Handle, Rect.Left + 2, Rect.Top + 2, clFuchsia);Спасибо, Dimaxx. Вроде работает без глюков втаком варианте, вот только не понятно, - почему не работает с DC.


Rusya   (2007-04-28 22:07:00) [8]


> Dimaxx ©   (28.04.07 11:32) [4]
> Да, вот еще что. Поскольку иконка одна на все (я так понял),
>  попробуй ничего не меняя загрузить ее при старте приложения
> (а не внутри OnDrawCell) и удалять только при закрытии приложения.
>  Возможно из-за этого могут вылезать артефакты...

Это ничего не меняет, по моим наблюдениям - разницы нет никакой. Притом, в дальнейшем мне понадобится грузить здесь разные битмапы и отрисовывать их, в зависимости от ячейки.


Rusya   (2007-04-28 22:03:00) [9]


> Dimaxx ©   (28.04.07 11:29) [3]
> Вполне возможно не совсем правильно вычисляется Rect после
> прокрутки. Попробуй вычислять его из ACol & ARow самостоятельно.
> Хотя Rect и так вычисляется через свою процедуру... А какого
> характера артефакты? Смещенная иконка, неправильные цвета,
>  наложенные изображения?

наложенные изображения, часть битмапа накладывается на битмап из соседней ячейки, при прокручвании списка. При смене текущего элемента (щелчком на элементе) может исчезать битмап у соседних с ним элементов.

>Попробуй еще вместо DC везде использовать
> ListEdit.Canvas.Handle - помню была трабла с отрисовкой
> именно из-за этого. Применил хэндл канвы - все стало ок.

Сейчас попробую.


Dimaxx   (2007-04-28 11:34:00) [10]

Мысли приходят не сразу... :) Попробуй еще создавать битмар с нулевыми размерами, а не 16х16.


Dimaxx   (2007-04-28 11:32:00) [11]

Да, вот еще что. Поскольку иконка одна на все (я так понял), попробуй ничего не меняя загрузить ее при старте приложения (а не внутри OnDrawCell) и удалять только при закрытии приложения. Возможно из-за этого могут вылезать артефакты...


Dimaxx   (2007-04-28 11:29:00) [12]

Вполне возможно не совсем правильно вычисляется Rect после прокрутки. Попробуй вычислять его из ACol & ARow самостоятельно.

Хотя Rect и так вычисляется через свою процедуру... А какого характера артефакты? Смещенная иконка, неправильные цвета, наложенные изображения?

Попробуй еще вместо DC везде использовать ListEdit.Canvas.Handle - помню была трабла с отрисовкой именно из-за этого. Применил хэндл канвы - все стало ок.


Rusya   (2007-04-28 09:41:00) [13]

Ну как бы перерисовка есть (см. выше) и работает, но работает шероховато - в некоторых случаях подглючивает?? Не могу понять, почему.


Dimaxx   (2007-04-26 17:51:00) [14]

Нет, все нужно делать самому. Я не работал с данным компонентом, но, например, нарисовав на панели рисунок в событии OnPaint приходилось всегда его перерисовывать. Скорее всего также и тут.


Наверх

Титульная страница Поиск, карта сайта Написать письмо