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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 30.03.2011, 12:18   #1
Dmitry333
Пользователь
 
Аватар для Dmitry333
 
Регистрация: 13.11.2009
Сообщений: 60
По умолчанию Ошибка доступа к памяти

Приветствую всех любителей и мастеров программирования, есть вопрос.

Так сложилось, что для решения моей задачи понадобилось написать компонент TColumner. Он представляет собой 2 колонки, элементы которого, TRecord, представлены объектом, тоже "самописаным", состоящим из Tlabel и TShape.

У TColumner есть метод добавить элемент и удалить. Все элементы предствлены динамическим массивом.

У TRecord есть событие OnLabelClick. И вот в чём собственно вопрос, как по нажатию на этот Label удалять его из списка TColumner.

Представляю описание объектов:
Код:
// Элемент столбца.
  TRecord = class(TObject)
      Owner:TComponent;
      labeltext:TLabel;
      shape:TShape;
      labWidth : Integer; // Длина LABEL
      x,y:Integer;
      Color:TColor; // Цвет shape
      Heigth,Width:Integer;
      Text:String;
      id:Integer;
      nomb:Integer; // Уникальный номер.
      Position : Boolean; // Позиция
      constructor Create(Owner:TComponent);
      procedure SetData(Text: String; Id:Integer; Position:boolean); // Установка текста.
      procedure Show(XPos, YPos : Integer; Color:TColor); // Показ.
      procedure labeltextClick(Sender:TObject);
      procedure destr(); // Free LABEL и Shape
  end;

  // Столбцы.
  TColumner = class(TObject)
    autoinc:integer;  // Уникальный номер каждому новому элементу.
    left,top:Integer;
    Owner:TComponent;
    verStep,horStep:Integer;    // Отступы.
    leftCount,rightCount:Integer;  // Количество элементов столбцов.
    lc,rc:array of TRecord;
    oparation:Byte; // Тип операциии 0 - ничего, 1 - удаление, 2 - изменение.
    constructor Create(Owner:TComponent);
    destructor Destroy;
    procedure AddColumn(Position:Boolean; Text:string; id:integer);
    procedure DelColumn(nomb:integer);  // Удаление из списка.
    procedure Show;
  end;



// Метод DelColumn(nomb:integer);

procedure TColumner.DelColumn(nomb: integer);
var
  i,j:Integer;
begin

  for i:=0 to Length(lc)-1 do
  begin
    if lc[i].nomb=nomb then
    begin
      lc[i].destr;
      for j:=i to Length(lc)-1 do
      begin
        lc[j]:=lc[j+1];
      end;

      SetLength(lc,Length(lc)-1);
      //Self.oparation:=0;
      a.Show;
      Exit;
    end;
  end;

  for i:=0 to Length(rc)-1 do
  begin
    if rc[i].nomb=nomb then
    begin
      rc[i].destr;

      for j:=i to Length(rc)-1 do
      begin
        rc[j]:=rc[j+1];
      end;

      SetLength(rc,Length(rc)-1);

      Self.oparation:=0;
      a.Show;
      Exit;
    end;
  end;

