![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Рисовать в ячейках 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 приходилось всегда его перерисовывать. Скорее всего также и тут.