Mega Code Archive

 
Categories / Delphi / VCL
 

How to create a dynamic PopUpMenu

Title: How to create a dynamic PopUpMenu Question: Have you ever wanted to Create a PopupMenu at a Position you wanted. e.g. from a button going up: _______ |_Item1_| |_Item2_|__ |Button___| Here is an approach with TrackPopupMenuEx. Hint: Use if you are stuck to StandardControls, otherwise you could use a clever component, if you find it Answer: So here is the commented sorce: unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Menus; const //our Message ID's WM_1TEST = WM_USER + 101; WM_2TEST = WM_USER + 102; WM_3TEST = WM_USER + 103; type TForm1 = class(TForm) Panel1: TPanel; Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); protected procedure WMCommand(var Msg: TWMCommand); message WM_COMMAND; end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.WMCommand(var Msg: TWMCommand); begin case Msg.ItemID of //- Msg.ItemID contains the WM_USER + x WM_1TEST : Memo1.Lines.Add('Command 1'); WM_2TEST : Memo1.Lines.Add('Command 2'); WM_3TEST : Memo1.Lines.Add('Command 3'); end; inherited; //- important for not disturbing Windows-MessageHandling end; procedure TForm1.Button1Click(Sender: TObject); var MyPopUpMenu : TPopUpMenu; MyMsg : LongBool; begin MyPopUpMenu := TPopUpMenu.Create(Self); MyPopUpMenu.AutoPopup := FALSE; MyPopUpMenu.AutoHotkeys := maManual; //Create the Items //AppendMenu here sufficient, just want to handle a simple OnClickEvent //could also be used with if or case if you don't want all the Items //everytime AppendMenu(MyPopUpMenu.Handle , MF_POPUP //- each Item in single Line //otherwise use // MF_MENUBREAK for a Column for each Item (all in one Line) // MF_MENUBARBREAK for a Column each Item with separator or MF_STRING or MF_UNCHECKED , WM_1TEST //- important the WM_USER+x identifies the Msg in WMCommand , 'Test1'); //Caption of the MenuItem AppendMenu(MyPopUpMenu.Handle , MF_POPUP or MF_STRING or MF_UNCHECKED , WM_2TEST //- important the WM_USER+x identifies the Msg in WMCommand , 'Test2'); AppendMenu(MyPopUpMenu.Handle , MF_POPUP or MF_STRING or MF_UNCHECKED , WM_3TEST //- important the WM_USER+x identifies the Msg in WMCommand , 'Test3'); MyMsg := TrackPopupMenuEx(MyPopUpMenu.Handle //the PopUpMenu to be shown // Alignment to the point specified! // horizontal vertical , TPM_LEFTALIGN or TPM_BOTTOMALIGN //in this case to the left and up //, TPM_LEFTALIGN or TPM_TOPALIGN //, TPM_LEFTALIGN or TPM_VCENTERALIGN //, TPM_RIGHTALIGN or TPM_BOTTOMALIGN //, TPM_RIGHTALIGN or TPM_TOPALIGN //, TPM_RIGHTALIGN or TPM_VCENTERALIGN //, TPM_CENTERALIGN or TPM_BOTTOMALIGN //, TPM_CENTERALIGN or TPM_TOPALIGN //, TPM_CENTERALIGN or TPM_VCENTERALIGN //or TPM_VERTICAL or TPM_HORIZONTAL //you could specify a region the PopUpMenu should'nt overlap //but you have to specify a TPMPARAMS(~TRect) structure (last Param) or TPM_RETURNCMD //Return the Identifier of the Item clicked //or TPM_NONOTIFY //no Message send back or TPM_LEFTBUTTON //the Left Button selects //or TPM_RIGHTBUTTON //the Right Button selects //or TPM_LEFTBUTTON or TPM_RIGHTBUTTON// or both or TPM_HORPOSANIMATION or TPM_VERNEGANIMATION //^these Settings look best with TPM_LEFTALIGN and TPM_BOTTOMALIGN //could also be: //TPM_NOANIMATION //or TPM_HORNEGANIMATION or TPM_VERPOSANIMATION , TControl(Sender).ClientOrigin.x //Origin of Menu X //+TControl(Sender).Width //use TPM_RIGHTALIGN and TPM_BOTTOMALIGN , TControl(Sender).ClientOrigin.y //Origin of Menu Y //the TopLeft Point of the Control which should have the Menu //used TControl here, so it could be used with most Control's //for Example if you want a TLabel to have a PoPUpMenu , Self.Handle //- Handle to the Window/Application , nil); //- TPMPARAMS structure, nil cause, i forced the PopUp Menu to go Left and Up if MyMsg then //- TrackPopUpMenuEx returns TRUE if everything worked out ok SendMessage(Self.Handle //- sending a message to the window , WM_COMMAND //- Type of Message , Integer(MyMsg) //- Param, i.e. ReturnValue of TrackPopUpMenuEx , 0); MyPopUpMenu.Free; //- destroy created PopUpMenu MyPopUpMenu := nil; end; end. //Reference: //Delphi Help: TrackPopUpMenu, AddMenu, DestroyMenu, Sendmessage //don't forget to check overview, Group, etc. in the Help Entrys Please give comments Chr.