unitLbxSrch;
interface
usesWindows, Messages, SysUtils, Classes, Controls, Forms, StdCtrls;
typeTFrmLbxSrch = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
ListBox1: TListBox;
Label1: TLabel;
procedureFormKeyPress(Sender: TObject; varKey: Char);
procedureListBox1Enter(Sender: TObject);
private
{ Private declarations }
FPrefix: array[0..255] ofchar;
public
{ Public declarations }
end;
varFrmLbxSrch: TFrmLbxSrch;
implementation
{$R *.DFM}
procedureTFrmLbxSrch.FormKeyPress(Sender: TObject; varKey: Char);
{ Помните о том, что свойство KeyPreview должно быть установлено в True }
var
curKey: array[0..1] ofchar;
ndx: integer;
begin
ifActiveControl = ListBox1 then begin
ifkey = #8 {Backspace (клавиша возврата)} then begin
ifFPrefix[0] <> #0 then begin
FPrefix[StrLen(FPrefix) - 1] := #0;
end
end else begin
curKey[0] := Key;
curKey[1] := #0;
StrCat(FPrefix, curKey);
ndx := SendMessage(ListBox1.Handle, LB_FINDSTRING,-1, longint(@FPrefix));
ifndx <> LB_ERR thenListBox1.ItemIndex := ndx;
end;
Label1.Caption := StrPas(FPrefix);
Key := #0;
end;
end;
procedureTFrmLbxSrch.ListBox1Enter(Sender: TObject);
begin
FPrefix[0] := #0;
Label1.Caption := StrPas(FPrefix);
end;
end.
– Ralph Friedman
Табуляция в графическом ListBox'е
Использование табуляции в ListBox'е когда компонент находится в стандартном режиме не составляет труда. Но что делать если надо использовать графическое отображение элементов списка? Ведь при этом надо самому писать обработчик отрисовки элементов с разбиением на колонки. Элементарное решение — использование API функции TabbedTextOut, однако результаты работы этой функции меня явно не удовлетворили. Пришлось-таки "выкручиваться"… Символ-разделитель можно использовать любой. Например, будем использовать символ "|", тогда обработчик OnDrawItem может выглядеть следующим образом:
procedureTBrowser.ListBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
S, Ss: String;
P: Integer; // Флаг символа-разделителя
begin
begin
ListBox1.Canvas.FillRect(Rect);
//Отрисовка графики
…
//
S:=ListBox1.Items.Strings[Index];
P:=Pos('|', S);
IfP=0 thenSs:=S
elseSs:=Copy(S, 1, P-1);
// Если нет табуляции, то пишем всю строку, иначе отрезаем кусок до разделителя
ListBox1.Canvas.TextOut(Rect.Left + 20, Rect.Top + 2, Ss);
IfP>0 then
ListBox1.Canvas.TextOut(ListBox1.TabWidth, Rect.Top + 2, Copy(S, P+1, Length(S)-P+2));
end;
end;
Не забудьте перед запуском поставить нужное значение TabWidth.
Virtualik
Перед тем, как вычислить позицию фразы, необходимо с помощью функции TextWidth вычислить ее ширину.
Например:
varJ, TempInt, LongPrefixLen, CurrPrefixLen: Integer;
begin
{Вычисляем TextWidth по ключевой строке}
{Устанавливаем CurrPrefixLen в TextWidth ключевого слова строки Indexth}
LongPrefixLen := 0;
forJ := 0 toListBox1.Items.Count-1 do
with ListBox1.Canvas do begin
TempInt:= TextWidth(Copy(Items[J], 1, Pos(KeyString, Items[J]-1)));
ifLongPrefixLen < TempInt thenLongPrefixLen:= TempInt;
ifJ = Index thenCurrPrefixLen:= TempInt;
end;
{PrevTextLeft – TextLeft = Где мы хотим вывести новый элемент}
TextOut(LongPrefixLen-CurrPrefixLen, Y, Items[I]);
end;
Создание ListBox во время выполнения программы
Установка выравнивания ListBox на alLeft вызывает изменение размеров ListBox при любом изменении размеров формы. Установка ширины происходит очень легко (помните о том, что ширина Width, которую вы видите в правой части строки, является свойством Width формы).
Количество элементов, хранимых ListBox, ограничено только доступной памятью.
procedureTForm1.CreateListBox;
varLB : TListBox;
begin
LB := TListBox.Create;
LB.Align := alLeft;
LB.Width := Width div2;
end;
Вот логика динамического создания ListBox и изменения его размера при изменения размеров формы. Я надеюсь, что помог вам. Также я подозреваю, что данные ListBox ограничены 32 килобайтами.
Читать дальше