Popup menu border


Simply put, I want to be able to show popup menus with solid borders, with my choice of thickness and colour.


Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Wim ten BrinkSelf-employed developerCommented:
AFAIK, the popup class doesn't have a customdraw method and doesn't even provide you any way to draw it yourself with simple events. I think it cannot be done, unless you want to write your own code for it. (E.g. by displaying a panel, drawing the menuoptions on this panel any way you like them and use OnClick events to respond to menu-options. But then this isn't a real popup anymore.)
MoonCalfAuthor Commented:
Erm, thanks alex, but I've already done a lot of drawing on the menus.  If you google you'll find lots of examples of custom-drawing on menus, both standard and popup.
Wim ten BrinkSelf-employed developerCommented:
Ah, I see. I was looking at the wrong location... :-)
Well, in that case you already know the answer... Use the CustomDraw event of the menu item... The simplest way to do this is by assigning one single OnDraw event to all the menu-items in your messagelist. The sender will be the menu item that wants to be drawn so use it to get the caption. If you want to draw a box around the whole popup menu then you have to look if the menu-item happens to be the first or last in the list. If so, you should draw the sides and either the top or bottom border. If it's not, draw only the sides.
Set the Popup OwnerDraw to True and on e.g. the FormCreate, call this code:

  for I := 0 to pred( PopupMenu1.Items.Count ) do
    PopupMenu1.Items[ I ].OnAdvancedDrawItem := GlobalAdvancedDrawItem;

And of course, add the GlobalAdvancedDrawItem function:

procedure TFormMain.GlobalAdvancedDrawItem( Sender: TObject; ACanvas: TCanvas; ARect: TRect; State: TOwnerDrawState );
  MenuItem: TMenuItem;
  if Sender.InheritsFrom( TMenuItem ) then begin
    MenuItem := TMenuItem( Sender );
    if ( MenuItem.MenuIndex = 0 ) then begin
      DrawEdge( ACanvas.Handle, ARect, EDGE_ETCHED, BF_LEFT or BF_RIGHT or BF_TOP );
    else if ( MenuItem.MenuIndex = Pred( MenuItem.Parent.Count ) ) then begin
      DrawEdge( ACanvas.Handle, ARect, EDGE_ETCHED, BF_LEFT or BF_RIGHT or BF_BOTTOM );
    else begin
      DrawEdge( ACanvas.Handle, ARect, EDGE_ETCHED, BF_LEFT or BF_RIGHT );
    ARect.Left := ARect.Left + 2;
    ARect.Top := ARect.Top + 2;
    ARect.Right := ARect.Right - 2;
    ARect.Bottom := ARect.Bottom - 2;
    ACanvas.TextRect( ARect, ARect.Left, ARect.Top, MenuItem.Caption );

Of course, you could use your own drawing technique. Also, above code doesn't check if items are hidden of if there's only one menu-item in the list. It needs more work... Use the canvas methods to draw whatever you like but also make sure to set the OnMeasureItem event if you want to make it a bit bigger. You have to make sure that whatever you draw will fit.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
MoonCalfAuthor Commented:
Thanks alex - with a bit of jigging around I can get that working with what I've already done.

Cheers mate,


It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.