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

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

Ошибка в коде, который раньше работал. [D7, XP]


Страницы:   1 2 3

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


Страницы:   1 2 3

Наверх

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