A Flat Popup Menu for Controls

CFlatPopupMenu

One thing has always bothered me about web-style controls that pop up menus, and that's the way that the menus don't look as if they are owned by the control. The default Windows menus with their 3D look always look like they belong to the browser and not to the control, hence I wrote this popup menu replacement that looks a lot better when owned by a control.

The class doesn't actually use any MFC so you're OK to go ahead and use it in ATL projects designed for web-based distribution. It also supports keyboard shortcuts and the bitmaps seen in recent Microsoft Office applications. All the colors are independently configurable at run-time so that you can make it fit in with your control's look and feel.

How to use it

  1. I use the STL implementations of string and vector so you'll have to ensure that you add #include <string> and #include <vector> to your stdafx.h file.
  2. Declare as many instances of CFlatPopupMenu as you require. You will need one for each menu and submenu.
  3. Call any SetXXX functions that you need in order to change the font, colors etc.
  4. Call Create() once for each menu and submenu object.
  5. Call AppendItem() and AppendPopup() as many times as necessary for your menu.
  6. Call Track() to display the menu.

OK, here's a breakdown of the class members you should know about as they stand today.

void SetFont(LPCTSTR pszFont)

Sets the font used in the menus. The default font is "MS Sans Serif"

void SetFontSize(const int size)

Sets the size of the font (in points) used in the menus. The default font size is 8 points. At present you should ensure that the font size does not exceed 17 pixels.

void SetPopupDelay(const int delay)

Sets the delay, in milliseconds, between a mouse entering a menu item that has a submenu attached, and that submenu being displayed. The user can always bypass the delay by clicking with a mouse button, just like the standard menus. The default value is 400ms.

void SetColor(const menuColor id,const COLORREF cr)

Sets one of the colors used in displaying the menu. The cr parameter specifies the color and the id parameter specifies one from the menuColor enumeration as listed below.

colorBorder Border color. Also used as the separator color
colorBackground Background area color
colorText Unselected menu item text color
colorGrayedText Grayed (disabled) menu item text color
colorHighlightText Highlighted (selected) menu item text color
colorHighlight Highlighted item bar (background) color
colorLightShadow Used to draw top and left 3D effect around selected icons
colorDarkShadow Used to draw bottom and right 3D effect around selected icons
colorIconTransparent Background color of icons that you can see through.

bool Create(HINSTANCE hInstance,const UINT bitmap_id=(UINT)-1)

Called to create, but not display the menu. You must call this after calling the formatting functions and before tracking the menu. MFC users will get the hInstance parameter by calling AfxGetInstanceHandle(), ATL users will get it by accessing _Module.m_hInst. The bitmap_id parameter specifies the resource identifier of the bitmap that the menu will load its icons from, the default value of -1 means that the menu does not contain icons. The bitmap consists of a strip of 16x15 icons (as used for toolbar buttons) indexed from the left starting at zero, as illustrated by the snapshot below which was taken from the bitmap editor in Developer Studio. The bright pink background color is used as the transparent color in the menu.

The function returns true or false to indicate success or failure.

bool AppendItem(const DWORD dwFlags,LPCTSTR pszName,const UINT itemid,const int icon=-1)

Call this function to add a new item to the end of the menu. dwFlags contains any of the following flags combined with a bitwise OR.

itemSeparator Item is a separator. Should not be combined with any other flags
itemNotSelectable Item is not selectable by the user.
itemGrayed Item is displayed in grayed text. Usually combined with itemNotSelectable.
itemBold Item is displayed using a bold font. Good for non-selectable titles.

pszName contains the text to display as the menu item, separators can pass NULL for this parameter. To include a keyboard shortcut for an item, prefix the shortcut character with an ampersand (&). itemid holds a non-zero identifier that is returned when the item is selected by the user. Non-selectable items and separators can pass zero for this parameter. icon holds the zero-based index of the icon image in the bitmap strip passed to the Create() function or -1 if there is no icon associated with this item.

The function returns true or false to indicate success or failure.

bool AppendPopup(const DWORD dwFlags,LPCTSTR pszName,CFlatPopupMenu& popup,const int icon=-1)

Call this function to add a new popup submenu to the end of a menu. dwFlags, pszName and icon are the same as in AppendItem() but you should not set the separator flag. popup is the actual submenu object that you want to associate with this menu item. This function does not take ownership of popup which means that if you allocated it with new then you should delete it.

The function returns true or false to indicate success or failure.

UINT Track(int x,int y,HWND hWnd,const bool bModal,const bool bPopup=false)

