Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Компоненты и классы
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 12.04.2017, 19:28
MProg MProg вне форума
Прохожий
 
Регистрация: 12.04.2017
Сообщения: 8
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Принудительное удаление объекта изнутри

Собственно есть код:

Код:
unit Unit1;

interface

uses SysUtils, Forms, Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FB:TButton;
    procedure FBClick(Sender: TObject);
    { Private declarations }
  public
    { Public declarations }
  end;

  TMButton = class(TButton)
   procedure Click; override;
  end;

var
  Form1: TForm1;
  MB:TMButton;
implementation

{$R *.dfm}

procedure CreateTMButton();
begin
  MB:=TMButton.Create(Form1);
  MB.Width:=Form1.ClientWidth;
  MB.Height:=Form1.ClientHeight-20;
  MB.Caption:='Class';
  MB.Parent:=Form1;
end;

procedure TMButton.Click;
begin
  inherited;
  //showmessage(inttostr(Integer(MB)));
  FreeAndNil(MB);
  //CreateTMButton();
  //showmessage(inttostr(Integer(MB)));
  //Showmessage('MButtonClick');

end;

procedure TForm1.FBClick(Sender: TObject);
begin
 FreeAndNil(MB);
 //CreateTMButton();
 //Showmessage('FBClick');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 CreateTMButton();
 FB:=TButton.Create(Form1);
 FB.Top:=Form1.ClientHeight-20;
 FB.Height:=20;
 FB.Width:=Form1.ClientWidth;
 FB.Caption:='Form';
 FB.OnClick:=FBClick;
 FB.Parent:=Form1;
end;

end.

В коде создается две кнопки: FB (для внешнего удаления), MB (для внутреннего удаления)

При клике на FB все работает удовлетворительно.

А при клике на MB происходит AV ошибка при выходе из процедуры из-за попытки передачи управления на уже несуществующие адреса.

Вопрос в том как адекватно спилить под собой ветку и не налюбнутся с дерева?
Тость, как можно адекватно(приближенно к правильному) удалять объект MB из той же TForm1.FBClick? Есть ли какие-то стандартные или нестандартные махинации со стеком или прыжками в иное место кода чтоб все адекватно удалялось и работало?

Буду признателен даже за извращенные варианты (хоть эта задачка в принципе извращенная вроде как)... Так сказать если не для дела, то для общего развития и более глубоко понимания сгодятся
Ответить с цитированием
  #2  
Старый 12.04.2017, 20:13
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Уберите везде строчку с freeandnil и вставьте её первой в createtmbutton ввиде if MB <> nil then FreeAndNil(MB);
Ответить с цитированием
  #3  
Старый 12.04.2017, 20:49
MProg MProg вне форума
Прохожий
 
Регистрация: 12.04.2017
Сообщения: 8
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
Уберите везде строчку с freeandnil и вставьте её первой в createtmbutton ввиде if MB <> nil then FreeAndNil(MB);

Это ничего не изменит и будет примерно также если бы просто расскоментировать строчку CreateTMButton();

Работает (без AV) только из-за того что объект наново создается и в том же адресном пространстве... Но это чисто мое предположение. Я еще не вникал по случайности оно так получается или по какому-то задуманому механизму.

Суть в том что надо вызывать FreeAndNil(MB) или его аналог в любом месте кода. Как во внутрях самого объекта MB так и за их предалами... И не важно будет ли объект пересоздан или нет

Все это не извращенными людьми делается внешними вызовами (в отношении к MB) по типу TForm1.FBClick и разными вариациями на тему...

PS: На коментарии в коде можно не смотреть.
Ответить с цитированием
  #4  
Старый 12.04.2017, 21:00
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Тогда проще из-самого-себя не удалять, а управлять видимостью
Ответить с цитированием
  #5  
Старый 12.04.2017, 21:12
MProg MProg вне форума
Прохожий
 
Регистрация: 12.04.2017
Сообщения: 8
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
Тогда проще из-самого-себя не удалять, а управлять видимостью

Что проще, знаю)
Интересно как такое можно из самого себя провернуть)
Ответить с цитированием
  #6  
Старый 12.04.2017, 22:21
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Получилось "харакири" через PostMessage
Код:
...
 protected
    procedure WndProc(var Msg: TMessage); override;
...

procedure TForm1.WndProc(var Msg: TMessage);
begin
  case Msg.Msg of
    CM_RELEASE: FreeAndNil(MB);
    else inherited;
  end;
end;

...
procedure TMButton.Click;
begin
  inherited;
  PostMessage(Form1.Handle, CM_RELEASE,0,0);
end;
Ответить с цитированием
  #7  
Старый 12.04.2017, 21:10
MProg MProg вне форума
Прохожий
 
Регистрация: 12.04.2017
Сообщения: 8
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Можно еще добавить вот так чтоб была более наглядно проилюстрированна суть извращения:

Код:
procedure TMButton.MyFree;
begin
  FreeAndNil(MB);
  MB.I:=0;
end;

procedure TMButton.Click;
begin
  inherited;
  MyFree();
end;


Тойсть ошибка происходить из-за того что идет обращение к объекту или его частям после того как он был удален...

Вопрос в том как излюбнуть систему чтоб управление после FreeAndNil(MB); переходило в какую-то часть программы и дальше все работало в штатном режиме как будто объекта MB и не бывало?

Для людей не насилующих свой мозг:
Удаление MB.I:=0; не решит проблему.. Так как "end" грубо говоря превращается в ассемблерный "ret" который вытаскивает адрес (удаленного объекта) из стека процесора и пытается с ним взаимодействовать


Решение которое мне приходит на ум то это какие-то махинации со стеком или "jmp" в какой-то участок кода, или вообще все вместе...
Но это пока еще вопрос как и не нарушу ли я этим какую-то священную логику самого самого Delphi
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 00:55.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter