Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.03.2011, 14:27   #1
ArtGrek
DelphiProger
Участник клуба
 
Аватар для ArtGrek
 
Регистрация: 14.11.2010
Сообщений: 1,023
Стрелка Динамическое создание и удаление компонент

вопрос, что я делаю не так? мне при удалении выдает Access violation, уже не первую подобную тему создаю и всеравно никак

что не верно, создание, выбор хозяина, выбор родителя, удаление, размер массива

Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, Spin;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Memo1: TMemo;
    ImBox: TScrollBox;
    procedure NewLength(sl: integer);
    procedure NewCreate(Sc: Integer);
    procedure NewDelete(sd: integer);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Panels: array of TPanel;
  Images: array of TImage;
  Effects: array of TComboBox;
  EffectsL: array of TLabel;
  Intervals: array of TSpinEdit;
  IntervalsL: array of TLabel;
  Checks: array of TCheckBox;

  IndexN: integer = -1;

implementation

{$R *.dfm}

procedure TForm1.NewLength(sl: integer);
begin
  Memo1.Lines.Add('New Lendgth ' + IntToStr(sl));

  SetLength(Panels,sl);
  SetLength(Images, sl);
  SetLength(Effects, sl);
  SetLength(EffectsL, sl);
  SetLength(Intervals, sl);
  SetLength(IntervalsL, sl);
  SetLength(Checks, sl);
end;

procedure TForm1.NewCreate(sc: integer);
begin
  NewLength(sc + 1);
  Memo1.Lines.Add('Created im N ' + IntToStr(Sc));

  Panels[sc] := TPanel.Create(ImBox);
  with Panels[sc] do
  begin
    Parent := ImBox;
    Top := 15;
    Left := 267 * sc + 15 * (sc + 1);
    Width := 267;
    Height := 150;
  end;
  Images[sc] := TImage.Create(Panels[sc]);
  Images[sc].Parent := Panels[sc];
  Effects[sc] := TComboBox.Create(Panels[sc]);
  Effects[sc].Parent := Panels[sc];
  EffectsL[sc] := TLabel.Create(Panels[sc]);
  EffectsL[sc].Parent := Panels[sc];
  Intervals[sc] := TSpinEdit.Create(Panels[sc]);
  Intervals[sc].Parent := Panels[sc];
  IntervalsL[sc] := TLabel.Create(Panels[sc]);
  IntervalsL[sc].Parent := Panels[sc];
  Checks[sc] := TCheckBox.Create(Panels[sc]);
  Checks[sc].Parent := Panels[sc];
end;

procedure TForm1.NewDelete(sd: integer);
begin
  Memo1.Lines.Add('Delete im N ' + IntToStr(Sd));

  Images[sd].Free;
  Effects[sd].Free;
  EffectsL[sd].Free;
  Intervals[sd].Free;
  IntervalsL[sd].Free;
  Checks[sd].Free;
  Panels[sd].Free;
  NewLength(IndexN);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  inc(IndexN);
  NewCreate(IndexN);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  i_delete, j_delete: integer;
begin
  for i_delete := IndexN downto 0 do
    if Checks[i_delete].Checked = True then
    begin
      NewDelete(i_delete);
      dec(IndexN);
    end;
end;

end.
VirusN13
ArtGrek вне форума Ответить с цитированием
Старый 01.03.2011, 15:35   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

не нравится мне строка NewLength(IndexN); в процедуре NewDelete, а если её закоментировать? Хотя наврядли поможет - удаление выборочное, а в массивах указателей всегда обрезается хвост, а нужно наверно организовывать перемещение указателей перед обрезкой хвоста
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 01.03.2011 в 15:41.
Аватар вне форума Ответить с цитированием
Старый 01.03.2011, 15:52   #3
ArtGrek
DelphiProger
Участник клуба
 
Аватар для ArtGrek
 
Регистрация: 14.11.2010
Сообщений: 1,023
По умолчанию

Цитата:
а нужно наверно организовывать перемещение указателей перед обрезкой хвоста
а как? я раньше и по другому удалял, но результат тотже был
VirusN13
ArtGrek вне форума Ответить с цитированием
Старый 01.03.2011, 17:33   #4
chertovich
Форумчанин
 
Аватар для chertovich
 
Регистрация: 26.07.2009
Сообщений: 489
По умолчанию

при освобождении используй
Код:
FreeAndNil
, а при создании, проверяй, может он уже создан:
Код:
  if not Assigned(Button) then
    Button := TButton.Create(Self);
Если в глубине души вы программист, то, следуя своим наклонностям, вы захотите написать кусок кода.
chertovich вне форума Ответить с цитированием
Старый 01.03.2011, 21:05   #5
ArtGrek
DelphiProger
Участник клуба
 
Аватар для ArtGrek
 
Регистрация: 14.11.2010
Сообщений: 1,023
По умолчанию

Цитата:
FreeAndNil
еффект такои же