Call this function to display the menu and track the user selection. x and y define the position of the top-left corner of the menu in screen co-ordinates. if bModal is true then hWnd is NULL, otherwise it is the window handle to post the WM_COMMAND message of the selected item to. bPopup is an internal parameter and should never be set by the user, always use the default value of false.

If bModal is true then function returns the item ID of the selected menu item, or zero if no item was selected. If bModal is false then the function returns zero.

An Example

This little code snippet demonstrates how simple it is to create and track a menu:

CFlatPopupMenu menu;
CPoint p;
int id;

// set some of the colors

menu.SetColor(CFlatPopupMenu::colorBorder,m_crText);
menu.SetColor(CFlatPopupMenu::colorText,m_crText);
menu.SetColor(CFlatPopupMenu::colorBackground,m_crBack);

// create it

menu.Create(AfxGetInstanceHandle(),IDB_FILE);

// add some items

menu.AppendItem(0,"&New...",1,0);
menu.AppendItem(0,"&Open...",2,1);
menu.AppendItem(0,"Close",3);
menu.AppendItem(CFlatPopupMenu::itemSeparator,NULL,0);
menu.AppendItem(0,"&Save",4,2);
menu.AppendItem(0,"Save &As...",5);
menu.AppendItem(0,"Save A&ll",6,3);
menu.AppendItem(CFlatPopupMenu::itemSeparator,NULL,0);
menu.AppendItem(0,"Page Set&up",7);
menu.AppendItem(0,"&Print...",8,4);

// track it

p.x=m_rcFile.left;
p.y=m_rcFile.bottom-1;
ClientToScreen(&p);

id=menu.Track(p.x,p.y,NULL,true);

if(id>0)
	// do something with 'id'
else
	// user cancelled the menu

Downloads

Download demo project - 48 Kb
Download source - 10 Kb


