Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.11.11;
Скачать: CL | DM;

Вниз

Проблемы отрисовки TComboBox в режиме OwnerDrawVariable   Найти похожие ветки 

 
Tack ©   (2007-06-29 17:46) [0]

Есть комбобокс, при раскрытии которого надо отрисовать 3 цветастеньких итема, каждый с разной высотой. Включаю режим OwnerDrawVariable, пишу обработчики OnMeasureItem, OnDrawItem. Все рисуется и рассчитывается, как надо, НО:
1) При свойствах

ItemHeight = 16; // стояло по умолчанию
DropDownCount = 3;

комбобокс не выпадает (выпадает полоска в 2 пикс.)

2) При свойствах

ItemHeight = 32;
DropDownCount = 64;

комбобокс выпадает и показывает 1 итем (по высоте первого), остальные надо прокручивать

3) При свойствах

ItemHeight = 100;
DropDownCount = 100;

список вываливается на фиксированную высоту, меньшую чем надо для отображения всех трех элементов. Опять появляется прокрутка.

Требуется, чтобы все три элемента выпали в список без прокрутки. Там где-то 300 пикселей по вертикали всего.

Числа ставил просто от фонаря, т.к. не могу вкурить, как они коррелируют.

Может, у кого-то была подобная проблема? Подскажите решение, пожалуйста.


 
Tack ©   (2007-06-29 20:02) [1]

вот пример кода, можете у себя запустить. Может это GDI у меня плохая, я уже не знаю что еще придумать:

unit Unit1;

interface

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

type
 TForm1 = class(TForm)
   ComboBox: TComboBox;
   procedure ComboBoxMeasureItem(Control: TWinControl; Index: Integer;
     var Height: Integer);
   procedure ComboBoxDrawItem(Control: TWinControl; Index: Integer;
     Rect: TRect; State: TOwnerDrawState);
   procedure FormCreate(Sender: TObject);
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ComboBoxMeasureItem(Control: TWinControl; Index: Integer;
 var Height: Integer);
begin
 // Рабочий вариант высот
//  case Index of
//   -1: Height := 16;
//    0: Height := 62;
//    1: Height := 75;
//    2: Height := 49;
//  end;

 // Нерабочий вариант высот
 case Index of
  -1: Height := 16;
   0: Height := 62;
   1: Height := 75;
   2: Height := 62;
 end;
end;

procedure TForm1.ComboBoxDrawItem(Control: TWinControl; Index: Integer;
 Rect: TRect; State: TOwnerDrawState);
var
 rc: TRect;
begin
 ComboBox.Canvas.FillRect(Rect);
 rc := Rect;
 InflateRect(rc, -3, -3);
 if not (odComboBoxEdit in State) then
 begin
   if odSelected in State then
   begin
     ComboBox.Canvas.Pen.Color := clRed;
     ComboBox.Canvas.Pen.Width := 3;
     ComboBox.Canvas.Rectangle(rc);
     ComboBox.Canvas.MoveTo(rc.Left, rc.Top);
     ComboBox.Canvas.LineTo(rc.Right, rc.Bottom);
     ComboBox.Canvas.MoveTo(rc.Left, rc.Bottom);
     ComboBox.Canvas.LineTo(rc.Right, rc.Top);
   end
   else
   begin
     ComboBox.Canvas.Pen.Color := clBlue;
     ComboBox.Canvas.Pen.Width := 3;
     ComboBox.Canvas.Rectangle(rc);
     ComboBox.Canvas.MoveTo(rc.Left, rc.Top);
     ComboBox.Canvas.LineTo(rc.Right, rc.Bottom);
     ComboBox.Canvas.MoveTo(rc.Left, rc.Bottom);
     ComboBox.Canvas.LineTo(rc.Right, rc.Top);
   end
 end
 else
   ComboBox.Canvas.TextOut(10, 4, "blablabla");
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 ComboBox.Width := 250;
 ComboBox.Style := csOwnerDrawVariable;
 ComboBox.ItemHeight := 62;  /// Если эту строку убрать, то список не выпадает
 ComboBox.DropDownCount := 3; // Если здесь поставить другие числа, то эффекта никакого
end;

end.



 
lottis   (2007-08-21 17:11) [2]

ты ItemHeight = 16; - оставь по умолчанию
а DropDownCount = 20; поставь 20. и всё прокатит.. :-)


 
Tack ©   (2007-08-21 22:42) [3]

> [2] lottis   (21.08.07 17:11)
> ты ItemHeight = 16; - оставь по умолчанию
> а DropDownCount = 20; поставь 20. и всё прокатит.. :-)

Попробовал, с нерабочим вариантом высот все равно появляется прокрутка :-(


 
Leonid Troyanovsky ©   (2007-08-23 12:06) [4]


> Tack ©   (21.08.07 22:42) [3]

> Попробовал, с нерабочим вариантом высот все равно появляется
> прокрутка :-(

В борландовской  реализации AdjustDropDown косяк:
не учиывается, что при csOwnerDrawVariable высота итемов разная.
Т.е., надо сделать наследника с примерно таким методом

procedure TMyComboBox.AdjustDropDown; // override;
var
 AHeight : Integer;
begin
  FDroppingDown := True;
  AHeight := .. ; // вычисляем требуемую высоту вып. списка
  SetWindowPos(FDropHandle, 0, 0, 0, Width, AHeight, SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_NOREDRAW or SWP_HIDEWINDOW);
  FdroppingDown := False;
  SetWindowPos(FDropHandle, 0, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or
  SWP_NOZORDER or SWP_NOACTIVATE or SWP_NOREDRAW or SWP_SHOWWINDOW);
end;

Но, скорее всего, больше чем на полувысоту экрана сделать его не дадут.

Если видна хотя бы часть последнего итема, то можно отказаться
от скролбара, перекрыв CreateParams:

inherited;
params := params and not CBS_NOINTEGRALHEIGHT and not WS_VSCROLL;

--
Regards, LVT.


 
Tack ©   (2007-08-26 12:04) [5]

Леонид, спасибо огромное!



Страницы: 1 вся ветка

Текущий архив: 2007.11.11;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.02 c
2-1192539115
фыва
2007-10-16 16:51
2007.11.11
TCheckListBox


15-1191914448
mefodiy
2007-10-09 11:20
2007.11.11
Зависание при работе BDE в ноутбуке HP с Vista Home Premium


2-1192618151
sydenis
2007-10-17 14:49
2007.11.11
rasdial


15-1191791670
malyar
2007-10-08 01:14
2007.11.11
как нарисовать линию зная ее угол наклона и длинну


2-1192455837
фыва
2007-10-15 17:43
2007.11.11
Вставка в мемо