Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Компоненты и классы
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 19.03.2012, 21:23
Аватар для Amgsys HQ
Amgsys HQ Amgsys HQ вне форума
Начинающий
 
Регистрация: 11.11.2011
Адрес: Загрузочный сектор
Сообщения: 115
Версия Delphi: 7, XE
Репутация: 538
По умолчанию TListBox.Style = lbOwnerDrawVariable

Доброго времени суток!

Как видно по заголовку, на форме присутствует ListBox. Задача такая:
отрисовать самому пункты списка, но сделать так, чтобы выбранный
пункт списка был отличного размера от невыделенных (больше) +
добавить на него несколько кнопок. Можно ли такое реализовать?

Использую следующий код, но он не работает:

Код:
procedure MyListBoxMeasureItem(Control: TWinControl; Index: Integer;
  var Height: Integer);
begin
  if Index = TListBox(Control).ItemIndex then
    Height := 50
  else Height := 20;
end;

Заранее спасибо!
__________________
Работа пpогpаммиста и шамана имеет очень много общего:
оба боpмочyт непонятные слова, совеpшают непонятные действия и не могyт объяснить, как оно pаботает.
Ответить с цитированием
  #2  
Старый 19.03.2012, 21:47
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

А MyListBoxDrawItem при этом используется?
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #3  
Старый 19.03.2012, 21:57
Аватар для Amgsys HQ
Amgsys HQ Amgsys HQ вне форума
Начинающий
 
Регистрация: 11.11.2011
Адрес: Загрузочный сектор
Сообщения: 115
Версия Delphi: 7, XE
Репутация: 538
По умолчанию

Цитата:
Сообщение от angvelem
А MyListBoxDrawItem при этом используется?
Да, конечно, используется. Там есть параметр (State: TOwnerDrawState),
который используется для определения выделен элемент или нет, и, в
зависимости от этого, отрисовывается требуемое содержимое.
__________________
Работа пpогpаммиста и шамана имеет очень много общего:
оба боpмочyт непонятные слова, совеpшают непонятные действия и не могyт объяснить, как оно pаботает.
Ответить с цитированием
  #4  
Старый 19.03.2012, 22:02
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Ну так и выкладывай весь код ответственный за отрисовку.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #5  
Старый 20.03.2012, 16:28
Аватар для Amgsys HQ
Amgsys HQ Amgsys HQ вне форума
Начинающий
 
Регистрация: 11.11.2011
Адрес: Загрузочный сектор
Сообщения: 115
Версия Delphi: 7, XE
Репутация: 538
По умолчанию

Информационная структура элемента, откуда берется информация при
отрисовке элемента.

Код:
TEventsListItem = packed record
  ItemID: Integer;
  Title, Text: String;
  EventsTime: Double;
  ImageIndex: Integer;
  BrushColor: Integer;
  PenColor: Integer;
  procedure Assign(ASource: TEventsListItem);
end;