Comments

  • Hvis du liker ekstra bass, vel, det er ditt valg

    Posted by mantouhmmm on 06/04/2013 06:50am

    [url=http://www.beatshodetelefoner.webstarts.com/]beats by dre norge[/url] and what not. That way you can target your marketing to the specific people that are interested in hiphop music. I'm not saying it's the only way of course, there are a lot of forums out there waiting for you to sign up to.Forums are a good place to promote yourself but you have to do it exactly right so people won't confuse you to a spammer. Don't sign up to forum just because you want more fans. Do it to stay up-to-date on everything that is happening in the industry and in the side you might get some more listeners, fans and even friends. Build connections and it will serve you well for a long time. Connections are the main thing in the music industry.So go and join forums, be active. When you have build an foundation then start promoting your underground beats, hiphop beats and whatever you do.Though the past few years the internet world has changed rapidly. Internet speeds have increased and the audience and market is increasing like crazy. [url=http://www.beatshodetelefoner.webstarts.com/]beats by dre norge[/url] Designet for imponerende lyd, K551 50 mm drivere (nesten 2 inches, for de som er på keiserlige målinger) som støttes av Engineering ekte AKG bilde. Disse referansen førsteklasses hodetelefonene er utformet for å gi et fullt realistisk og naturtro gjengivelse av livet, og de gode sjåfører er grunnlaget for gjennomføring av lyden. Fast Image Engineering er utformet for å gi klarhet, dybde og avstand i musikk lytting. Lukkede tilbake beatsbre1 SJD gir støyisolering å holde uønsket støy fra mens lær innpakket, polstrede øreklokker hindre lyd lekker ut. AKG design er ikke bare verdifullt for ørene, men øynene samt lette og portable hodetelefoner er laget i klassisk stil med tidløs vinkler Andre funksjoner inkluderer. [url=http://www.beatsdrenorge.webgarden.com/]beats by dre norge[/url] dette er lett å finne fra ulike nettsteder som har blitt prøvd og testet over tid. De trommerytmer er en viktig og en svært viktig del av beats samling uansett hva slags valdet du skriver skal de rap beats eller Jazz slår trommer er veldig viktig siden de gir en god følelse til composition.Visit ulike nettsteder og prøve litt av beats som er der og lytte til dem og prøve hva som tilbys. Besøke nettsteder som tilhører de ulike musikkproduksjon skoler for noen tips som hjelper deg i å kombinere din gratis rap beats og andre musikksjanger beats. Å kunne laste ned beats på nettet en av hemmelighetene er å slå sammen flere e-postlister som slår nedlasting nettsteder de vil gi deg siste nytt om downloads.

    Reply
  • More concessions with herveleger, more lodge a get someone clandestinely on his!

    Posted by Mrleftcowsf on 04/20/2013 05:05pm

    opusherve leger sale burberry sale kidgenuine burberry bags be jaundiced totoms store burberry Bags pick uptoms outlet store unstudiedtoms outlet online hawk

    Reply
  • Jordan shoes mentioned Gene to pay off the discredit, a disunion of Nike

    Posted by TaddyGaffic on 04/20/2013 12:09am

    But in an e mail concerning the LSU activity from South Carolina on October 13, the faculty included the image but digitally erased the cross. The picture was in any other case untouched. A minimum of 15 folks have already been injured as Polish and Russian football enthusiasts clashed in Warsaw forward of your teams' 1-1 attract.. Once I have said, the soccer cleats by [url=http://markwarren.org.uk/goodbuy.cfm]nike free[/url] Adidas have the similar characteristics, therefore in order to know all of them, then expect to have a lengthy list. Obviously, those are the same in ways that Adidas is the one brand that they carry. The lightness of the weight of the materials used in making the Adidas soccer cleats is definitely the main reason why the soccer cleats the manufacture and they are sold in the market are lightweight too. Pokhara is our base for this aerial playground. The [url=http://markwarren.org.uk/property-waet.cfm]nike air max 90[/url] choppy green hills all around offer a lifetime's worth of glorious flying possibilities, many of them still virgin. I Alpine (forward) launch, leaning forward, pulling my lines taut, with my glider laid out in an arc behind me. That is, you want something whose design is similar to that of a ski boot. That means that the inside removable liner, is a moldable type. ( it forms to the contours of your foot, providing maximum comfort and support.) You want the boot itself, made of a stiff plastic, or waterproof outer shell, again for support and insulation. Self defense purposes purposes dealing with #3 * Having the ability to contemplate [url=http://turbo-vac.co.uk/components_13.cfm]nike free 4.0 v2[/url] gets and in addition leg techinques will not likely typically injure. I propose you will get out there applying reside training goods and rehearse fighting and also staying get to that has a close friend and even martial arts university undergraduate. Physical exercise diffusing strikes, using images, supplying photos, and in addition keeping crystal clear focused although becoming bombarded with plenty hits in addition to tennis shoes

    Reply
  • UilKY Rdz IJcL

    Posted by wEAGiLDvim on 11/16/2012 07:32pm

    carisoprodol 350 mg buy somatropin mexico - buy soma with mastercard

    Reply
  • NxBSK eaW Gnix

    Posted by dahueQzhud on 11/14/2012 11:35am

    carisoprodol online soma drug withdrawal - carisoprodol metabolism

    Reply
  • problem in Track(...)

    Posted by sbarker on 01/04/2006 02:54pm

    In the original, when destroying the menu, occasionally it would get a message and never dispatch it.  (In the case where GetMessage returned true, but m_hWnd had been destroyed).
    
    Pretty tiny problem, but for the desired functionality, the message loop should be changed to:
    
    // go into a modal loop
    while(IsWindow(m_hWnd)) {   
        if(GetMessage(&msg,NULL,0,0)==TRUE) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else {
            break;
        }
    }

    Reply
  • Some fixing for runtime menu usage

    Posted by BOIL on 12/29/2005 07:58am

    Anyway, big thanks to the author There are a couple of problems when it is taken to dropdown button menu: 1) menu self closing during navigation 2) self hunging at GetMessage loop For detailed information contact me (for free, of course, :-) ) and I'll send changed source or publish it (FlatPopupMenu.cpp, FlatPopupMenu.h)

    Reply
  • Where can I contact Andy Brown?

    Posted by Legacy on 08/31/2002 12:00am

    Originally posted by: BC

    Apparently, Andy Brown doesnt use this email address anymore and I'd really like to contact him. Can anybody help?

    Reply
  • Is there has the menu supporting thange font on it

    Posted by Legacy on 06/22/2002 12:00am

    Originally posted by: okush

    I seek everywhere to fin menu which supporting change
    font but i cannot find it anywhere Please somebody tell
    me where to find it Thank you

    Reply
  • regarding menu

    Posted by Legacy on 04/26/2002 12:00am

    Originally posted by: mohan

    Hi Andy,
    Your sample was so Cool, solved my problem.
    I have got a question(could be simple to U,think so)
    ,
    got several classes(actually Dialog box as CFormView as base class), need to display them when mouse is clicked.
    I'm wondering 'coz dialog class derived from CFormView doesn't have 'doModal' as like the classes derived from CDialog.
    Hope im'not troubling you.
    regards,
    mohan

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • Businesses are moving more and more of their customer transactions to the web. Security is understandably a top concern as online transactions increase, so it is important to make sure your electronic signature provider meets the highest security standards. That means more than simply passing a security audit or obtaining a certification. This white paper provides recommendations for taking a broader view of e-signature security, and answers key questions that help identify the security requirements against …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds