Visit our Sponsor   Visit our Sponsor
delphi3000.com - the free delphi knowledge platform
delphi3000.com - the free delphi knowledge platform
488 Users Online NOW
Have a look at your member-status

connecting people's knowledge


  - Recent ArticlesRSS feed for Recent Articles on delphi3000.com
  - List of All Articles
  - Top Viewed Articles
  - Articles (+Attachem.)
  - Articles Of Interest
  - Categories
  - Top Uploader
  - Search
  - Index

  - My Home
  - Submit an Article
  - My Articles
  - My Personal Data
  - My Bookmarks
  - Activities
  - Login/Logout

  - Sign Up
  - Why Sign Up
  - Newsletter

  - Press
  - Advertise

  - Contact
  - Feedback





Community
Borland
ClubeDelphi
Dr. Bob
UK-BUG
Delphi Meetings
Planeta Delphi



Loremo - the 1.5 liter car coming in 2009




Startblatt.de






Share this article with friendsShare this article with friends
Rate this articleRate this article - to keep the quality of delphi3000.com !
Comment this article or read through previous comments (2)


How to create a dynamic PopUpMenuFormat this article printer-friendly!Bookmark function is only available for registered users!
Product:
Delphi all versions
Category:
Win API
Skill Level:
Scoring:
Last Update:
04/30/2003
Search Keys:
delphi delphi3000 article borland vcl code-snippet TrackPopUpMenuEx TrackPopUpMenu API SendMessage
Times Scored:
3
Visits:
3252
Uploader: Christoph Otto
Company:
Reference: http://msdn.microsoft.com/library/default.asp search TrackPopUpMenuEx
 
Question/Problem/Abstract:
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


Generated by PasToWeb, a tool by Marco Cantù.


Please give comments

Christoph Otto
otto.c@gmx.net





Please rate this article!
Skill level:
BeginnerExpert

Useful:
No!Very!

Overall rating:
PoorExcellent



Comments to this article
Write a new comment
Variation
    Denis Falqueto (Oct 20 2005 6:58PM)

Well, I want to say that this can help too if you have a popup menu that must be poped up in the upper margin of a component, for example, above a button. Here is what I did and it worked very fine:

// You must have a popup menu, with its items

// In the OnClick of a button:
var Msg : LongBool;
begin
  // Calls the menu and assign the command in the Msg variable.
  Msg := TrackPopupMenuEx( PopupMenu1.Handle, TPM_LEFTALIGN or TPM_BOTTOMALIGN
      or TPM_RETURNCMD or TPM_LEFTBUTTON or TPM_HORPOSANIMATION or TPM_VERNEGANIMATION,
      TControl( Sender ).ClientOrigin.x, TControl( Sender ).ClientOrigin.y,
      Self.Handle, nil );

  // If the user selected some item, lets call it
  if ( Msg ) then
    PopupMenu1.DispatchCommand( Word( Msg ) );


I looked for this problem in many sites but this was the only one that has some advice. Thanks!!!
Respond

RE: Variation
Marvin Gage (May 3 2006 11:03PM)

Your code does not work.  It leaves some menu items invisible.

Well, I want to say that this can help too if you have a popup menu that must be poped up in the upper margin of a component, for example, above a button. Here is what I did and it worked very fine:

// You must have a popup menu, with its items

// In the OnClick of a button:
var Msg : LongBool;
begin
  // Calls the menu and assign the command in the Msg variable.
  Msg := TrackPopupMenuEx( PopupMenu1.Handle, TPM_LEFTALIGN or TPM_BOTTOMALIGN
      or TPM_RETURNCMD or TPM_LEFTBUTTON or TPM_HORPOSANIMATION or TPM_VERNEGANIMATION,
      TControl( Sender ).ClientOrigin.x, TControl( Sender ).ClientOrigin.y,
      Self.Handle, nil );

  // If the user selected some item, lets call it
  if ( Msg ) then
    PopupMenu1.DispatchCommand( Word( Msg ) );

Menu items are not visible with the above code.
Respond














 
Sign up to consume product discounts for Bronze memberships !

read more


  Visit our Sponsor

 

  Community Ad of
Peganza
 
   














 







     
  Copyright © 2000 - 2007 delphi3000.com - All rights reserved. Terms of use. || Privacy
delphi3000.com is a service by bluestep.com IT-Services GmbH (Vienna)