Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.005 c
6-23693
Filat
2002-04-10 17:20
2002.07.08
Обмен файлами между организацией и её клиентами через Интернет?


14-23728
PTE
2002-06-05 20:26
2002.07.08
дайте плиз русский хелп к RxDrawGrid?


1-23583
Боева Наталья
2002-06-24 04:27
2002.07.08
отчет в word


3-23498
id_privin
2002-06-17 10:11
2002.07.08
Как понять тип поля?


1-23659
Tutov Roman
2002-06-26 10:42
2002.07.08
Разыскивается URL





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский