Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2011.09.04;
Скачать: [xml.tar.bz2];

Вниз

отрисовка Items в tlistbox   Найти похожие ветки 

 
stay unknown   (2011-05-12 15:57) [0]

Нужно рисовать айтемы листбокса.

Кажды айтем должен получится вида:

Тип:           Телевизор ЖК \ ТВ
Производитель: Samsung
Модель:        UE37C6540SW

Слева еще иконка товара будет. Вопрос: как лучше организовать отрисовку:

- написать функцию, что-то типа:


function DrawBlockProductDescription(Canvas: TCanvas; X, Y: Int; Margins: TMargins; Bitmap: TBitmap): TRect;


- написать класс.

Что посоветуете?


 
Kerk ©   (2011-05-12 15:58) [1]

Да функции хватит. Зачем тут целый класс.


 
b z   (2011-05-12 16:02) [2]


> Что посоветуете?
ListView


 
Лукошко   (2011-05-12 16:31) [3]

Есс-но, это - простой пример на скорую руку, сделай нормально.

Класс товара:


type
TItem=class
 public
   tp:string;
   ds:string;
   md:string;
 end;


В коде:


{заполнение листбокса товаром}
procedure TForm1.Button1Click(Sender:TObject);
var
 i:integer;
 item:TItem;
begin
 for i:=1 to 10 do begin
   item:=TItem.Create;
   item.tp:="Тип продукции: "+IntToStr(i)+" DFG";
   item.ds:="Производитель продукции: "+IntToStr(i)+" manufacture";
   item.md:="Модель: "+IntToStr(i)+" serial";
   ListBox1.AddItem(item.tp,item);
 end;
end;

{отрисовка}
procedure TForm1.ListBox1DrawItem(Control:TWinControl; Index:Integer; Rect:TRect; State:TOwnerDrawState);
var
 LoadIndex:integer;
 Bitmap:TBitmap;
 BMPRect:TRect;
 ColorRect:TRect;
begin
 with TListBox(Control),Canvas do begin
   {выделяем выделение :o)}
   if odSelected in State then Brush.Color:=$00FAEADC
   else Brush.Color:=clWindow;
   FillRect(Rect);
   {рисуем разделители}
   Pen.Style:=psDot;
   Pen.Color:=clGray;
   MoveTo(128,Rect.Top);
   LineTo(128,Rect.Bottom);
   MoveTo(Rect.Left,Rect.Bottom-1);
   LineTo(Rect.Right,Rect.Bottom-1);
   {левая строка}
   Font.Color:=clNavy;
   Font.Size:=8;
   Font.Style:=[fsBold];
   TextOut(Rect.Left+20,Rect.Top+2,TItem(Items.Objects[index]).md);
   {верхняя строка}
   Font.Color:=clBlack;
   Font.Size:=8;
   Font.Style:=[fsBold];
   TextOut(Rect.Left+150,Rect.Top+2,TItem(Items.Objects[index]).tp);
   {нижняя строка}
   Font.Color:=clMaroon;
   Font.Size:=7;
   Font.Style:=[];
   TextOut(Rect.Left+166,Rect.Top+17,TItem(Items.Objects[index]).ds);
   {убираем рамку}
   if odFocused in State then DrawFocusRect(Rect);
 end;
end;


 
Лукошко   (2011-05-12 16:37) [4]

Рисовка иконки из иконлиста:

BlaBlaImageList.Draw(TListBox(Control).Canvas,10,Rect.Top+5,IconIndex,true);


Рисовка иконки из битмапа:

   {рисуем иконку}
var
 Bitmap:TBitmap;
 BMPRect:TRect;
begin
   Bitmap:=TBitmap.Create;
   try
     Bitmap.LoadFromFile({путь к файлу, к примеру});
     if Bitmap<>nil then begin
       BMPRect:=Bounds(36,Rect.Top+7,16,16);
       BrushCopy(BMPRect,Bitmap,Bounds(0,0,Bitmap.Width,Bitmap.Height),Bitmap.Canvas.Pi xels[15,0]);
     end;
   finally
     Bitmap.Free;
   end;
end;


 
Лукошко   (2011-05-12 16:39) [5]

У листбокса должен быть style=lbOwnerDrawVariable или lbOwnerDrawFixed.
Первый - для разных по высоте итемов, если мне не изменяет память.


 
KilkennyCat ©   (2011-05-12 17:12) [6]


