Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

У ListBox глючит событие ListBox1DrawItem ??? [D7, WinXP]


kyn66 ©   (2007-01-23 15:54:00) 

Добрый день! Чем большепрограммируешь, тем больше выявляется вопросов и непоняток. Вот сейчас у ListBox валит постоянно Access Violation в ситуации следующей:

Var
 st : TStringList;
 Bitmap1 : TBitmap;
 Bitmap2 : TBitmap;
begin
 Bitmap1 := TBitmap.Create;
 Bitmap2 := TBitmap.Create;
 st := TStringList.Create;
....
st.AddObject(MemTab.FieldByName('OSName').Value, Bitmap1);
st.AddObject(DM1.OsTbl.FieldByName('OSIndName').Value,Bitmap2);
...
 if st.Count <> 0 then
  begin
     RepMsgFrm := TRepMsgFrm.Create(Application);
     RepMsgFrm.ListBox1.Items.AddStrings(st);
     RepMsgFrm.ShowModal;
     st.Free;
     RepMsgFrm.Close;
     RepMsgFrm.Free;
     Close;
     Exit;
  end;
....

procedure TRepMsgFrm.ListBox1DrawItem(Control: TWinControl; Index: Integer;
 Rect: TRect; State: TOwnerDrawState);
Var
 Bitmap : TBitmap;
 Offset : Integer;
begin
 Offset := 0;
 with TCustomListBox(Control).Canvas do
  begin
    FillRect(Rect);
    Bitmap := TBitmap(ListBox1.Items.Objects[Index]);
    if Bitmap <> nil then
     begin
       Bitmap.Transparent :=True;
       BrushCopy(Bounds(Rect.Left + 2, Rect.Top + 2, Bitmap.Width, Bitmap.Height),
                 Bitmap, Bounds(0, 0, Bitmap.Width, Bitmap.Height), clWhite);
       Offset := Bitmap.Width + 8;
     end;
    TextOut(Rect.Left + Offset, Rect.Top, Listbox1.Items[Index]);
  end;{With}
 Bitmap.Destroy;
end;
...


Вопрос: почему в событии DrawItem, зная , что у ListBox1 3 итема, при втором прохождении вылетает Access Violation? При трассировке обнаруживается, что Indexостается неизменным и равен 0 ???
Вылетает после этой строки:

Bitmap := TBitmap(ListBox1.Items.Objects[Index]);
    if Bitmap <> nil then
...


Джо   (2007-01-23 19:33:00) [1]

Прекрасно. Вот смотри. Каждый раз, когда какая-то строка в Листбоксе перерисовывается, вызывается обработчик OnDrawItem. Повторю — для каждой строки и каждый раз, когда перерисовывается. Вопрос на засыпку — зачем ты в этом обработчике уничтожаешь экз. своих битмапов?


Kyn66   (2007-01-23 19:04:00) [2]

В данном случае я выразил не удивление свое, а констатацию факта, применив такой метод.


Плохиш   (2007-01-23 19:01:00) [3]


> А конкретнее мона в чем наивность заключается?

Выделено жирным шрифтом. Если, не дай сатана, будешь дальше программить не читая теории поймёшь, если успеешь до встречи с благодарными пользователями...


Kyn66   (2007-01-23 18:59:00) [4]


> Просто удивительно. А откуда в Objects вообще ссылки на
> битмапы берутся и где оные создаются?


А для этого нужно подняться вверх к моему вопросу и посмотреть выложенный код.


> Наивный чукотский мальчик. Хотя в данном случае медицина,
>  думается, бессильна.

А конкретнее мона в чем наивность заключается?


Плохиш   (2007-01-23 18:56:00) [5]


> Kyn66 ©   (23.01.07 18:51) [8]
> На onCreate формы я сделал
>
> Var Bitmap : TBitmap;
>
> Затем на событии ListBox1DrawItem
>
> Bitmap := TBitmap(ListBox1.Items.Objects[Index]);
>
> затем на Destroy формы
>
> Bitmap.Free;
>
>
> И все работает.

Наивный чукотский мальчик.
Хотя в данном случае медицина, думается, бессильна.


Джо   (2007-01-23 18:55:00) [6]

> [8] Kyn66 ©   (23.01.07 18:51)
> На onCreate формы я сделал
>
> Var Bitmap : TBitmap;
>
> Затем на событии ListBox1DrawItem
>
> Bitmap := TBitmap(ListBox1.Items.Objects[Index]);
>
> затем на Destroy формы
>
> Bitmap.Free;
>
>
> И все работает.

Просто удивительно. А откуда в Objects вообще ссылки на битмапы берутся и где оные создаются?


Kyn66   (2007-01-23 18:54:00) [7]

Воти получается , объявив один Bitmap , с ним и работаем. Поработали - уничтожили


Плохиш   (2007-01-23 18:51:00) [8]


> Сранно

Классно по клавише не попал :-)


Kyn66   (2007-01-23 18:51:00) [9]

На onCreateформы я сделал

Var Bitmap : TBitmap;

Затем на событии ListBox1DrawItem

Bitmap := TBitmap(ListBox1.Items.Objects[Index]);

затем на Destroyформы

Bitmap.Free;


И все работает.


Плохиш   (2007-01-23 18:50:00) [10]


> Kyn66 ©   (23.01.07 18:45) [5]
> Оригинальное решение.

В чём оригинальность?

> Однако а как я узнаю какому Bitmap-у я буду присваивать
> объект из ListBoxa?

Сранно, вроде все буквы/слова знакомые, а смысл вопроса ускользает. Ты - программер и присваивай адресобъекта той переменной, которой тебе и надо для дальнейшей обработки.


Kyn66   (2007-01-23 18:45:00) [11]

Оригинальное решение.Однако а как я узнаю какому Bitmap-у я буду присваивать объект из ListBoxa?
with TCustomListBox(Control).Canvas do
 begin
   FillRect(Rect);
   Bitmap := TBitmap(ListBox1.Items.Objects[Index]);
   if Bitmap <> nil then
    begin
      Bitmap.Transparent :=True;
      BrushCopy(Bounds(Rect.Left + 2, Rect.Top + 2, Bitmap.Width, Bitmap.Height),
                Bitmap, Bounds(0, 0, Bitmap.Width, Bitmap.Height), clWhite);
      Offset := Bitmap.Width + 8;
    end;
   TextOut(Rect.Left + Offset, Rect.Top, Listbox1.Items[Index]);
 end;{With}


TRUNK   (2007-01-23 16:43:00) [12]


> А как тогда правильно и где его объявлять .....?


const
 BitmapCount = x;

var
 Bitmaps: array[0..BitmapCount-1] of TBitmap;

procedure TForm1.Form1Create(Sender: TObject);
begin
//..................
for i := 0 to BitmapCount-1 do
 Bitmaps[i] := TBitmap.Create;
//..................
end;



> А как тогда правильно и где его .... освобождать?


procedure TForm1.Form1Destroy(Sender: TObject);
begin
//..................
for i := 0 to BitmapCount-1 do
 Bitmaps[i].Free;
//..................
end;


Kyn66   (2007-01-23 16:26:00) [13]

А как тогда правильно и где его объявлять и освобождать?


TRUNK   (2007-01-23 16:16:00) [14]

Из-за Bitmap.Destroy уже при второй перерисовке рисовать будет нечего.
P.S. Для уничтожения обьектов вместо Destroy рекомендуется использовать Free.


MBo   (2007-01-23 16:13:00) [15]

>при втором прохождении вылетает Access Violation?
дык
Bitmap.Destroy;


Наверх

Титульная страница Поиск, карта сайта Написать письмо