Recent

Author Topic: Popup menu hierarchy  (Read 377 times)

simone

  • Hero Member
  • *****
  • Posts: 626
Popup menu hierarchy
« on: October 16, 2024, 02:48:10 pm »
I start the post illustrating something I didn't know, in order to confirm that I understood correctly, then I ask the consequent question.

Suppose we have a control with an associated popup menu, which is the parent of a control with a different associated popup menu, both set at design time. If at run time the popup menu of the child control is disabled (i.e. the PopupMenu property set to nil), every time the right mouse button is pressed on the child control, the context menu of the parent control is shown. Therefore the possibility of activating the popup menu is not disabled. The attached example shows this mechanism.

If this is confirmed, then I have the following problem. I'm developing a component that can be used as a child of any parent, within a parent-child hierarchy. This control, if in a certain state, uses the right mouse button for a specific function, therefore in that state the popup menu of the control itself must not be active. In this state, to prevent the parent control's popup menu from being shown, should I recursively nil all the ancestors' popup menus, or is there a smarter way to disable the popup?
Microsoft Windows 10 64 bit - Lazarus 3.0 FPC 3.2.2 x86_64-win64-win32/win64

zeljko

  • Hero Member
  • *****
  • Posts: 1668
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: Popup menu hierarchy
« Reply #1 on: October 16, 2024, 03:03:41 pm »
What about setting TPopupMenu.AutoPopup to false (parent popup menu) ?
EDIT: Sorry, in that case you should call manually popup for your parent control. Maybe MyChild.OnContextPopup and then set Handled := True if MyChild.PopupMenu = nil.
« Last Edit: October 16, 2024, 03:06:58 pm by zeljko »

simone

  • Hero Member
  • *****
  • Posts: 626
Re: Popup menu hierarchy
« Reply #2 on: October 16, 2024, 04:08:33 pm »
The problem is that if the child control is a TScrollBox, as in my attached example, the OnContextPopup property is not available.
Microsoft Windows 10 64 bit - Lazarus 3.0 FPC 3.2.2 x86_64-win64-win32/win64

simone

  • Hero Member
  • *****
  • Posts: 626
Re: Popup menu hierarchy
« Reply #3 on: October 16, 2024, 05:09:57 pm »
While waiting for a more intelligent solution to the problem, here's what I had thought:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Menus;
  9.  
  10. type
  11.  
  12.   { TScrollBox }
  13.  
  14.   TScrollBox=class(Forms.TScrollBox)
  15.     private
  16.       procedure EnablePopupMenus;
  17.       procedure DisablePopupMenus;
  18.     public
  19.       PopupMenuList : array of TPopupMenu;
  20.   end;
  21.  
  22.   { TForm1 }
  23.  
  24.   TForm1 = class(TForm)
  25.     Button1: TButton;
  26.     Button2: TButton;
  27.     MenuItem1: TMenuItem;
  28.     MenuItem2: TMenuItem;
  29.     MenuItem3: TMenuItem;
  30.     PopupMenu1: TPopupMenu;
  31.     PopupMenu2: TPopupMenu;
  32.     ScrollBox1: TScrollBox;
  33.     procedure Button1Click(Sender: TObject);
  34.     procedure Button2Click(Sender: TObject);
  35.   private
  36.  
  37.   public
  38.  
  39.   end;
  40.  
  41. var
  42.   Form1: TForm1;
  43.  
  44. implementation
  45.  
  46. {$R *.lfm}
  47.  
  48. { TScrollBox }
  49.  
  50. procedure TScrollBox.DisablePopupMenus;
  51. var
  52.   P : TWinControl;
  53. begin
  54.   PopupMenuList:=nil;
  55.   P:=self;
  56.   while Assigned(P) do
  57.     begin
  58.       Insert(P.PopupMenu,PopupMenuList,Length(PopupMenuList));
  59.       P.PopupMenu:=nil;
  60.       P:=P.Parent;
  61.     end;
  62. end;
  63.  
  64. procedure TScrollBox.EnablePopupMenus;
  65. var
  66.   P : TWinControl;
  67.   ind : integer;
  68. begin
  69.   P:=self;
  70.   for ind:=0 to Length(PopupMenuList)-1 do
  71.     begin
  72.       P.PopupMenu:=PopupMenuList[ind];
  73.       P:=P.Parent;
  74.     end;
  75. end;
  76.  
  77. { TForm1 }
  78.  
  79. procedure TForm1.Button1Click(Sender: TObject);
  80. begin
  81.   ScrollBox1.DisablePopupMenus;
  82. end;
  83.  
  84. procedure TForm1.Button2Click(Sender: TObject);
  85. begin
  86.   ScrollBox1.EnablePopupMenus;
  87. end;
  88.  
  89. end.  
Microsoft Windows 10 64 bit - Lazarus 3.0 FPC 3.2.2 x86_64-win64-win32/win64

jamie

  • Hero Member
  • *****
  • Posts: 6733
Re: Popup menu hierarchy
« Reply #4 on: October 16, 2024, 08:17:55 pm »
I could consider this as a bug, but I am not sure of this isn't the way it should work..

In any case look at my test app.
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Menus, StdCtrls,Lmessages;
  9. Type
  10.  
  11. { TscrollBar }
  12.  
  13. TscrollBox = Class(Forms.TScrollBox)
  14.   procedure WndProc(Var Msg:TLMessage); Override;
  15. end;
  16.  
  17.   { TForm1 }
  18.  
  19.   TForm1 = class(TForm)
  20.     Button1: TButton;
  21.     MenuItem1: TMenuItem;
  22.     MenuItem2: TMenuItem;
  23.     MenuItem3: TMenuItem;
  24.     MenuItem4: TMenuItem;
  25.     MenuItem5: TMenuItem;
  26.     MenuItem6: TMenuItem;
  27.     MenuItem7: TMenuItem;
  28.     PopupMenu1: TPopupMenu;
  29.     PopupMenu2: TPopupMenu;
  30.     ScrollBox1: TScrollBox;
  31.   private
  32.  
  33.   public
  34.  
  35.   end;
  36.  
  37. var
  38.   Form1: TForm1;
  39.  
  40. implementation
  41.  
  42. {$R *.lfm}
  43.  
  44. { TscrollBar }
  45.  
  46. procedure TscrollBox.WndProc(var Msg: TLMessage);
  47. begin
  48.   if Msg.msg = LM_ContextMenu then
  49.   begin
  50.     If PopUpMenu = Nil then
  51.     Msg.Msg := 0;
  52.   end;
  53.   inherited WndProc(Msg);
  54. end;
  55.  
  56. end;
  57.  
  58.  

Btw, That works  :D
The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018