> type
> TItem=class
>  public
>    tp:string;
>    ds:string;
>    md:string;
>  end;
>

из пушки по воробьям.


 
clickmaker ©   (2011-05-12 17:39) [7]

> из пушки по воробьям

почему? У него же реальный объект "Телевизор" с параметрами, как раз тянет на класс


 
Лукошко   (2011-05-12 17:45) [8]


> KilkennyCat ©   (12.05.11 17:12) [6]

Так удобнее же.
Хотя можно и рекорд, и вообще строку с разделителями :o)


 
stay unknown   (2011-05-12 18:05) [9]

с отрисовкой разобрался, теперь сложность в другом. айтем может быть 3 видов:

Тип:           Телевизор ЖК \ ТВ
Производитель: Samsung
Модель:        UE37C6540SW

Тип:         не найден (<ID типа>)

Модель:      не найдена (<ID модели>)

Размер айтема напрямую зависит от высоты блока рисуемой информации в событии OnDrawItem. Как динамически менять его размер. Знаю что размер можно менять в OnMeasureItem, но как из события узнать высоту нарисованного блока.


 
clickmaker ©   (2011-05-12 18:09) [10]

> как из события узнать высоту нарисованного блока

Canvas.TextHeight


 
stay unknown   (2011-05-12 18:27) [11]

Я про другое

у меня размер блока выводимой информации рассчитывается на момент отрисовки (не для всех Items он одинаковый). Сам блок представляет собой несколько TextOut"ов разделенных между собой.

Все возможные варианты.

(1)

Тип:           Телевизор ЖК \ ТВ
Производитель: Samsung
Модель:        UE37C6540SW

(2)

Тип:           Телевизор ЖК \ ТВ
Производитель: Samsung

(3)

Производитель: Samsung
Модель:        UE37C6540SW

(4)

Тип:           Телевизор ЖК \ ТВ
Модель:        UE37C6540SW

(5)

Тип:           Телевизор ЖК \ ТВ

(6)

Производитель: Samsung

(7)

Модель:        UE37C6540SW

Блок 1 - одного размера, 2, 3, 4 - другого, 5,6,7 - третьего

Как из OnMeasureItem получить высоту отрисованного блока для I-ого айтема


 
KilkennyCat ©   (2011-05-12 18:32) [12]


> clickmaker ©   (12.05.11 17:39) [7]

потому, что тут достаточно

> Лукошко   (12.05.11 17:45) [8]


как-то привык, что в переменных хранятся данные того же типа, что и переменная (а не использование, например, строковых для чисел). Это удобно. При виде класса я буду предполагать наличие гораздо большего, чем пара переменных.


 
Игорь Шевченко ©   (2011-05-12 18:34) [13]


> Как из OnMeasureItem получить высоту отрисованного блока
> для I-ого айтема


item же передается, по нему и вычислить


 
KilkennyCat ©   (2011-05-12 18:35) [14]


> Как из OnMeasureItem получить высоту отрисованного блока
> для I-ого айтема

высчитать сразу при отрисовке.


 
Лукошко   (2011-05-12 18:46) [15]

Меняем условие:

{заполнение листбокса товаром}
procedure TForm1.Button1Click(Sender: TObject);
var
 i:integer;
 item:TItem;
begin
 for i:=1 to 10 do begin
   item:=TItem.Create;
   item.tp:="Тип продукции: "+IntToStr(i)+" DFG";
   if (i mod 2)=0 then item.ds:="Производитель продукции: "+IntToStr(i)+" manufacture"
   else item.ds:="";
   item.md:="Модель: "+IntToStr(i)+" serial";
   ListBox1.AddItem(item.ds,item); //обрати внимание - передаю другой итем
 end;
end;


Вычисление высоты:

{меняем высоту итема}
procedure TForm1.ListBox1MeasureItem(Control:TWinControl; Index:Integer; var Height:Integer);
begin
 if TListBox(Control).Items[Index]="" then Height:=20;
end;


ЗЫ: Обрати внимание, объект item в AddItem добавляется ПОСЛЕ вызова MeasureItem


 
Лукошко   (2011-05-12 18:50) [16]


> KilkennyCat ©   (12.05.11 18:32) [12]

