Валентин Озеров - Советы по Delphi. Версия 1.4.3 от 1.1.2001
- Название:Советы по Delphi. Версия 1.4.3 от 1.1.2001
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Валентин Озеров - Советы по Delphi. Версия 1.4.3 от 1.1.2001 краткое содержание
…начиная с 1001. Смотрите другие файлы…
Советы по Delphi. Версия 1.4.3 от 1.1.2001 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Письмо читателя
Использование табуляции в 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
Выравнивание в ListBox'е
Delphi 1
Перед тем, как вычислить позицию фразы, необходимо с помощью функции 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 во время выполнения программы
Delphi 1
Установка выравнивания 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 килобайтами.
unitUnit1;
interface
usesSysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls { вам нужно это для ListBox } ;
typeTForm1 = class(TForm)
procedureFormCreate(Sender: TObject);
procedureFormResize(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
listbox: TListBox;
implementation
{$R *.DFM}
procedureTForm1.FormCreate(Sender: TObject);
begin
listbox := TListBox.Create(self);
listbox.Parent := self;
listbox.Top := 0;
listbox.Left := 0;
listbox.Width := self.Width div2;
listbox.Height := self.Height div2;
listbox.items.add('тест 1');
listbox.items.add('тест 2');
{ и т.д, и т.п. … }
end;
procedureTForm1.FormResize(Sender: TObject);
begin
listbox.Width := self.Width div2 ;
listbox.Height := self.Height div2 ;
end;
end.
Двойной ListBox
Я расположил на форме два компонента Listbox, и с помощью следующего кода заполнил один из них данными из таблицы:
tableName.Refresh; {в вашем случае это может и не понадобится}
tableName.First; {Убедимся, что мы смотрим первую запись}
while nottableName.Eof do{проходим в цикле таблицу}
begin
listbox1.items.add(tableName.FieldByName('USRID').AsString); {добавляем элемент в listbox1}
tableName.Next; {переходим к следующей записи}
end;
ниже я привел процедуру из моего рабочего кода, в котором я использую эту технологию. Я передаю ей в качестве параметров имя таблицы и имена компонентов listbox1 и listbox2. Я пользуюсь этой процедурой, поскольку у меня есть несколько таблиц с полями одинакового типа:
procedureTTemplateFrm.buildList(tableName: TTable; SelBox, AvailBox: TListBox);
begin
{в этой процедуре мы собираемся добавить данные в listbox'ы}
{получаем любые новые данные}
tableName.Refresh;
{Убедимся, что мы смотрим первую запись}
tableName.First;
{Теперь очищаем ListBox'ы}
SelBox.Clear;
AvailBox.Clear;
{Теперь добавляем элементы}
while nottableName.EOF do begin
AvailBox.Items.Add(tableName.fieldByName('USRID').AsString + ' ' + tableName.fieldByName('DESCRIPTION').AsString);
tableName.Next;
end;
end;
Как перемещать данные между этими двумя списками? Если вы хотите использовать технологию «drag and drop» (перетащи и брось), то в обработчике mousedown вашей исходной таблицы воспользуйтесь процедурой begindrag:
ifButton = mbLeft thenTlistbox(sender).BeginDrag(false);
Затем, в вашем другом ListBox, для «опознания» и получения данных создайте следующий обработчик DragOver:
ifSource = ListBox1 thenAccept := true
elseAccept := false;
Не используйте «Accept := (Source is TListbox)», как это показано в большинстве примеров. У вас имеется два компонента ListBox, следовательно, вам нужно сослаться на имя объекта, а не на его тип, а иначе программа просто не поймет кто есть кто.
Затем в обработчике dragDrop поместите следующий код, добавляющий данные в ListBox2 и удаляющий их из ListBox1.
Listbox2.Items.Add(Listbox1.Items[Listbox1.ItemIndex]);
Listbox1.Items.Delete(Listbox1.ItemIndex);
И, наконец, добавьте кнопку «Сохранить», если вы хотите сохранить содержимое ListBox2 в базе данных.
Я надеюсь, что это именно то, что вы искали, и что это окажется вам полезным. Если вы хотите также перемещать данные из ListBox2 в ListBox1, вам необходимо будет создать тот же код, но реверсировать его для получения в коде правильных ссылок на компоненты ListBox.
ListBox — OnChange
Delphi 1
Интервал:
Закладка: