Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Полезные примочки для ListBoxа и для ComboBoxа


Автор: Pakshin A. S. 14.3.2003, 03:13
Вставка в ListBox картинки.
Установите свойства Style = lbOwnerSrawFixed.
Модуль формы будет выглядеть так:
Код

unit Unit1;

interface

uses
Windows, Messages, SysUtils, variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

type
TForm1 = class (TForm)
 ListBox1: TListBox;
 procedure FormActivate(Sender: TObject);
 procedure ListBox1DrawItem(Control: TWinControl; Index: integer; Rect: TRect; State: TOwnerDrawState);
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormActivate(Sender: TObject);
var
Ico: TIcon;
begin
with ListBox1.Items do
 begin
  Ico:=TIcon.Create;
  Ico.LoadFromFile('c:\Program Files\Common Files\Borland Shared\Images\Icons\chemical.ico');
  AddObject('Some text', Ico);
  Ico:=Ticon.Create;
  Ico.LoadfromFile('c:\Program Files\Common Files\Borland Shared\Images\Icons\chip.ico');
  AddObject('Some text', Ico);
  Ico.Free;
 end;
end;

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: integer; Rect: TRect; State: TOwnerDrawState);
var
Ico:Ticon;
Offset:integer; //ширина отступа текста
begin
with (Control as TListBox).Canvas do
 begin
  FillRect(Rect);
  Offset:=2;
  Ico:=TIcon((Control as TListBox).Items.Objects[Index[);
  if Ico <> nil
   then
    begin
     Draw(Rect.Left + 1, Rect.Top + 2, TIcon((Control as TListBox).Items.Objects[Index]));
     OffSet:=Ico.Width + 9;
    end;
  TextOut(Rect.Left + OffSet, rect.Top + 7, (Control as TListBox).Items[Index]);
 end;
end;




Добавление горизональной полосы прокрутки в TListBox.
Код

procedure TForm1.FormCreate(Sender: TObject);
var
i, MaxWidth: integer;
begin
MaxWidth:=0;
for i:+0 to ListBox1.Items.Count-1 do
 if MaxWidth < ListBox1.Canvas.TextWidth(ListBox1.Items.Strings[i])
  then
   MaxWidth:=ListBox1.Canvas.textWidth(ListBox1.Items.Strings[i]);
SendMessage(ListBox1.Handle, LB_SETHORIZANTALEXTENT, MaxWidth + 2, 0);
end;




Компонент, реализующий Hint в выпадающем списке ComboBox

Код

type
TVSComboBox = class(TCustomComboBox)
...
private
 FHint: THintWindow;
...
protected
 procedure WMCTLCOLORLISTBOX(var Message: TMessage); message WM_CTLCOLORLISTBOX;
...

Главное не забыть выполнить инициальзацию компонента в конструкторе:
...
begin
inherited Create(AOwner);
FHint:=THintWindow.Create(Self);
...

Чтобы получить информацию об активной строке в выпадающем списке ComboBox, перезватите сообщение WM_CTLCOLORLISTBOX. В процедуре сообщения проанализируёте строку и, если её длинна больше ширины выпадающего списка, передайте "длинную строку" в FHint и активизируйте его:
FHint.ActivateHint(TextRc, Items[ItemIndex]);
Если активная строка в выпадающем списке "короткая" - спрячьте FHint:
FHint.ReleaseHandle;

Автор: Song 14.3.2003, 04:23
Это ты типа ликбез что ли? :-/

Автор: Medved 14.3.2003, 07:16
Всесьма похвально.... (без сарказма). Ликбез приветсвуется.

Автор: stab 14.3.2003, 11:13
Прикольно, только почему загрузка иконок в первом примере происходит при наступлении события OnActivate. Лучше это делать на OnCreate или OnShow...

Автор: Pakshin A. S. 15.3.2003, 04:15
Через несколько дней напишу ещё что-нибудь полезное...

Автор: Pakshin A. S. 15.3.2003, 04:20
Впринцепе в ListBox можно запихнуть и BitMap:
[CODE]
procedure ListDrawItem(...);
var
BitMap: TBitMap;
begin
// Инициализацию BitMapa писать не буду
...
with (Control as TListBox).Canvas do
begin
FillRect(Rect);
Draw(rect.Left, Rect.Top, BitMap);
TextOut(Rect.Left + 2 + BitMap.Width, Rect.Top, ListBox1.Items.Strings[Index]);
end;
end;
...

Автор: Pakshin A. S. 15.3.2003, 04:21
Чёрт, забыл закрыть секцию CODE, надо быть внимательнее...

Автор: Pakshin A. S. 15.3.2003, 04:31
Нашел в одной книге интересный пример:
Код

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: integer; Rect: TRect; State: TOwnerDrawState);
var
s:string;
Sym:char;
N:Word;
Def: TColor;
begin
with (Control as TListBox).Canvas do
 begin
  s:=Items[Index];
  Fillrect(Rect);
  MoveTo(Rect.Left + 2, Rect.Top);
  SetTextAlign(Canvas.Handle, TA_LEFT OR TA_UPDATECP);
  Def:=Font.Color;
  for n:=1 to Length(s) do
   begin
    Sym:=AnsiUpperCase(S[n])[1];
    case Sym of
     'А', 'Я': Font.Color:=clRed;
    else
     ForntColor:=Def;
    end;
  Windows.textOut(Convas.Handle, 0, 0, @S[N], 1);
 end;
end;
end;

В результате все буквы А и Я будут красного цвета.

Автор: MacTep 16.3.2006, 19:58
Ничего отрицательного сказать не хочу, но в последнем коде куча ошибок. Это раз! Два, он не работает нормально! Постарался исправить, ничего не получилось путевого. Может быть разберемся в нем и посраемся довести его до совершенства?

Автор: Quadr0 16.3.2006, 21:46
...

Автор: MacTep 16.3.2006, 22:21
Quadr0, ну вот это уже совсем другое дело. Но согласись, что вовсе не так, как написанов примере выше! smile
Добавлено @ 22:31
Quadr0, а можно узнать для чего нужны переменные ChRect, FocusRect: TRect;
и что обозначают куски кода:
Код

  { Цвет выделения и рамка }
  FocusRect := Rect;
  with FocusRect do
  begin
    Inc(Left, 1);
    Inc(Top, 1);
    Dec(Right, 1);
    Dec(Bottom, 1);
  end;
  with Lb.Canvas do
  begin
    Pen.Style := psClear;
    if odSelected in State then
      Brush.Color := clHighlight;
    FillRect(Rect);
    Rectangle(FocusRect);
  end;
  { Вывод текста }
  ChRect := Rect;
  with ChRect do
  begin
    Inc(Left, 4);
    Inc(Top, 1);
    Right := Left;
  end;

Попытался сам вникнуть, но не получилось! smile

Автор: Quadr0 16.3.2006, 22:49
...

Автор: MacTep 17.3.2006, 14:14
А как можно сделать так, чтобы, например, красным текстом были написаны лишь строки с номерами 1, 3, 5 и 7, а после нажатия на кнопку 2, 4, 6, 8???

Автор: _hunter 17.3.2006, 15:06
для определения строки в обработчик передается Index
для реакции на нажатие устанавливай где-нить флаг

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)