Инкрементальный поиск в ListBox II
Я видел приложение, в котором ListBox позволял осуществлять инкрементальный поиск. При вводе очередного символа он позиционирует вас к первой ячейке, начало значения которой совпадает с введенным пользователем текстом, или выделяет все строки с текстом, содержащим введенный текст.
Как это осуществить на Delphi?
Здесь придется немного воспользоваться Win API. Установите свойство формы KeyPreview в True и сделайте примерно следующее:
unit LbxSrch;
interface
uses Windows, Messages, SysUtils, Classes, Controls, Forms, StdCtrls;
type TFrmLbxSrch = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
ListBox1: TListBox;
Label1: TLabel;
procedure FormKeyPress(Sender: TObject; var Key: Char);
procedure ListBox1Enter(Sender: TObject);
private
{ Private declarations }
FPrefix: array[0..255] of char;
public
{ Public declarations }
end;
varFrmLbxSrch: TFrmLbxSrch;
implementation
{$R *.DFM}
procedure TFrmLbxSrch.FormKeyPress(Sender: TObject; var Key: Char);
{ Помните о том, что свойство KeyPreview должно быть установлено в True }
var
curKey: array[0..1] of char;
ndx: integer;
begin
if ActiveControl = ListBox1 then begin
if key = #8 {Backspace (клавиша возврата)} then begin
if FPrefix[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));
if ndx <> LB_ERR then ListBox1.ItemIndex := ndx;
end;
Label1.Caption := StrPas(FPrefix);
Key := #0;
end;
end;
procedure TFrmLbxSrch.ListBox1Enter(Sender: TObject);
begin
FPrefix[0] := #0;
Label1.Caption := StrPas(FPrefix);
end;
end.
– Ralph Friedman
Табуляция в графическом ListBox'е
Письмо читателя
Использование табуляции в ListBox'е когда компонент находится в стандартном режиме не составляет труда. Но что делать если надо использовать графическое отображение элементов списка? Ведь при этом надо самому писать обработчик отрисовки элементов с разбиением на колонки. Элементарное решение — использование API функции TabbedTextOut, однако результаты работы этой функции меня явно не удовлетворили. Пришлось-таки "выкручиваться"… Символ-разделитель можно использовать любой. Например, будем использовать символ "|", тогда обработчик OnDrawItem может выглядеть следующим образом:
procedure TBrowser.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);
If P=0 then Ss:=S
else Ss:=Copy(S, 1, P-1);
// Если нет табуляции, то пишем всю строку, иначе отрезаем кусок до разделителя
ListBox1.Canvas.TextOut(Rect.Left + 20, Rect.Top + 2, Ss);
If P>0 then
ListBox1.Canvas.TextOut(ListBox1.TabWidth, Rect.Top + 2, Copy(S, P+1, Length(S)-P+2));
end;
end;
Не забудьте перед запуском поставить нужное значение TabWidth.
Virtualik
Выравнивание в ListBox'е
Delphi 1
Перед тем, как вычислить позицию фразы, необходимо с помощью функции TextWidth вычислить ее ширину.
Например:
var J, TempInt, LongPrefixLen, CurrPrefixLen: Integer;
begin
{Вычисляем TextWidth по ключевой строке}