"Wyatt Says..." is a collection of articles by Wyatt O'Day talking about wyDay products and the things we've learned along the way.
A question I see raised often on forums is some variation on “how do I get menus that look like Vista’s menus: icons with the baby-blue selection highlight.” Or, how do I get my menus to look like Windows Explorer context menus:
The first thing you should notice is the light-blue gradient used for the selection highlight. The second thing is the alpha-blended icon (that is, the icon has partially transparent pixels that blend nicely with the light-blue gradient).
But how do you get that look without owner-drawing your menu items? There was a nice post over at Mircosoft’s Shell Blog describing how to do it in C++. I’ve taken the applicable parts of the C++ code and ported them to a nice little interface for .NET languages. That is, you’ll be able to use my code with C#, VB.NET, and any other .NET languages that exists.
Here’s a screenshot of the interface I created (called VistaMenu) running in Windows Vista, Windows XP, and Windows 98:
As you can see, I took the time to make sure the VistaMenu worked and looked good even in the older Windows systems.
How to use VistaMenu
You need to add ContextMenu, MainMenu, and VistaMenu controls to the Visual Studio toolbox:
This should add all the necessary controls to the Toolbox. Now just drag the VistaMenu control to your form (you only need one VistaMenu per Form), a MainMenu, and any number of ContextMenus.
All you have to do now is click a menu items, and in the the Properties window select an Image. No messy ImageList is necessary:
You should know…
As I mentioned parenthetically above, you only need one VistaMenu per form. This one VistaMenu component handles all the MenuItems for the MainMenu and all ContextMenus on your Form. If you add more than one ‘VistaMenu’ component you’ll waste resources and your program will likely crash.
Also, VistaMenu is for ContextMenus and MainMenus, NOT ContextMenuStrips and MenuStrips. They’re completely different controls.
Also out, SplitButton 2.0
Version 2.0 of the SplitButton adds support for ContextMenu in addition to ContextMenuStrip. Now you can use the shiny new VistaMenu with the SplitButton.
This is a breaking change, however. Previously you had to set the ‘SplitMenu’ property with a ContextMenuStrip, but in this version there are two properties: ‘SplitMenu’ and ‘SplitMenuStrip’. Where ‘SplitMenu’ takes a ContextMenu, while ‘SplitMenuStrip’ takes a ContextMenuStrip.
Questions, comments, complaints…
Take a trip over to the forum and let me have it. No registration is required, and all input is welcome.
Download VistaMenu: Includes the source code, a compiled binary, and demo projects for both C# and VB.NET.
Download SplitButton v2.0: Includes the source code and the compiled binary. It works with every .NET language.
I’ve updated the SplitButton control to paint the Image property, plus I’ve added ImageAlign and TextAlign support. I’ve also fixed a dozen other little bugs, and code signed the dll file.
The reason I had left the Image property unimplemented was because I thought “who needs a car any color other than black?” It turns out some people do. If you have any comments, bug reports, or general chit-chat leave a post on the forum. (No registration required)
Download SplitButton v1.6 [includes SplitButton.dll and the C# source files] It works with any .NET 2.0 or above language (C#, VB.NET, etc.)
You’re dying to know what the AIC is, aren’t you? No, it’s not a test to see if you qualify for insurance with a talking wallaby. Rather, you’ll be glad to hear that I’ve coined a new computer acronym which you can add to your arsenal of entirely forgettable “stupid geek talk.”
The AIC test (pronounced “ache test”), briefly, is a confirmation that your program works at 3a.m. Specifically it’s a guard that you, the programmer, put in place for your customers’ all-nighters. He’ll be running Firefox with over 30 tabs open, Photoshop with nearly a gig’s worth of images in memory, and several other CPU & memory intensive programs, plus your own program.
He’s 20 minutes away from finishing after nearly 20 hours of caffeine fueled work. He clicks a link in Firefox and the browser freezes. Realizing a bad situation in the making, he flips back to Photoshop to save his work. “Application Not Responding,” Windows gleefully reports. He switches from program to program, leaving a trail of unresponsive programs.
By the time he flips to your program, his Tea is in a puddle on his desk and he’s used phrases that would make a longshoreman blush. Now begins the anger induced clickscapade. Clicking furiously, and largely at random, he’s going to try to save his work, export and upload his data, and print a copy of his work all while your program blinks between responsive and unresponsive states. Your program has to process each click and keystroke perfectly. This means no flaky behavior.
From that series of events alone, the AIC test sounds suspiciously arbitrary. If you’ve taken even a beginners computer course you’ll already know that nothing in the computer is arbitrary or unpredictable. To illustrate my point I’ll describe the steps I took to fix an already usable SplitButton control to an AIC passable SplitButton control.
SplitButtons are everywhere from Firefox to Photoshop to many Microsoft products. Here’s a SplitButton in Firefox:
As the name SplitButton implies, the functionality of the back button in Firefox is divided. Click the near the green arrow and the browser goes back a page; click the downward pointing black arrow (the drop-down region) and a list of recently visited sites appears.
These types of buttons are seen so often in Windows programs, you’d think Microsoft would have built the functionality into the Windows API prior to adding it to Windows Vista. Not so. After googling for a few hours I found three options:
The SplitButton I opted to use was by the Microsoft programmer, Jessica. After an hour of use I noticed a few sticky parts in her nearly perfect implementation. First of all, the drop-down region of the SplitButton didn’t fill the full height of the button:
If the user clicks the right hand side of Jessica’s button the user will expect a menu to pop-up. However, the highlight shows that if the user clicks either the top or bottom five pixels they will have triggered the normal button click-event. At 3a.m. this subtlety is death. It’s an easy fix, so why not fix it?
Then there’s the matter of right clicking. In Firefox’s SplitButtons a right click shows the menu directly under the button â€“ acting identical to clicking the drop-down region. Jessica’s implementation, along with SplitButtons in Windows toolbars, shows the menu wherever the right click happened. I prefer displaying the menu directly under the button so it doesn’t obscure the button’s text:
And lastly, Jessica forgot to implement the disabled state for the SplitButton. It’s another easy fix, and is essential if you disable buttons:
All of these “major” fixes took less than an hour to implement and test, and they reduced my own frustration with the button. I use the SplitButton in the InstantUpdate Designer so the user can select options when uploading their newly created update files:
If I were to use an unaltered version Jessica’s SplitButton, then a user could easily start large uploads when he only wanted to change an upload option. Quirks like these make months of hard work seem wasted. And, it’s only through anger induced clickscapades do these problems show themselves.
Update October 13, 2008: You can view all the latest changes at the SplitButton changelog page.
Download the fixed SplitButton. Open source, and confirmed working with .NET 2.0 and above (C#, VB.NET, etc.).