1. Computing & Technology

Discuss in my forum

PopupMenu With Different Item Heights (and Custom Graphics)

By , About.com Guide

Custom PopUp Menu Item Height with Graphics

Custom PopUp Menu Item Height with Graphics

A popup menu appears when the user clicks on a control with the right mouse button.

Popup Menu wih Images

Drop a TPopupMenu (name "PopupMenu1") on a form. Assign it 3 menu items: popItem1, PopItem2 and popItem3. Drop a TImageList (name "ImageList1"), populate it with 3 bitmaps.
Use ImageList1 for the PopupMenu1's Images property.

When a popup menu is shown, the image appears next to the menu item caption. By design, all items are of the same height.

Menu Items with Custom Height

If you need to have different height for some of the menu items, you must turn to owner drawing.

Let's say we want to have a larger height for the second menu item "popItem2", and draw some custom graphics for it.

When OwnerDraw for the TPopupMenu is true, each menu item will receive an OnMeasureItem and an OnDrawItem event when they need to be rendered on screen.

Here's what to do:

  1. Set OwnerDraw to True for the Popup Menu.
  2. To apply owner drawing for the second menu item, handle the OnMeasureItem and AdvancedDrawItem events
The OnMeasureItem event is used to set the height (and width) of the menu item. The OnAdvancedDrawItem occurs when an owner-draw menu needs to be drawn.

Here's the implementation for those two events, for the "popItem2":

 //draw graphics item
 procedure TMainForm.popItem2AdvancedDrawItem(
   Sender: TObject; ACanvas: TCanvas;
   ARect: TRect; State: TOwnerDrawState) ;
 begin
   ACanvas.FillRect(ARect) ;
 
   //draw text
   ACanvas.Font.Style := [fsBold];
   ACanvas.TextRect(ARect,24 + ARect.Left, 4 + ARect.Top,'Picture in PopupMenu!') ;
 
   //shrink rect
   InflateRect(ARect,-5,-5) ;
   //move it "down"
   ARect.Top := ARect.Top + 20;
   //draw image
   ACanvas.StretchDraw(ARect, Image1.Picture.Graphic) ;
 end;
 
 //set the item height
 procedure TMainForm.popItem2MeasureItem(
   Sender: TObject; ACanvas: TCanvas;
   var Width, Height: Integer) ;
 begin
   //set to desired height
   Height := 100;
 end;
 

Note: in the above code, a TImage (name "Image1") is used to supply the graphics to be drawn for the menu item.

If you want to use an image contained in the ImageList, you can use the next code for the OnAdvancedDrawItem event:

 //draw graphics item
 procedure TMainForm.popItem2AdvancedDrawItem(
   Sender: TObject; ACanvas: TCanvas;
   ARect: TRect; State: TOwnerDrawState) ;
 var
   bitmap : TBitmap;
 begin
   ACanvas.FillRect(ARect) ;
 
   //draw text
   ACanvas.Font.Style := [fsBold];
   ACanvas.TextRect(ARect,24 + ARect.Left, 4 + ARect.Top,'Picture in PopupMenu!') ;
 
   //draw graphics from the imagelist
   bitmap := TBitmap.Create;
   try
     ImageList1.GetBitmap(popItem2.ImageIndex,bitmap) ;
     InflateRect(ARect,-5,-5) ;
     ACanvas.StretchDraw(ARect, bitmap) ;
   finally
     bitmap.Free;
   end;
 end;
 
In the above code, the GetBitmap of the TImageList is used to draw the graphics contained in the image list.

Delphi tips navigator:
» Save (and Load) all the Images from a Delphi TImageList to a Single File
« How to Hide / Show the Main Menu of a Delphi Application

Source Code

©2012 About.com. All rights reserved.

A part of The New York Times Company.