end;
Назначаю на клик метод удаления и получаю ошибку доступа к памяти (((
Так что посоветуете сделать?

Прикрепил текстовый док. с реализацией методов.
Вложения
Тип файла: rar source.rar (1.2 Кб, 8 просмотров)
Dmitry333 вне форума Ответить с цитированием
Старый 30.03.2011, 12:47   #2
eduard93
Форумчанин
 
Регистрация: 06.12.2010
Сообщений: 300
По умолчанию

Код:
procedure TRecord.destr;
begin
  Self.labeltext.Free;
  Self.shape.Free;
  Self.Free; //Что это такое?
end;
Научитесь делать нормальные деструкторы. Пример: http://delphikingdom.com/asp/viewite...catalogid=1186
eduard93 вне форума Ответить с цитированием
Старый 30.03.2011, 13:25   #3
Dmitry333
Пользователь
 
Аватар для Dmitry333
 
Регистрация: 13.11.2009
Сообщений: 60
По умолчанию

Цитата:
Сообщение от eduard93 Посмотреть сообщение
Код:
procedure TRecord.destr;
begin
  Self.labeltext.Free;
  Self.shape.Free;
  Self.Free; //Что это такое?
end;
Научитесь делать нормальные деструкторы. Пример: http://delphikingdom.com/asp/viewite...catalogid=1186

self.free - это высвобождение памяти ооданной по объект TRecord.

)) я умею делать деструкторы, это просто уже от безысходности и от того что мого чего перепробовал.
Dmitry333 вне форума Ответить с цитированием
Старый 30.03.2011, 13:28   #4
Dmitry333
Пользователь
 
Аватар для Dmitry333
 
Регистрация: 13.11.2009
Сообщений: 60
По умолчанию

Метод удаления работает, если его вызывать в другом месте, то есть не в обработчике OnClick LABEL. А вызывая его здесь, удаляется сам LABEL и возврат идёт в обработчик уже удалённого LABELA.

Что посоветуете?
Dmitry333 вне форума Ответить с цитированием
Старый 30.03.2011, 13:32   #5
eduard93
Форумчанин
 
Регистрация: 06.12.2010
Сообщений: 300
По умолчанию

Цитата:
я умею делать деструкторы
По вашему коду этого не видно. Сделайте как учат книжки. А если и после этого у вас будут ошибки, кидайте исправленный код сюда.
eduard93 вне форума Ответить с цитированием
Старый 30.03.2011, 13:41   #6
Dmitry333
Пользователь
 
Аватар для Dmitry333
 
Регистрация: 13.11.2009
Сообщений: 60
По умолчанию

Цитата:
Сообщение от eduard93 Посмотреть сообщение
По вашему коду этого не видно. Сделайте как учат книжки. А если и после этого у вас будут ошибки, кидайте исправленный код сюда.
Создал деструктор:

Код:
destructor TRecord.Destroy;
begin
  labeltext.Free;
  shape.Free;
end;
Но суть то не в этом, вопрос остался открытым.
Dmitry333 вне форума Ответить с цитированием
Старый 30.03.2011, 14:00   #7
eduard93
Форумчанин
 
Регистрация: 06.12.2010
Сообщений: 300
По умолчанию

Вы теперь его вызываете из DelColumn? И баг остался?
eduard93 вне форума Ответить с цитированием
Старый 30.03.2011, 14:03   #8
Dmitry333
Пользователь
 
Аватар для Dmitry333
 
Регистрация: 13.11.2009
Сообщений: 60
По умолчанию

Цитата:
Сообщение от eduard93 Посмотреть сообщение
Вы теперь его вызываете из DelColumn? И баг остался?

Так точно!
Dmitry333 вне форума Ответить с цитированием
Старый 30.03.2011, 14:51   #9
eduard93
Форумчанин
 
Регистрация: 06.12.2010
Сообщений: 300
По умолчанию

Эх, нелегкое это дело - компиляция чужого кода. Но зато заметил наконец ошибку. Вы из обработчика нажатия labeltext ее саму удаляете. Решить проблемму можно посылая сообщения форме (через PostMessage) с просьбой удалить нужные записи. Будет приблизительно так: http://www.delphikingdom.ru/asp/answ...IDAnswer=17337
eduard93 вне форума Ответить с цитированием
Старый 30.03.2011, 15:05   #10
Dmitry333
Пользователь
 
Аватар для Dmitry333
 
Регистрация: 13.11.2009
Сообщений: 60
По умолчанию

Цитата:
Сообщение от eduard93 Посмотреть сообщение
Эх, нелегкое это дело - компиляция чужого кода. Но зато заметил наконец ошибку. Вы из обработчика нажатия labeltext ее саму удаляете. Решить проблемму можно посылая сообщения форме (через PostMessage) с просьбой удалить нужные записи. Будет приблизительно так: http://www.delphikingdom.ru/asp/answ...IDAnswer=17337

Благодарю за внимание!

Та написано использовать таймер... Это как-то "некрасиво" ((
Dmitry333 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ошибка доступа при выделении памяти в чужом процессе Neoteric Общие вопросы Delphi 21 06.12.2010 16:50
Ошибка доступа памяти, при работе с принятой строкой. Zeraim Работа с сетью в Delphi 11 26.01.2010 01:11
Ошибка доступа к памяти AzoTik Общие вопросы Delphi 6 22.01.2010 10:17
Ошибка: Нарушение доступа к памяти. VladimirAleks Общие вопросы Delphi 6 03.11.2009 14:42
Ошибка создания доступа к папке Oleg-vp Работа с сетью в Delphi 4 14.01.2008 14:35