Цитата:
Аватар нужно наверно организовывать перемещение указателей перед обрезкой хвоста
вы не могли бы пояснить как?
VirusN13
ArtGrek вне форума Ответить с цитированием
Старый 01.03.2011, 21:14   #6
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Код:
procedure TForm1.NewDelete(sd: integer);
var i: Integer;
begin
  Memo1.Lines.Add('Delete im N ' + IntToStr(Sd));

  Images[sd].Free;
  Effects[sd].Free;
  EffectsL[sd].Free;
  Intervals[sd].Free;
  IntervalsL[sd].Free;
  Checks[sd].Free;
  Panels[sd].Free;
  for i:=sd to IndexN-1 do begin
    Images[i]:=Images[i+1];
    Effects[i]:=Effects[i+1];
    EffectsL[i]:=EffectsL[i+1];
    Intervals[i]:=Intervals[i+1];
    IntervalsL[i]:=IntervalsL[i+1];
    Checks[i]:=Checks[i+1];
    Panels[i]:=Panels[i+1];
  end;
  NewLength(IndexN);
end;
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 02.03.2011, 13:32   #7
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Ват вам ППниПП
Один слепой по команде ложит яйца в лоток для яиц и запоминает, сколько он уже положил. Другой слепой ищет тухлые яйца (по запаху конечно) и, если находит такое, то кричит "Нашел тухлое яйцо" и выкидывает его.
Прикол в том, что слепой (тот, который ложит яйца) не знает какое яйцо оказалось тухлым и считает что это было именно последнее яйцо. Соответственно, подкладывает новые яйца на уже занятые места.
В итоге, когда второй слепой начинает свой нюхательный обход и доходит до пустого лотка его сильно переглючивает от такой кализии, что ему приходится нюхать яйцо, которого нет.

Во-первых:
Выкинь и забудь глобальную переменную IndexN

Во-вторых:
Пользуйся TList или "открой глаза" и прежде чем ложить яйцо найди пустое место.

Последний раз редактировалось Sibedir; 02.03.2011 в 13:36.
Sibedir вне форума Ответить с цитированием
Старый 02.03.2011, 13:52   #8
ArtGrek
DelphiProger
Участник клуба
 
Аватар для ArtGrek
 
Регистрация: 14.11.2010
Сообщений: 1,023
По умолчанию

Цитата:
Ват вам ППниПП
....
супер, спасибо, доходчивее не бывает
вроди исправил как сказали выше и нормально работает
Цитата:
Во-первых:
Выкинь и забудь глобальную переменную IndexN
ета переменая в оригинале програмы считываеца с ини фаила, думаю она всетаки нужна
Цитата:
Пользуйся TList
полизовался, вернее TObjectList, но проблем было не меньше
хотя мне самому работать с TList больше нравица
VirusN13
ArtGrek вне форума Ответить с цитированием
Старый 02.03.2011, 14:27   #9
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Цитата:
ета переменая в оригинале програмы считываеца с ини фаила, думаю она всетаки нужна
Я не зря сказал, что выкинуть IndexN нужно именно "Во-первых". Хранение этой лишней информации и привло вас к ошибке. Логика программы должна быть самодостаточной.
Строго говоря, дублирование данных вешь полезная. Тот же КЭШ. Или когда TWinConrtol хранит текущее состояние в каком-нибудь поле FValue, чтоб каждый раз не запрашитать его ч/з хэндел. Но уж ни как не в глобальной переменной. Да и что дает вам IndexN, если удален не 1 на несколько элементов.

Цитата:
но проблем было не меньше
Так разберитесь. TList - хороший пример работы со списками для начинающих.

Цитата:
ета переменая в оригинале програмы считываеца с ини фаила, думаю она всетаки нужна
Опять же: ни в коем случает она не нужна. А то доживете еще до такого (видел как-то что-то подобное на форуме, хотя ваш вариант ни чем не лучше):
Код:
  IniF := TIniFile.Create (FileName);
  for i := 1 to 10 do begin
    Section := 'Section' + IntToStr (i);
    Index := IniF.ReadInteger (Section, 'Index', 0);
    Data := IniF.ReadString (Section, 'Data', '');
А в самом ini-файле
Цитата:
[Section1]
Index = 1
Data = 'sgfk sdfsk'
[Section2]
Index = 2
Data = 'sgfk sdfsk'
[Section3]
Index = 3
Data = 'sgfk sdfsk'
[Section4]
Index = 4
Data = 'sgfk sdfsk'
Чтоб, как говорится, наверняка.
Sibedir вне форума Ответить с цитированием
Старый 02.03.2011, 14:39   #10
ArtGrek
DelphiProger
Участник клуба
 
Аватар для ArtGrek
 
Регистрация: 14.11.2010
Сообщений: 1,023
По умолчанию

Цитата:
Index := IniF.ReadInteger (Section, 'Index', 0);
за ето отдельное спасибо, чено говоря не знал

думаю правельнее будет загрузить проект, что б знали с чем я работаю,
что бы вы заменили, учитывая что я знаю меньше вас
Вложения
Тип файла: zip ArtGrek.zip (3.8 Кб, 15 просмотров)
VirusN13
ArtGrek вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Динамическое удаление TCheckBox Maks57 Помощь студентам 9 24.11.2009 00:24
Динамическое создание массива Juggernaut Общие вопросы Delphi 3 20.05.2009 15:13
Динамическое создание событий Fandaret Общие вопросы Delphi 4 14.05.2009 04:20
Динамическое создание формы. Son Общие вопросы Delphi 1 04.02.2009 15:33
Динамическое создание фрейма s-force Общие вопросы Delphi 9 05.09.2007 16:56