Работа с фрэймами

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
SeZuka
постоялец
Сообщения: 209
Зарегистрирован: 05.09.2012 14:58:05

Работа с фрэймами

Сообщение SeZuka »

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

Код: Выделить всё

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Buttons;

type

  { TFrame1 }

  TFrame1 = class(TFrame)
    BitBtn1: TBitBtn;
    procedure BitBtn1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

implementation

{$R *.lfm}

{ TFrame1 }

procedure TFrame1.BitBtn1Click(Sender: TObject);
begin
  Free;
end;

end.

Вызов его:

Код: Выделить всё

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  with TFrame1.Create(Self) do begin
    Parent := Self;
    Show;
    //Free;
  end;
end;

Извне все нормально уничтожается:

Код: Выделить всё

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  with TFrame1.Create(Self) do begin
    Parent := Self;
    Show;
    Free;
  end;
end;

Что я делаю не так или как это обойти?
Аватара пользователя
vada
энтузиаст
Сообщения: 691
Зарегистрирован: 14.02.2006 12:43:17

Сообщение vada »

Это похоже на то что вы хотели застрелиться, но неудачно. Не насмерть стрельнулись, а просто нормально так себя поранили и сознание потеряли. Поэтому добить себя ну никак не можете.
А вот если прохожего попросите вас застрелить, то он сможет вас добить, если сразу не получилось.
SeZuka
постоялец
Сообщения: 209
Зарегистрирован: 05.09.2012 14:58:05

Сообщение SeZuka »

:D Смешно, но действительно так, уже и об стену бился и яд пил, а никак не получается себя прибить насмерть :D
А если по существу, почему не получается прибить самого себя?
Аватара пользователя
qivi
энтузиаст
Сообщения: 703
Зарегистрирован: 19.01.2009 12:45:54
Откуда: Россия

Сообщение qivi »

viewtopic.php?f=5&t=6204
Четвёртый пост сверзу
Аватара пользователя
amateur
энтузиаст
Сообщения: 552
Зарегистрирован: 03.08.2007 10:15:32

Сообщение amateur »

мда... а вики уже не рулит?

http://wiki.freepascal.org/Frames

Хоть и на инглиш но понять можно (особено в конце интересное написано).
SeZuka
постоялец
Сообщения: 209
Зарегистрирован: 05.09.2012 14:58:05

Сообщение SeZuka »

qivi Спасибо!
Натыкаюсь на очередные грабли, на дельфях вроде как все проще было, хотя там я пользовался MDI-формами, а не фрэймами.

amateur И что там интересного написано? Конструктор и деструктор, а про то как убить самого себя ни слова.
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

SeZuka писал(а):про то как убить самого себя ни слова.


А стандартный деструктор Destroy уже отменили? Или религия не позволяет?

destructor TFrame1.Destroy;
begin
// уничтожение созданных формой объектов...
inherited Destroy;
end;
Последний раз редактировалось Лекс Айрин 27.02.2013 17:42:26, всего редактировалось 1 раз.
Аватара пользователя
amateur
энтузиаст
Сообщения: 552
Зарегистрирован: 03.08.2007 10:15:32

Сообщение amateur »

:)
там и есть та самая "вкусняшка" для убиения фрейма...

фрейм убить можно (только он про это не знает ему надо указать как).

пользовался MDI-формами
посмотрите в сторону TDI или компонент в RxFPC.
SeZuka
постоялец
Сообщения: 209
Зарегистрирован: 05.09.2012 14:58:05

Сообщение SeZuka »

Лекс Айрин писал(а):А стандартный деструктор Destroy уже отменили? Или религия не позволяет?

destructor TFrame1.Destroy;
begin
// уничтожение созданных формой объектов...
inherited Destroy;
end;

Если вместо Free вызвать Destroy, то та же самая ошибка, хотя Free тот же самый Destroy и вызывает.
И я никакие объекты вручную не создавал, чтоб их уничтожать вручную. Или по вашей логике все что положили на форму во время проектирования, при закрытии формы надо вручную убивать?

P.S. Кстати дело здесь не во фрейме, а в вызове деструктора объекта из события самого объекта. Создайте новый проект, положите на форму кнопку и в обработчике нажатия вызовите деструктор формы, получите туже ошибку:

Код: Выделить всё

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  Free; // Либо Destroy;
end;
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

SeZuka, попробуйте воспользоваться методом Close. Но, кстати, не вижу чтобы деструктор был описан. Похоже, что вы вызываете того чего просто нет.
iskander
энтузиаст
Сообщения: 627
Зарегистрирован: 08.01.2012 18:43:34

Сообщение iskander »

SeZuka писал(а):чтобы фрэйм уничтожился при нажатии кнопки на нем, то есть из самого себя

Код: Выделить всё

procedure TFrame1.BitBtn1Click(Sender: TObject);
begin
  Parent.RemoveControl(Self);
end;
SeZuka
постоялец
Сообщения: 209
Зарегистрирован: 05.09.2012 14:58:05

Сообщение SeZuka »

Лекс Айрин писал(а):SeZuka, попробуйте воспользоваться методом Close. Но, кстати, не вижу чтобы деструктор был описан. Похоже, что вы вызываете того чего просто нет.

Деструктор есть у любого объекта порожденного от TObject, и если я не переписываю деструктор своего объекта, то вызывается деструктор предка. А вот если я насоздаю в объекте кучу всего, о чем не знает предок, тогда действительно надо переопределять деструктор, чтоб почистить эту кучу перед собственным удалением. А вот у фрейма нет метода Close :D

iskander писал(а):

Код: Выделить всё

procedure TFrame1.BitBtn1Click(Sender: TObject);
begin
  Parent.RemoveControl(Self);
end;

Так он удалится с формы (ну или кто там его Parent'ом является), а в памяти так и останется висеть.
iskander
энтузиаст
Сообщения: 627
Зарегистрирован: 08.01.2012 18:43:34

Сообщение iskander »

SeZuka писал(а):а в памяти так и останется висеть.

Есть такое дело. :roll:
Ну тогда как по ссылке qivi.
Можно ещё сообщение послать, но это геморнее:

Код: Выделить всё

uses
  Classes, SysUtils, FileUtil, Forms, Controls, StdCtrls,
  LclType, LMessages, LclIntf;


const
    WM_FREE = WM_USER+ 100;

type

  { TFrame1 }

  TFrame1 = class(TFrame)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
    procedure WMFree(var aMsg: TLMessage); message WM_FREE;
  public
    { public declarations }
  end;

implementation

{$R *.lfm}

{ TFrame1 }

procedure TFrame1.Button1Click(Sender: TObject);
begin
  PostMessage(Handle,WM_FREE,wParam(Self),0);
end;

procedure TFrame1.WMFree(var aMsg: TLMessage);
begin
  if aMsg.wParam = wParam(Self) then
    Free;
end;
Ответить