Prisoner
спасибо, реализовал
Правда было довольно много мучений, распишу их, чтобы другие не мучались
1. В design-time надо ListBox'y установить опции loOwnerDrawFixed либо loOwnerDrawVariable (кстати, в чем разница?), иначе данная процедура по-видимому игнорируется.
2. Для программирующих не с помощью VCL, а с помощью KOL
Код:
function TForm1.ListBox1DrawItem(Sender: PObj; DC: HDC; const Rect: TRect;
ItemIdx: Integer; DrawAction: TDrawAction;
ItemState: TDrawState): Boolean;
var
S: string;
Sel: Boolean;
begin
S:=TKOLListBox(Sender).Items[ItemIdx];
Sel:=odsSelected in ItemState;
if Sel then begin
TKOLListBox(Sender).Canvas.Brush.Color:=clhighLight;
TKOLListBox(Sender).Font.Color:=clWhite;
end;
FillRect(DC, Rect, TKOLListBox(Sender).Canvas.Brush.Handle);
//TKOLListBox(Sender).Canvas.MoveTo(Rect.Left + 2, Rect.Top);
Windows.MoveToEx(DC, Rect.Left + 2, Rect.Top, nil);
SetTextAlign(DC, TA_LEFT or TA_UPDATECP);
TKOLListBox(Sender).Font.FontStyle:=[fsBold];
TextOut(DC, 0, 0, PChar(S), Length(S));
if Sel then begin
TKOLListBox(Sender).Font.Color:=clWindowText;
TKOLListBox(Sender).Canvas.Brush.Color:=clWindow;
end;
end;
Если не заменить закомментированную строку на ту, что идет следом, то все строки будут "рисоваться" в один ряд. По-видимому глюк программистов.
Кстати 2 проблемы еще остались. Надо выделенный элемент писать на синем фоне (ну как обычно). Для этого я ввёл обрабочик
Код:
if odsSelected in ItemState then ...
Но! Если операцию заливки (FillRect) выполнять
до вывода текста (TextOut), то сам текст выводится на белом фоне, а если
после - то текст "скрывается" под этим слоем краски.
Пока писал эти строки, допёрло как сделать
в самое начало надо добавить вызов SetBkMode, т.е.
Код:
....
begin
SetBkMode(DC, TRANSPARENT);
S:= ....
И последняя проблема:
Код:
....
TKOLListBox(Sender).Font.Color:=clWindowText;
....
Вот из-за этой строки (она почти в конце) ListBox перерисовывается бесчисленное число раз (я ждал около 30 сек, потом надоело; сама программа не зависает). Если ее (строку) закомментировать, то программа работает нормально. Причем если эту строку поместить в любое другое место процедуры, то результат опять же отрицательный... Ничего не понимаю...
В итоге выяснилось, что это происходит, когда используется больше 1 вызова свойства Font.Color . Причем даже если делать так:
Код:
....
if Sel then cl:=clWhite else cl:=clWindowText;
TKOLListBox(Sender).Font.Color:=cl;
....
Вот с этим я никак не могу разобраться...