[DUG] How do you free an Object Instance when you have anInterfaceReference?

Stacey Verner stacey at cjntech.co.nz
Thu Sep 29 16:00:15 NZST 2005


I did think about using the helper object, but I didn't really like the
fact that you have an extra objects running around that won't be there
in the end, and have to be managed while you are building the menu.

Using the interface allows you to have code such as:

procedure SetupDoStuffMenu;
var
  LRootItem: IcjnMenuItem;
begin
  // Add the initial root item.
  // miActions can be TCustomMenuItem or TTBCustomItem (and
descendants).
  LRootItem := TcjnMenuTools.InsertSubMenuItem(miActions, 0, 'Do
Stuff');
  LRootItem.AddMenuItem('Do A', OnDoA);
  LRootItem.AddMenuItem('Do B', OnDoB);
  LRootItem.AddDividerItem;
  LRootItem.AddMenuItem('Do C', OnDoA);
  LRootItem.AddMenuItem('Do D', OnDoD);
end;

The menu items are now owned by the menu and will be free'd by it.

I also wanted to learn a bit more about interfaces, as I am starting to
understand their power.

Another question.

All of the classes I am using here have a caption property, but they
don't gave GetCaption and SetCaption is private. FCaption is also
private.

Is there any way of settings up an interface with a Caption property
that will be implemented by the Caption property of the actuallt class?

Stacey

> -----Original Message-----
> From: delphi-bounces at ns3.123.co.nz 
> [mailto:delphi-bounces at ns3.123.co.nz] On Behalf Of Struan Judd
> Sent: Thursday, 29 September 2005 15:39
> To: 'NZ Borland Developers Group - Delphi List'
> Subject: RE: [DUG] How do you free an Object Instance when 
> you have anInterfaceReference?
> 
> Stacey Verner wrote:
> > If you have an object the implements and interface, and you have a 
> > reference to the interface, how do you free the object using the 
> > reference to the interface?
> > 
> > I have the following (simplified) interface and classes.
> > 
> > interface
> > 
> > type
> > 
> >   IMyMenuItem = interface
> >     function AddMenuItem(PCaption: String; POnClick: TNotifyEvent):
> >     IMyMenuItem; procedure MyFree;
> >   end;
> > 
> >   TMyMenuItem = class(TMenuItem, IMyMenuItem)
> >   public
> >     function AddMenuItem(PCaption: String; POnClick: TNotifyEvent):
> >     IMyMenuItem; procedure MyFree;
> >   end;
> > 
> >   TMyTBMenuItem = class(TTBItem, IMyMenuItem)
> >   public
> >     function AddMenuItem(PCaption: String; POnClick: TNotifyEvent):
> >     IMyMenuItem; procedure MyFree;
> >   end;
> > 
> > implementation;
> > 
> > function TMyMenuItem.AddMenuItem(PCaption: String; POnClick:
> >   TNotifyEvent): IMyMenuItem; var LMenuItem: TMyMenuItem; begin
> >   LMenuItem := TMyMenuItem.Create(PParent.Owner);
> >   LMenuItem.Caption := PCaption;
> >   LMenuItem.OnClick := POnClick;
> >   Result := LMenuItem;
> > end;
> > 
> > procedure TMyMenuItem.MyFree;
> > begin
> >   Free;
> > end;
> > 
> > function TMyTBMenuItem.AddMenuItem(PCaption: String; POnClick:
> >   TNotifyEvent): IMyMenuItem; var LMenuItem: TMyTBMenuItem; begin
> >   LMenuItem := TMyTBMenuItem.Create(PParent.Owner);
> >   LMenuItem.Caption := PCaption;
> >   LMenuItem.OnClick := POnClick;
> >   Result := LMenuItem;
> > end;
> > 
> > procedure TMyTBMenuItem.MyFree;
> > begin
> >   Free;
> > end;
> > 
> > The intention of this is to allow you to dynamically create menu 
> > items, but it doesn't matter if you have a normal menu 
> (TMenuItem) or 
> > a Toolbar 2000 menu (TTBItem). You just deal with 
> IMyMenuItem and the
> > correct objects are created behind the scenes.   
> > 
> > This works pretty well except I have an intermittent access 
> violations 
> > when freeing.
> > 
> > MyMenuItem: IMyMenuItem;
> > 
> > ... // Do some stuff.
> > 
> > MyMenuItem := RootMenuItem.AddMenuItem('Hello World', 
> > HelloWorldClick);
> > 
> > ... // Later on
> > 
> > MMyMenuItem.MyFree; // Intermiitent access violation here!
> > 
> > I don't actually like the fact that I have MyFree. It was 
> the only way 
> > I could think of doing it at the time.
> > 
> > Stacey
> > 
> > Stacey Verner             Ph:   +64-9-4154790
> > Software Developer        Fax:  +64-9-4154791
> >                           DDI:  +64-9-4154797
> > CJN Technologies Ltd.     Email: stacey at cjntech.co.nz
> > <mailto:stacey at cjntech.co.nz>
> > PO Box 302-278, North Harbour, Auckland 1330, New Zealand
> > 12 Piermark Drive, North Harbour, Auckland, New Zealand Visit our 
> > website at http://www.cjntech.co.nz/ <http://www.cjntech.co.nz/>
> 
> 
> I'd implement this as a "helper" object that delegates the properties,
> methods and events to the actual obect:
> 
> Ie.
> 
> Type
>   TMyMenuItem = class(TObject)
>   public
>     procedure AddMenuItem(PCaption: String; POnClick: TNotifyEvent):
> TMyMenuItem; virtual; abstract;
>   end;
> 
>   TMyMenuItemStandard = class(TMyMenuItem)
>   private
>     FMenuItem: TMenuItem;
>   public
>     procedure AddMenuItem(PCaption: String; POnClick: TNotifyEvent):
> TMyMenuItem; override;
>     destructor Destroy;
>   end;
> 
> .
> .
> .
> 
> And of course Destroy would Free the included Menu item (of 
> whatever type)
> 
> Thus you're not having to mix the Interface variables desire 
> to be reference
> counted and the standard Delphi wilful destruction schemes.
> 
> TTFN
> 
> Struan Judd                                
> Mailto:struan.judd at ecargo.co.nz Developer                     
>          
> Phone:   +64 (9) 368 9368 eCargo                                     
> Fax:     +64 (9) 368 9369 Visibility - Communication - Measurement   
> Mobile:  +64 (21) 685 335 Private & Confidential                     
> http://www.ecargo.co.nz 
> 
> 
> _______________________________________________
> Delphi mailing list
> Delphi at ns3.123.co.nz
> http://ns3.123.co.nz/mailman/listinfo/delphi
> 



More information about the Delphi mailing list