![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Ошибка в коде, который раньше работал. [D7, XP]
kyn66 © (2009-11-03 13:14:00)Уважаемые мастера. Помогите найти ошибку в коде, взятом из рабочей программы:
1) Наполняем stданными
procedure FormSt;
Var
st : TStringList;
Bitmap1 : TBitmap;
begin
st := TStringList.Create;
Bitmap1 := TBitmap.Create;
ListBox1.Clear;
for i := 1 to KolLotery do
begin
DM1.ImageList1.GetBitmap(32, Bitmap1);
st.AddObject('первая запись', Bitmap1);
st.AddObject('вторая запись', Bitmap1);
st.AddObject('третья запись', Bitmap1);
end;
ListBox1.Items.AddStrings(st);
st.Free;
Bitmap1.Free;
end;
2) Отрисовываем ListBox с пиктограммами
procedure TMainFrm.ListBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
Var
Offset : Integer;
Bitmap : TBitmap;
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}
end;
Ошибка вылетает на "жирной" строке
kyn66 (2009-11-03 14:45:00) [21]
> Сергей М. © (03.11.09 13:51) [27]
> Вернись к варианту, котоый был раньше ("работал").И вынеси
> GetBitmap из тела цикла.
Все понял! Спасибо!
Тема закрыта.
Демо (2009-11-03 14:06:00) [22]
> Сергей М. © (03.11.09 13:53) [28]
>
> > главное потом не забыть его удалить по завершении
>
>
> Можешь даже и не удалять - система не обеднеет, это для
> нее не потеря.
>
>
Ж-))
Сергей М. (2009-11-03 13:53:00) [23]
> главное потом не забыть его удалить по завершении
Можешь даже и не удалять - система не обеднеет, это для нее не потеря.
kyn66 (2009-11-03 13:51:00) [24]
> и почему бы не вызвать DM1.ImageList1.GetBitmap(32, Bitmap1);
> один раз?а при закрытии программы убить глобальный объект
> Bitmap1
Согласен, так можно и сделать. У Bitmap1небольшая смысловая нагрузка, в плане просто картинку передать и все. Можно его отдельно создать и главное потом не забыть его удалить по завершении.
Сергей М. (2009-11-03 13:51:00) [25]Вернись к варианту, котоый был раньше ("работал").
И вынеси GetBitmap из тела цикла.
kyn66 (2009-11-03 13:48:00) [26]2Сергей М.
Как посоветует мастер поступить в такой ситуации? Чтобы и волки были сыты......
clickmaker (2009-11-03 13:47:00) [27]> Я подумал что он уже не нужен, поскольку Listbox1 уже наполнен
> данными
AddObject не копирует объект.
и почему бы не вызвать DM1.ImageList1.GetBitmap(32, Bitmap1); один раз?
а при закрытии программы убить глобальный объект Bitmap1
kyn66 (2009-11-03 13:45:00) [28]
> Сергей М. © (03.11.09 13:41) [20]
> Теперь тебя ждут другие грабли - утечка памяти
:) Сообщение появилось пока я про это и пмсал [22].
kyn66 (2009-11-03 13:44:00) [29]Просто procedure FormSt;может повторяться несколько раз, поэтому и решил что нужно удалять ненужные объекты, так как в этой процедуре Bitmap1 создается заново
Bitmap1 := TBitmap.Create;
Dennis I. Komarov (2009-11-03 13:43:00) [30]
> Сергей М. © (03.11.09 13:41) [20]
Фигня то какая... Разве ее мало? Разве нас это заставит буквари читать?
Сергей М. (2009-11-03 13:41:00) [31]
> акомментировал "убийство" Bitmap1 и все пошло нормально
Теперь тебя ждут другие грабли - утечка памяти
kyn66 (2009-11-03 13:39:00) [32]
> Сергей М. © (03.11.09 13:34) [14]
Я дико извеняюсь, но закомментировал "убийство" Bitmap1 и все пошло нормально. Я подумал что он уже не нужен, поскольку Listbox1 уже наполнен данными... ListBox1.Items.AddStrings(st);
clickmaker (2009-11-03 13:36:00) [33]> Bitmap локально объявлен во второй процедуре и с успехом
> инициализируется там же
>
> Bitmap := TBitmap(ListBox1.Items.Objects[Index]);
это не инициализация. Это присваивание значения указателя, который указывает уже на труп
Сергей М. (2009-11-03 13:36:00) [34]
> смутные сомнения по поводу корректной отработки st.AddObject('вторая
> запись', Bitmap1)
Не терзайся, он работает абсолютно корректно - копирует строки и ассоциированные с ними ссылки.
Сергей М. (2009-11-03 13:35:00) [35]
> и с успехом инициализируется там же
>
мусором !
Объекта-то нет, ты уничтожил его доэтого !
Сергей М. (2009-11-03 13:34:00) [36]
> ошибка в блоке после проверки Bitmap на nil
А почему бы ей не быть не-nil ?
Ты же записал не-nil, вот она и прошла проверку.
А объект ты убил.
А ссылка на него осталась.
kyn66 (2009-11-03 13:34:00) [37]
> получает значение, равное копии указателя на объект, который
> ты собственноручно убил в 1-й процедуре.
Bitmapлокально объявлен во второй процедуре и с успехом инициализируется там же
Bitmap := TBitmap(ListBox1.Items.Objects[Index]);
Терзают смутные сомнения по поводу корректной отработки st.AddObject('вторая запись', Bitmap1)...
Dennis I. Komarov (2009-11-03 13:32:00) [38]
> И тем более ошибка в блоке после проверки Bitmap на nil
А с чего ты взял, что там nil?
Сергей М. (2009-11-03 13:32:00) [39]
> в коде, который раньше работал
Раньше был другойкод.
Потому и работал.
kyn66 (2009-11-03 13:31:00) [40]
> а потом обращаешься к трупу за свойством Transparent
И тем более ошибка в блоке после проверки Bitmap на nil