Код отрисовки (EventsList - мой класс, является хранилищем record'ов).
В списке EventsListBox содержатся значения TEventsListItem.ItemID

Код:
procedure TEventsListFrame.EventsListBoxDrawItem(Control: TWinControl;
  Index: Integer; Rect: TRect; State: TOwnerDrawState);
const
  IMAGE_TOP_MARGIN = 2;
  IMAGE_LEFT_MARGIN = 3;
  TITLE_LEFT_MARGIN = 4;
  TITLE_TOP_MARGIN = IMAGE_TOP_MARGIN + 1;
  DTIME_RIGHT_MARGIN = 4;
  DTIME_TOP_MARGIN = TITLE_TOP_MARGIN;
  TEXT_LEFT_MARGIN = IMAGE_LEFT_MARGIN;
  TEXT_RIGHT_MARGIN = DTIME_RIGHT_MARGIN;
  TEXT_TOP_MARGIN = 4;
  TEXT_BOTTOM_MARGIN = 2;
var
  FCanvas: TCanvas;
  FList: TStrings;
  S: String;
  TempColor: Integer;
  TempStyle: TFontStyles;
  TitleHeight: Integer;
  TextRect: TRect;
  EventData: TEventsListItem;
begin
  FCanvas := TListBox(Control).Canvas;
  FList := TListBox(Control).Items;
  FCanvas.FillRect(Rect);
  if Index < TListBox(Control).Items.Count then
  begin
    if not EventsList.SearchFor(StrToIntDef(FList[Index], 0), EventData) then Exit; // Поиск инфо-структуры по ItemID
    { Отрисовка изображения }
    FCanvas.Draw(Rect.Left + IMAGE_LEFT_MARGIN, Rect.Top + IMAGE_TOP_MARGIN,
      EventsListImages.PngImages[EventData.ImageIndex].PngImage);
    { Отрисовка заголовка события }
    TempColor := FCanvas.Font.Color;
    TempStyle := FCanvas.Font.Style;
    try
      if odSelected in State then
      begin
        FCanvas.Font.Color := clYellow;
        FCanvas.Font.Style := [fsBold];
      end;
      TitleHeight := FCanvas.TextHeight(EventData.Title);
      FCanvas.TextOut(Rect.Left + IMAGE_LEFT_MARGIN + 16 + TITLE_LEFT_MARGIN,
        Rect.Top + TITLE_TOP_MARGIN, EventData.Title);
    finally
      FCanvas.Font.Color := TempColor;
      FCanvas.Font.Style := TempStyle;
    end;
    { Отрисовка времени события }
    TempColor := FCanvas.Font.Color;
    try
      FCanvas.Font.Color := clSilver;
      S := TimeToStr(EventData.EventsTime);
      FCanvas.TextOut(Rect.Right - DTIME_RIGHT_MARGIN -
        FCanvas.TextWidth(S), Rect.Top + DTIME_TOP_MARGIN, S);
    finally
      FCanvas.Font.Color := TempColor;
    end;
    if odSelected in State then
    begin
      { Отрисовка текста события }
      TempColor := FCanvas.Font.Color;
      try
        FCanvas.Font.Color := clWhite;
        S := EventData.Text;
        TextRect.Left := Rect.Left + TEXT_LEFT_MARGIN;
        TextRect.Top := Rect.Top + TITLE_TOP_MARGIN + TitleHeight + TEXT_TOP_MARGIN;
        TextRect.Right := Rect.Right - TEXT_RIGHT_MARGIN;
        TextRect.Bottom := Rect.Bottom - TEXT_BOTTOM_MARGIN;
        DrawText(FCanvas.Handle, PChar(S), Length(S), TextRect, DT_WORDBREAK);
      finally
        FCanvas.Font.Color := TempColor;
      end;
    end;
  end;
end;

Размеры элемента списка.

Код:
procedure TEventsListFrame.EventsListBoxMeasureItem(Control: TWinControl;
  Index: Integer; var Height: Integer);
begin
  if Index = TListBox(Control).ItemIndex then
    Height := 48
  else Height := TListBox(COntrol).ItemHeight;
end;
__________________
Работа пpогpаммиста и шамана имеет очень много общего:
оба боpмочyт непонятные слова, совеpшают непонятные действия и не могyт объяснить, как оно pаботает.
Ответить с цитированием
  #6  
Старый 20.03.2012, 21:09
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

............
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #7  
Старый 20.03.2012, 21:32
Аватар для Amgsys HQ
Amgsys HQ Amgsys HQ вне форума
Начинающий
 
Регистрация: 11.11.2011
Адрес: Загрузочный сектор
Сообщения: 115
Версия Delphi: 7, XE
Репутация: 538
По умолчанию

Цитата:
Сообщение от angvelem
............
А можно теперь это расшифровать?

P.S. Знает ли кто-нибудь, как изменить высоту выделенной строки? Бог с этими кнопками...
__________________
Работа пpогpаммиста и шамана имеет очень много общего:
оба боpмочyт непонятные слова, совеpшают непонятные действия и не могyт объяснить, как оно pаботает.

Последний раз редактировалось Amgsys HQ, 20.03.2012 в 21:36.
Ответить с цитированием
  #8  
Старый 20.03.2012, 21:38
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Я по ошибке не там начал отвечать.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #9  
Старый 20.03.2012, 22:29
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Для изменения высоты выделенного Item-а, этого достаточно:
Код:
procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
var
  Selected : Boolean;
begin
  Selected := (State = [odSelected, odFocused]) or (State = [odSelected]);
  if Selected then
    SendMessage(ListBox1.Handle, LB_SETITEMHEIGHT, Index, 45)
  else
    SendMessage(ListBox1.Handle, LB_SETITEMHEIGHT, Index, 16);

  with ListBox1.Canvas do
  begin
    FillRect(Rect);
    if Selected then
    begin
      Font.Style := [fsBold];
      Font.Size := 24;
    end
    else
    begin
      Font.Style := [];
      Font.Size := 8;
    end;
    TextOut(Rect.Left + 1, Rect.Top + 1, ListBox1.Items[Index]);
  end;
end;
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #10  
Старый 22.03.2012, 15:41
Аватар для Amgsys HQ
Amgsys HQ Amgsys HQ вне форума
Начинающий
 
Регистрация: 11.11.2011
Адрес: Загрузочный сектор
Сообщения: 115
Версия Delphi: 7, XE
Репутация: 538
По умолчанию

angvelem, данный код работает, но выбранный элемент перекрывает элемент стоящий после него.
__________________
Работа пpогpаммиста и шамана имеет очень много общего:
оба боpмочyт непонятные слова, совеpшают непонятные действия и не могyт объяснить, как оно pаботает.
Ответить с цитированием
  #11  
Старый 22.03.2012, 17:06
Pyro Pyro вне форума
Так проходящий
 
Регистрация: 18.07.2011
Сообщения: 805
Версия Delphi: 7Lite
Репутация: 6063
По умолчанию

http://delphi.cjcsoft.net/viewthread.php?tid=47017
PHP код:
procedure Listbox_CalcLineHeights(AListbox:TListbox);
var
   
iinteger;
   
MeasureItemEvent TMeasureItemEvent;
begin
   
if Assigned(AListbox) and AListbox.HandleAllocated then begin
     with AListbox 
do begin
       MeasureItemEvent 
:= OnMeasureItem;
       if 
Assigned(MeasureItemEventthen begin
         
for i:=0 to Items.Count-do begin
           MeasureItemEvent
(AListboxih);
           
SendMessage(HandleLB_SETITEMHEIGHTih);
         
end;
       
end;
     
end;
   
end;
end
должно пересчитать высоты элементов
Ответить с цитированием
  #12  
Старый 23.03.2012, 11:37
Аватар для Amgsys HQ
Amgsys HQ Amgsys HQ вне форума
Начинающий
 
Регистрация: 11.11.2011
Адрес: Загрузочный сектор
Сообщения: 115
Версия Delphi: 7, XE
Репутация: 538
По умолчанию

Pyro, спасибо за код, он подходит. Но если в списке очень много элементов (например, более 1000), то перебирать все в подряд - это круто.
__________________
Работа пpогpаммиста и шамана имеет очень много общего:
оба боpмочyт непонятные слова, совеpшают непонятные действия и не могyт объяснить, как оно pаботает.
Ответить с цитированием
  #13  
Старый 23.03.2012, 21:21
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Дополнительно можно проверять на видимость iterm-а - обновлять только видимые.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 21:42.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter