KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Валентин Озеров - Советы по Delphi. Версия 1.4.3 от 1.1.2001

Валентин Озеров - Советы по Delphi. Версия 1.4.3 от 1.1.2001

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Валентин Озеров, "Советы по Delphi. Версия 1.4.3 от 1.1.2001" бесплатно, без регистрации.
Перейти на страницу:

begin

 Label1.Caption:=Copy(GoString,i,LengthGoString);

 Inc(i);

 If Length(GoString)-LengthGoString < i then i:=1;

end

ListBox 

Навигация в ListBox при множественном выборе

Тема: Навигация в ListBox при множественном выборе

Данный пример выводит сообщение для каждого элемента Listbox, выбранного пользователем.

procedure TForm1.Button1Click(Sender: TObject);

var Loop: Integer;

begin

 for Loop := 0 to Listbox1.Items.Count – 1 do begin

  if listbox1.selected[loop] then ShowMessage(Listbox1.Items.Strings[Loop]);

 end;

end

Внешние данные и ListBox

Delphi 2 

Мне необходимо создать Listbox с использованием внешних данных, хранимых в огромном (!) TStringList. Существует ли какое-нибудь системное сообщение, которое я мог бы перехватывать для получения данных Listbox из внешнего TStringlist?

Просматривая справочник по API, я нашел интересный пункт, который может помочь вам решить проблему: в Win32 вы можете создать Listbox со стилем LBS_NODATA:

(из описания CreateWindow:)

LBS_NODATA

Определяет ListBox со стилем no-data (без данных). Данный стиль необходимо применять в случае, если количество элементов в ListBox превышает одну тысячу. no-data ListBox также должен иметь стиль LBS_OWNERDRAWFIXED, но не может иметь стиль LBS_SORT или LBS_HASSTRINGS.

no-data ListBox похож на owner-drawn ListBox за исключением того, что он не содержит в своих элементах строк и изображений (иконок). Команды добавления, вставки или удаления данных в элементах такого типа ListBox будут проигнорированы, а запросы для поиска строк всегда будут заканчиваться неудачей. При необходимости отрисовки данного элемента, Windows посылает родительскому окну сообщение WM_DRAWITEM. Член itemID стуктуры DRAWITEMSTRUCT, передаваемой с сообщением WM_DRAWITEM, определяет номер строки (элемент), который должен быть перерисован. no-data ListBox не посылает сообщение WM_DELETEITEM.

Количество элементов в таком списке вы можете установить с помощью сообщения LB_SETCOUNT. Это позволит вам создать «виртуальный» ListBox с очень небольшой загрузкой.

Чтобы воспользоваться новым стилем, вам нужно создать новый класс-наследник от TListbox и перекрыть метод CreateParams.

– Peter Below

Инкрементальный поиск в 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 по ключевой строке}

 {Устанавливаем CurrPrefixLen в TextWidth ключевого слова строки Indexth}

 LongPrefixLen := 0;

 for J := 0 to ListBox1.Items.Count-1 do

  with ListBox1.Canvas do begin

  TempInt:= TextWidth(Copy(Items[J], 1, Pos(KeyString, Items[J]-1)));

  if LongPrefixLen < TempInt then LongPrefixLen:= TempInt;

  if J = Index  then CurrPrefixLen:= TempInt;

 end;

 {PrevTextLeft – TextLeft = Где мы хотим вывести новый элемент}

 TextOut(LongPrefixLen-CurrPrefixLen, Y, Items[I]);

end;

Создание ListBox во время выполнения программы

Delphi 1

Установка выравнивания ListBox на alLeft вызывает изменение размеров ListBox при любом изменении размеров формы. Установка ширины происходит очень легко (помните о том, что ширина Width, которую вы видите в правой части строки, является свойством Width формы).

Количество элементов, хранимых ListBox, ограничено только доступной памятью.

procedure TForm1.CreateListBox;

var LB : TListBox;

begin

 LB := TListBox.Create;

 LB.Align := alLeft;

 LB.Width := Width div 2;

end;

Вот логика динамического создания ListBox и изменения его размера при изменения размеров формы. Я надеюсь, что помог вам. Также я подозреваю, что данные ListBox ограничены 32 килобайтами.

unit Unit1;


interface


uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls  { вам нужно это для ListBox }  ;


type TForm1 = class(TForm)

 procedure FormCreate(Sender: TObject);

 procedure FormResize(Sender: TObject);

private

 { Private declarations }

public

 { Public declarations }

end;


var

 Form1: TForm1;

 listbox: TListBox;


implementation


{$R *.DFM}


procedure TForm1.FormCreate(Sender: TObject);

begin

 listbox := TListBox.Create(self);

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*