Ну так-то согласен, рекорд понятнее.


> Игорь Шевченко ©   (12.05.11 18:34) [13]

В том-то и дело, что ещё не передался Item, только после OnMeasureItem добавляется ссылка. Ну или ткните меня носом :o)


 
clickmaker ©   (2011-05-12 18:58) [17]

> Ну так-то согласен, рекорд понятнее

вообще, объектную модель не гуй должен диктовать. Сегодня листбокс, а завтра разноцветный суперпупергридвью какой-нить с хедерами и футерами.


 
Игорь Шевченко ©   (2011-05-12 19:10) [18]


> В том-то и дело, что ещё не передался Item, только после
> OnMeasureItem добавляется ссылка. Ну или ткните меня носом
> :o)


http://msdn.microsoft.com/en-us/library/bb775925(v=vs.85).aspx


 
Лукошко   (2011-05-12 19:18) [19]


> clickmaker ©   (12.05.11 18:58) [17]

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


> Игорь Шевченко ©   (12.05.11 19:10) [18]

Прочитал.


 
Игорь Шевченко ©   (2011-05-12 19:24) [20]

Лукошко   (12.05.11 19:18) [19]


> Прочитал.


Там написано, что сообщение посылается в зависимости от стиля, если стиль с элементами фиксированной высоты, то один раз для контрола, если стиль с элементами разной высоты, то для каждого элемента.
Поэтому фраза

> только после OnMeasureItem добавляется ссылка

в этом контексте звучит слегка некорректно


 
Лукошко   (2011-05-12 19:37) [21]


> Игорь Шевченко ©   (12.05.11 19:24) [20]

Я понял, что там написано :o)
Да, согласен, немного не так. Ну так у автора как раз вэриэйбл высота, сообщение посылается каждый раз. Но ещё до добавления ссылки на объект в AddObject"е.


 
Игорь Шевченко ©   (2011-05-12 21:16) [22]

Лукошко   (12.05.11 19:37) [21]

Все, сообразил.

TListBoxStrings.Add посылает LB_ADDSTRING, а Object к этому моменту еще не установлен, потому что TStrings.AddObject сначала выполняет Add, а потом PutObject

Я бы в таком случае хранил список объектов отдельно и использовал бы виртуальный ListBox


 
Лукошко   (2011-05-12 21:32) [23]


> Игорь Шевченко ©   (12.05.11 21:16) [22]

Я именно так и сделал, виртуальный ListBox. Вообще, не очень удобно сделано в генофонде, много лишнего надо писать.

Автор топика, думаю, может обойтись > Лукошко   (12.05.11 18:46) [15]


 
Dimka Maslov ©   (2011-05-12 22:13) [24]

Что мешает воспользоваться компонентом TListView, у которого уже есть возможность отрисовки иконок?


 
Германн ©   (2011-05-13 02:47) [25]


> Dimka Maslov ©   (12.05.11 22:13) [24]
>
> Что мешает воспользоваться компонентом TListView, у которого
> уже есть возможность отрисовки иконок?
>

А при чем тут "возможность отрисовки иконок"?


 
Лукошко   (2011-05-13 15:12) [26]

Так вот старался-старался, писал, собирал у себя готовый код, а автор даже спасибо не сказал :o(
У вас тут все студенты неблагодарные?


 
KilkennyCat ©   (2011-05-13 18:10) [27]


> Лукошко   (13.05.11 15:12) [26]

настоящие герои плюют на признание толпы.


 
Лукошко   (2011-05-13 19:10) [28]


> KilkennyCat ©   (13.05.11 18:10) [27]

Хыхы
Мне до героя далекоооо... :o)



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

Форум: "Прочее";
Текущий архив: 2011.09.04;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.004 c
15-1305311860
Kerk
2011-05-13 22:37
2011.09.04
Паттерны проектирования


15-1304872083
HF-Trade
2011-05-08 20:28
2011.09.04
Капча javascript


2-1305913737
TarenoKostanay
2011-05-20 21:48
2011.09.04
Вставка стороннего приложения в окно программы


2-1305875891
samalex2504
2011-05-20 11:18
2011.09.04
Установить формат ячейки в Excel


8-1215855784
AlexanderMS
2008-07-12 13:43
2011.09.04
Программа вылетает на команде IGraphBuilder.RenderFile





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский