Jump to content
giomach

VCL menu control needed

Recommended Posts

I'm looking for a VCL control to use in Delphi XE.  It should be made up of TMenuItems, but neither TMainMenu or TPopupMenu meets my need.

 

Unlike TMainMenu, the control should allow placement anywhere on the form, and should allow the items to be displayed vertically  — as TPopupMenu does.  (I don't need submenus.)

 

Unlike TPopupMenu, it should not disappear when an item is clicked, but should have Hide and Show methods.

 

Basically I want the appearance of a popup menu but with the behaviour of a normal control.

 

Does such a control exist?  If I have to create it myself, where should I start?

 

Thanks for any ideas.

Share this post


Link to post

if dont exists, you can do it that way:

  • create a Form to acommodate your options, let's call it: "myFormPopUp"
    • add your components necessary to create your necessity
    • add the events necessary
    • if necessary, use "OnClose" = Action := caFree;
  • using "MouseDown" event in your "form (where you want the "clicks") on screen, just ask to "Show" the "MyFormPopUp" with options simulating a "popup" menu, let's call it: MyFormCustomer = mark the property "KeyPreview=true"
  • for better usage, create the "MyFormPopUp" on create of "MyFormCustomer" or in any other place to global access!
  • when need "hide" the "MyFormPopUp", just use: MyFormPopUp.HIDE;
  • when need "destroy it" the "MyFormPopUp", just use: MyFormPopUp.Close;

 

note: if the "focus" is in any other control, like "TEdit", you need use "OnKeyDown" of Edit control!!! or assing it for all controls on focus!

 

do you understand?

Edited by programmerdelphi2k

Share this post


Link to post

Thanks for your suggestions.  I want to emphasize that I really do want the menu items to look like TMenuItem — I want to have accelerator keys, a tag property, separator items (caption = '-'), highlighting of the item under the mouse, etc.  The aspect of TPopupMenu that I don't want is that it disappears by itself.  I've been down the road of writing handlers for every event that could make the popup menu disappear, but that just leads to more problems.

 

I may be wrong, but it seems difficult to achieve the visual "simulation of a popup menu" that I have described using other standard controls, such as possibly TButtonGroup, whether placed on a separate form or not.

 

This leads me to think that the solution must be a new control, a descendant of TMenu using TMenuItem directly, probably mixing code from both TMainMenu and TPopupMenu, but I have no experience of writing controls.  So I asked if such a control already exists, or if not, how I should go about making one.

 

If I have failed to understand the suggestions already made, please say if you think they can still work for me.

Share this post


Link to post

TMS have a popup menu TAdvStickyPopupMenu in which items have a property which sets them to not hide the menu when clicked.  But I don't think it is available on its own, only in the VCL UI Pack.

Share this post


Link to post
10 hours ago, giomach said:

If I have failed to understand the suggestions already made

You should really show a mockup of what GUI you want because all suggestions done could do what I understood you want. And in my opinion you have enough in Delphi to achieve your goal without to much work.

Share this post


Link to post

Thank you all for taking the trouble to help.

 

I'm trying programmerdelphi2k's solution but I'm missing something, as clicking any of the three buttons produces no result (the ShowMessage doesn't appear).

 

test.thumb.jpg.39f5bcab1f4ab0cebce7c5c5a39f6827.jpg

 

I also attach my unit3 source and the text of my form3.

 

I also attach a screenshot of my application at present. The rectangle at the upper right of the form is a dynamically-built TPopUpMenu.

 

popup.thumb.jpg.7b350f189572af1d73406d0c1874bf3a.jpg

 

You can see the features of TMenuItem which I am using:  accelerator keys on the bottom three items, a separator item above these three, highlighting of the item under the mouse, enabling and disenabling items according to the context.  These are all provided by TMenuItem.  Not seen is the use in programming of TMenuItem's tag property.  Perhaps these can all be implemented in the suggested solutions by additional programming? — I don't know if that is possible.

form3.txt

Unit3.pas

Share this post


Link to post

here my sample in "7z " compress-files

VCL_imitating_a_Popup_with_a_Form.7z

 

  • each button on myFormPopUp is using an "action" from "ActionList" component!
  • then, you use "actionXXX.Execute" event to create your logic [ not ButtonXXX.click() ]   ... my ShowMessage(...) for example!
Edited by programmerdelphi2k

Share this post


Link to post

The sample project is working well now — I needed to put OnExecute handlers on the actions.

 

I'm pleasantly surprised to find that TSpeedButton shares some of the desired features of TMenuItem, even without further programming by me.  I'll try now to use it in my application, and see how that goes.

 

Apart from anything else, I have learned about "Actions", and the technique for getting a popup to follow the movement of the main form will certainly be useful.

 

Thanks again all round.

 

Share this post


Link to post

other way "more" simple yet:

  • create your PopUp options in a "FRAME" - named "myPopUpUsingFrame" - OK!
  • now, in your "form-in-usage" (for example, myFormWithEdits...), on "OnCreate" event... create your "myPopUpUsingFrame"
  • now, in your "form-in-usage", just use "OnMouseDown" to "show your frame-popup"
  • more simple to use, because "in fact" your new-frame will a "child" from your "form-in-usage", then, you can use shortcuts, tab to jump for it etc...

procedure TfrmFormMain.FormCreate(Sender: TObject);

  frmFramePopupMenu         := TmyPopUpUsingFrame.Create(nil);
  frmFramePopupMenu.Visible := false; // hide it for while...
  frmFramePopupMenu.Parent  := self;  // to show on current form 
...

end;

 

procedure TfrmFormMain.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  MyActiveControl: TWinControl;
begin
  MyActiveControl := self.ActiveControl;
  //
  if (Button = TMouseButton.mbRight) then
    begin
        if not(frmFramePopupMenu = nil) then
          begin
            frmFramePopupMenu.Left := X;
            frmFramePopupMenu.Top  := Y;
            //
            frmFramePopupMenu.Show;
            //
            MyActiveControl.SetFocus;
          end;
    end;

Sem título.png

Edited by programmerdelphi2k

Share this post


Link to post

This is the outcome of my attempt to replace the popup menu at the upper right (as shown in a previous attachment) by a control which will not disappear unless I make it, while preserving as much of the appearance as possible.  This is implemented by means of a number of TSpeedButtons created at runtime and placed on a TPanel which is created at design time.

 

popup2.thumb.jpg.a270332712d53e2fad4769208defb238.jpg

 

It's fairly satisfactory, most importantly the accelerator keys work.

 

If there's anything of interest in this, it is probably the fact that the SpeedButton under the cursor, although it stands out a little, does not change colour here, though it does so in a newly-created VCL project.  After much trouble I tracked this down to my old application having Project/Options/Application/Enable runtime themes not set, whereas it is set by default in a new project.  However setting it in my old project upset my colour scheme and made a TListView malfunction.  So I make do without setting it, and partially compensating by putting Flat = true on the SpeedButtons.

 

Thanks to all who helped me towards a solution to this problem, which has been rumbling on for years.

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×