Search code examples
delphicontrolsparentmenuitemsender

TComponet / any other Superclass and its child item detection


I have Popup menu control on form ( grr, I most likely gonna make it dynamic - hate static tools ). It has got Item with SubMenu. SubMenu has three Menu Items ( TMenuItem class ).

I need to check by taking Sender param in if..then statement whenever procedure has been called by the Item with SubMenu or by SubMenu Items.

I tried different vraiations with typecasting and superclass operations but no luck. I think it is possible to something like this:

if FindControl(MenuItemWithSubMenu.Handle) = TControl(Sender as TComponent).Parent then ...

but, of course, with correct typecasting and commands ..

Any ideas appreciated.

Additional Information by community request:

The code itsef ( if I simply check by component name prop ) looks like this:

procedure TForm1.xClick(Sender: TObject); // procedure that has attached onClick from    PopupActionBar1 Items
begin    
if ((TComponent(Sender).Name = 'Unloadresources1') or  // PopupActionBar1.Items[3]
     (TComponent(Sender).Name = 'VKPCache11')       or // PopupActionBar1.Items[3].Items[0]
     (TComponent(Sender).Name = 'VKPCache21')       or // PopupActionBar1.Items[3].Items[1]
     (TComponent(Sender).Name = 'AllCache31')       or // PopupActionBar1.Items[3].Items[2]
     (ActLoadVal = 2)) and (PopupActionBar1.Items[3].Caption = 'Delete VKP Cache') then begin .. end;
end;

The problem is that it is way to weak approach and needs additional coding if programm user wants to add / drag'n'drop / insert component or control or object in runetime. In this way programm itself would automatically do hald job in my place - know what to call and when :)

On ( static ) Form1 is ( static ) PopupActionBar1. It has four Items. Forth Item has SubMenu - with three Items.

Both fourth item with submenu items ( PopupActionBar1.Items[3] ) and three submenu items ( PopupActionBar1.Items[3].Items[0 .. 2] OnClick event handlers are set to Procedure containing If..Then statement wrote above.

Task - by eveluating Sender parameter and using its OOP capabilities - check if Procedure has been called from PopupActionBar1.Items[3] Menu Item or its SubMenu items ( PopupActionBar1.Items[3].Items[0] or PopupActionBar1.Items[3].Items[1] or PopupActionBar1.Items[3].Items[2] ).

I have tried various syntax ... also tried typecasting manipulations with TControl, TWinControl, TComponent .. ( no use of TObject is it has got no Parent ( excl. OLE ) ..


Solution

  • You don't need to find the Item, it is already the Sender. I.e. you can do

    procedure TForm1.MyItem1Click(Sender: TObject);
    begin
      if Sender = MyItem1 then
        [...]
      else if Sender = MyItem2 then
    

    I generally use the tag property to differentiate the MenuItem that triggered the handler. Not elegant, but works.

    procedure TForm1.Item1Click(Sender: TObject);
    begin
      case TMenuItem(Sender).Tag of
        0: [..];
        1: [..];
        [..]
    

    One has to remember to set the all menu item's OnClick events to point to the same handler. This is something I don't remember till I see clicking one has no effect..