![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
У 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;