1. Home
  2. Computing & Technology
  3. Delphi Programming

Implement a Button with a Drop Down (Popup) Menu
A Delphi Button with an Additional Drop Down (Popup/Arrow) Menu

By , About.com Guide

Drop-Down Button (Button with a Popup Menu)

Drop-Down Button (Button with a Popup Menu)

A "Button with a Drop Down Context Menu" appears as a normal button with an additional down arrow on the right side of the button. Clicking the "popup button" acts as, well, clicking the button.
Clicking the arrow display a popup menu with an additional set of options.

You will usually find such buttons on toolbars. Delphi IDE's Run button hosts a down arrow - allowing you to select what project in a project group to start. Clicking on the run buttonn directly starts the currently active project.

Another example is the "Send/Receive" button on the toolbar of Outlook Express email client.

There are quite a few (even free with source) third-party Delphi components implementing the idea of a "drop down button".

Let's see how to quickly create such a button using Delphi's TFrame object and two "ordinary" TButton controls, for a test :)

A Dirty implementation of a "Drop Down Button"

The easiest way of mimicking a "drop down button" is to actually have two buttons. The "left" one will act as a "standard" button. The right one will display a down arrow.
Clicking on the right button will display a popup menu with an additional set of options to be executed.

Here are the steps to implement a drop down button with a demo application:

  1. Create a new Delphi project containing one form.
  2. Add a Frame to the project by selecting File - New - Other - Delphi Files - Frame from the IDE's main menu.
  3. On the frame add two buttons.
  4. Let the left one be named "MainButton". Set the Align property to alClient.
  5. Let the right one be named "MenuButton". Set the Align property to alLeft.
  6. Save the unit as "UnitButtonMenu". Let the name of the frame be "ButtonMenu".
Since a frame has the PopupMenu property, you'll use it to accept a popup menu that will be displayed when the user click on the "MenuButton".

Since, by design, a popup menu assigned to a Delphi control, gets displayed when the user clicks the right button over the component, we need to suppress the display of the frame's context menu. This is done using the OnContextPopup event of the frame.

Here's the initial source code of the frame ("UnitButtonMenu" unit):

unit UnitButtonMenu;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Menus;

type
  TButtonMenu = class(TFrame)
    MainButton: TButton;
    MenuButton: TButton;
    procedure FrameContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean) ;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

implementation
{$R *.dfm}

procedure TButtonMenu.FrameContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean) ;
begin
  //suppress the default context menu
  Handled := true;
end;

end.
What's needs to be implemented is the actual display of the popup menu when the "arrow button" is clicked.

Create the handler for the OnClick event of the "MenuButton" button for the frame:

procedure TButtonMenu.MenuButtonClick(Sender: TObject) ;
var
  popupPoint : TPoint;
begin
  if Assigned(PopupMenu) then
  begin
    popupPoint.X := MenuButton.Left + (MenuButton.Width DIV 2) ;
    popupPoint.Y := MenuButton.Top + (MenuButton.Height DIV 2) ;
    popupPoint := ClientToScreen(popupPoint) ;

    //display the popup in the center of the "menu button"
    PopupMenu.Popup(popupPoint.X, popupPoint.Y) ;
  end;
end;

When the "arrow button" is clicked we display the popup menu assigned to the frame object - as if the frame was right-clicked.

Note that the actual popup menu used is not a part of the frame. You will create a popup menu and its items on the form where the "ButtonMenu" will be hosted.

Using the "Drop Down Button"

On the form drop the "ButtonMenu" frame. You do that by dragging the "Frames" items from the Standard group on the component palette.

When you "drop", the "Select frame to insert" dialog box will let you select the frame to be added to the form.

Having the "ButtonMenu" frame on the form, drop one TPopupMenu on the form, also. Add items to the popup menu. Assign it to the PopupMenu property of the frame object (by default named "ButtonMenu1") on the form.

Let's say you have to menu items defined for the popup: "CloseItem" and "CloseSaveItem". Here's a sample implementation of the OnClick event handlers:

procedure TForm1.CloseItemClick(Sender: TObject) ;
begin
  ShowMessage('This should close the program...') ;
end;

procedure TForm1.CloseSaveItemClick(Sender: TObject) ;
begin
  ShowMessage('Save all user information and close program ...') ;
end;

Notes to note

Note that you can double-click the frame's "arrow button" at design-time. Delphi will create a non-empty event handler:
procedure TForm1.ButtonMenu1MenuButtonClick(Sender: TObject) ;
begin
  //added by Delphi - display the popup menu
  ButtonMenu1.MenuButtonClick(Sender) ;

  //add more code here
  //....

end;
What's more you can change any of the properties of both the buttons directly from the form hosting the frame.

You could use the TBitBtn buttons, for glyphs to be easily displayed on the buttons.

I'll leave you to your imagination. This implementation is not ideal, but does the trick :)

Source Code

Download

Explore Delphi Programming
About.com Special Features

Holiday Central

What to eat, where to go, fun things to do and how to save money on the perfect gifts. More >

Family Tech Center

Stay connected and entertained with reviews on tips on the latest HDTVs, cellphones and more. More >

  1. Home
  2. Computing & Technology
  3. Delphi Programming
  4. Using VCL Components
  5. Implement a Button with a Drop Down Menu in Delphi

©2009 About.com, a part of The New York Times Company.

All rights reserved.