Форум: "Основная";
Текущий архив: 2002.07.08;
Скачать: [xml.tar.bz2];
ВнизФорма + интерфейс Найти похожие ветки
← →
kull (2002-06-26 10:45) [0]Вот такой интересный вопросик: Как форму наследовать от интерфейса?
Так?
IMyForm = interface
...
end;
TForm1 = class(TForm, IMyForm)
...
end;
var
itf : IMyForm;
begin
itf := TForm1.Create(Application);
itf := nil;
end;
Что то здесь не так, когда делаю itf := nil - форма остается.
← →
Polevi (2002-06-26 10:57) [1]а что с ней должно произойти по твоему
обнулил ты указатель и что ?
← →
kull (2002-06-26 11:10) [2]Так, если бы я сделал так:
type
IMyObject = interface
...
end;
TMyObject = class(TInterfacedObject,IMyObject)
end;
var
itf : IMyObject;
begin
itf := TMyObject.Create;
itf := nil;
end;
экземпляр класса TMyObject бы уничтожился.
Я понимаю что форма это не TInterfacedObject, но как можно это реализовать?
← →
Skier (2002-06-26 11:52) [3]> kull
"Что то здесь не так, когда делаю itf := nil - форма остается"
А с чего ты взял что она остаётся ???
← →
kull (2002-06-26 12:14) [4]
> А с чего ты взял что она остаётся ???
Ну я же вижу ее на экране!
← →
Игорь Шевченко (2002-06-26 12:20) [5]kull © (26.06.02 12:14)
А кнопки меню Debug и View CPU из клавиатуры выломаны, что ими нельзя воспользоваться ? :-))
http://www.tuxedo.org/~esr/faqs/smart-questions.html
← →
Skier (2002-06-26 12:25) [6]> kull
Из твоего кода следует, что ты её вообще не показываешь
itf := TForm1.Create(Application);
itf := nil;
Тогда давай уж код целиком.
← →
kull (2002-06-26 12:32) [7]
> Из твоего кода следует, что ты её вообще не показываешь
ничего не следует.
Я в Object inspector-e ставлю Visible у формы в True.
А вот весь код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
IMyForm = interface
end;
TForm1 = class(TForm,IMyForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var
itf: IMyForm;
begin
itf := TForm1.Create(Application);
itf := nil;
end;
> Игорь Шевченко © (26.06.02 12:20)
Мне кажется Debuger здесь ни причем.
Вопрос в консепте...
← →
Бурундук (2002-06-26 12:33) [8]2kull
зануление ссылки приводит к уничтожению объекта, если такое поведение определено в _Release. Для TInterfacedObject это так.
А для формы - нет.
function TComponent._Release: Integer;
begin
if FVCLComObject = nil then
Result := -1 // -1 indicates no reference counting is taking place
else
Result := IVCLComObject(FVCLComObject)._Release;
end;
← →
Fiend (2002-06-26 12:35) [9]люди гляньте внимательнее!!!
он же просто обнуляет указатель а не вызывает деструктор объекта!
В твоём случае ничего не уничтожается!!!
А объект как бы уничтожился, потому что ты потерял указатель на него, поэтому больше обратиться к нему не можешь,но есть в памяти твоего процесса.
Потому то и форма видна, что она не уничтожена, а просто на нее потерян указатель
← →
Skier (2002-06-26 12:35) [10]> kull
Мда. Учится и ещё раз учиться...
← →
Бурундук (2002-06-26 12:41) [11]Fiend ©
Врачу, исцелися сам (в смысле гляди внимательней)
У него всё-так не указатель, а интерфейсная ссылка, и обычно её зануления достаточно для уничтожения объекта.
← →
Игорь Шевченко (2002-06-26 12:44) [12]Fiend © (26.06.02 12:35)
C интерфейсами все не так
← →
kull (2002-06-26 12:49) [13]2Бурундук
А как можно сделать такую штуку, то есть правильно переписать _Release?
И шо це таке - IVCLComObject?
← →
Skier (2002-06-26 13:00) [14]> kull
Лови :
Только поправь GUID
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
IMyForm = interface
["{A24918B1-88D7-11D6-B3DB-000102AD844C}"]
procedure Show;
end;
TForm1 = class(TForm,IMyForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
protected
FRefCount: Integer;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
public
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var
itf: IMyForm;
begin
itf := TForm1.Create(Application);
itf.Show;
itf := nil;
end;
function TForm1._AddRef: Integer;
begin
Result := InterlockedIncrement(FRefCount);
end;
function TForm1._Release: Integer;
begin
Result := InterlockedDecrement(FRefCount);
if Result = 0 then Destroy;
end;
end.
← →
kull (2002-06-26 13:06) [15]
> Skier © (26.06.02 13:00)
Спасибо это я уже попробовал.
Но если itf сделать членом класса TForm1 и убрать
itf := nil , после закрытия приложения Access Violation.
Здесь мне кажется есть тонкости, ведь форму можно и ручками закрыть, а ссылочка на интерфейс то останется.
← →
Skier (2002-06-26 13:10) [16]> kull
Давай-ка конкретней расскажи чего ты хотишь сделать ?
А то трудно советовать.
Или приведи код где происходит AV и чего ты хочешь
от этого кода добиться.
← →
Бурундук (2002-06-26 13:13) [17]2 kull ©
Дело в том, что при закрытии приложения itf выходит из зоны видимости и освобождается. А форма к тому времени уже уничтожена, и вызывается _Release уничтоженной формы. Отсюда AV.
Поэтому не рекомендуется смешивать обычные ссылки на объекты и интерфейсные ссыли. А избавиться от обычной ссылки на форму вряд ли удастся, по крайней мере в Screen она пропишется.
← →
kull (2002-06-26 13:17) [18]AV я так думаю происходит из-за того, что при закрытии главной формы все остальные уже закрыты.
А при уничтожении ссылки на интерфейс происходит попытка еще раз закрыть форму отсюда и AV.
На конкретную строчку AV не показывает.
← →
Skier (2002-06-26 13:25) [19]> kull
А как ты форму закрываешь ?
caFree что ли ставишь в обработчике OnClose ??
← →
kull (2002-06-26 13:37) [20]Нет ничего не ставлю:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
IMyForm = interface
end;
TForm1 = class(TForm,IMyForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
FRefCount: Integer;
itf: IMyForm;
protected
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
itf := TForm1.Create(Application);
end;
function TForm1._AddRef: Integer;
begin
Result := InterlockedIncrement(FRefCount);
end;
function TForm1._Release: Integer;
begin
Result := InterlockedDecrement(FRefCount);
if Result = 0 then Destroy;
end;
end.
← →
vuk (2002-06-27 01:11) [21]Когда Вы работаете с объектами, реализующими интерфейсы и в то же время являющимися компонентами VCL, Вы должны определиться с тем, кто и как будет управлять временем жизни объекта.
В VCL, как известно временем жизни объекта управляет его владелец, а в интерфейсной модели - сам объект посредством счетчика ссылок (если этот подсчет реализован). Если попытаться смешать эти два подхода, то как раз и возникают различные конфликты. Поэтому, как уже зметили выше эти модели лучше не смешивать.
Тем не менее необходимость такая зачастую возникает и делать это можно, но нужно это делать осторожно(есть ряд тонкостей). В таком случае лучше будет полагаться не на интерфейсные ссылки, а на стандартную работу с объектами в VCL. Собственно говоря по-умолчанию все так и происходит. Поэтому и не реализован подсчет ссылок в TComponent и его наследниках.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.07.08;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.007 c