Adding TMenuItem at run time...

Dear Friends,

First of all, happy new year and and lot of success for 2000 to all of you...

I'm writing a component (like a TreeView) and I need to assign a popup menu to it.
At run time, everything is working fine as expected but when I close the application, I
get the following error:

  raised exception class EExternalException...

If I remove the two lines (see code sample below)

  PopupMenu.Items.Add(MnAddGroup);
  PopupMenu.Items.Add(MnAddProject);

I didn't receive this error anymore but, of course, the popup menu is not more dispayed.

What's wrong ?
Thank you in advance for your help
Bob

{------------------------------------------------------------------------------}
type

  TRBRepositoryTree = class
  private
    { Private declarations }
    MyPopup     : TPopupMenu;
    MnAddGroup  : TMenuItem;
    MnAddProject: TMenuItem;

    ...

  public
    { Public declarations }
    Constructor   Create(AOwner: TComponent); override;
    Destructor    Destroy; override;

    ...

  end;
{------------------------------------------------------------------------------}
Constructor TRBRepositoryTree.Create(AOwner: TComponent);
var
  MyBitmap: TBitmap;
begin
  Inherited Create(AOwner);

  {Popup Menu related actions}
  MyPopup               := TPopUpMenu.Create(self);
  PopupMenu.AutoPopup   := true;
 
  MnAddGroup            := TMenuItem.Create(self);
  MnAddGroup.Caption    := 'Add Group...';
  MnAddGroup.OnClick    := NewGroupClick;

  MnAddProject          := TMenuItem.Create(self);;
  MnAddProject.Caption  := 'Add Project...';
  MnAddProject.OnClick  := NewProjectClick;

  PopupMenu:= PopupMenu;

  PopupMenu.Items.Add(MnAddGroup);
  PopupMenu.Items.Add(MnAddProject);
 
  ...

end;
{------------------------------------------------------------------------------}
Destructor TRBRepositoryTree.Destroy;
begin
  ImagLst.Free;
  PopupMenu.Free;
  MnAddGroup.Free;
  MnAddProject.Free;
  Inherited Destroy;
end;
{------------------------------------------------------------------------------}

baudewynsAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

kretzschmarCommented:
hi baudewyns,

just before i do a closer look, a guess

Destructor TRBRepositoryTree.Destroy;
begin
  ImagLst.Free;
  PopupMenu.Free;
  MnAddGroup.Free;   //must not freed, freed by popupmenu or at least by self
  MnAddProject.Free;    //must not freed, freed by popupmenu or at least by self
  Inherited Destroy;
end;

well, just a guess (not tested).
can you specify, at which line/procedure the exception is raised?

meikl
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
kretzschmarCommented:
hi again,

i guess i got it
replace this line
PopupMenu:= PopupMenu;
with
PopupMenu:= MyPopup;
in your create-statement

meikl
0
LischkeCommented:
The Free calls are the cause for the exception. The menu items are created with an owner (whichever it is, doesn't matter). This owner will release the classes on its own destruction. Hence the variables for MnAddGroup etc. aren't valid anymore (more correct, the inherited destructor tries to free already freed classes).

To avoid further problems with menus I'd like to suggest that you look closer at NewItem. This will create menu items and assign all necessary data (caption, event etc.) in one call. You can directly use the result of NewItem in the Items.Add command so no intermediate references are kept if you don't need them.

Ciao, Mike
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

kretzschmarCommented:
hi mike,

yup, this was also my first look, but
it was telled if removed the add-method no exception is raised.

the realy problem lies also here:

  PopupMenu:= PopupMenu; //thats nil := nil

  PopupMenu.Items.Add(MnAddGroup); //thats Nil.Items...->Exception
   
meikl
0
LischkeCommented:
That's what I thought too, but I think this is only a typo from stripping down the code for sending it here, because if this would really be so in code then the program wouldn't even have started without throwing an exception, but the question above states that the program runs fine until it is stopped.

Ciao, Mike
0
baudewynsAuthor Commented:
Here are the conclusion:

* The code "PopupMenu:= PopupMenu;" was only a bad retranscription of my own code which was correctly "PopupMenu:= MyPopup" as expected.

* If I remove the Free method for the two MenuItem, I don't receive the error anymore as suggested by meikl.
Conclusion, if I create the object without using it, I can free myself the object. If I assign this object to another one, this job is done automatically by this parent object.

Thank you all, that was very simple as usual.
 
0
kretzschmarCommented:
hi baudewyns,

glad thats now working,
decide now, who should be graded,
because also mike's suggestion was correct and more detailed as my was.

just use the link accept comment as answer, which should available upper right to each comment.

don't worry to decide to grade mike.
it's your decission.

meikl
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.