![]() |
Languages »
C / C++ Language »
General
Intermediate
A Simple Bitmap Button ImplementationBy Marc CliftonA small class that provides a pure bitmapped button capability for WinForms. |
C#.NET 1.1, Win2K, WinXP, Win2003VS.NET2003, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||

It appears after some minor searching that nobody has written a BitmapButton for The Code Project (or anywhere else). WiB's excellent XP style button control solves the problem of XP style buttons with icons. But what if you want to control the entire appearance of the button using a bitmap, regardless of OS, manifest, theme, etc.? This control does provides that ability. Mind you that this class is pretty bare bones--I haven't made any effort to make is usable with a form designer. If anyone wants to update the code with this capability, I'll be more than happy to add them as a co-author.
The BitmapButton class uses a single bitmap comprised of one or more images, where each image represents the button in one of five states. The images must be placed contiguously from left to right. For example:
represents the bitmap of a button with five states:
The button is initialized in the usual manner with the additional line of code to specify the bitmap file:
bitmapButton=new BitmapButton(); bitmapButton.Location=new Point(232, 32); bitmapButton.Size=new Size(32, 32); bitmapButton.TabIndex=0; bitmapButton.Text="&Down"; bitmapButton.Image=new Bitmap("downArrow.bmp");
Three important notes:
Text field is used exclusively to specify the keyboard shortcut for the button;
That's it. (If you forget the image, the program will generate an exception).
Button state is a complicated thing when considering the dual user interface of keyboard and mouse. For example, the user may have the mouse over the button but be using the tab key to navigate between the controls. A complete state diagram appears as follows:

This diagram represents the state transitions that must be considered when using the mouse and the keyboard together. It's fairly complicated!
If the keyboard is being used, the state diagram is much simpler (the Disabled state has been removed for clarity only):

If the mouse is being used, the state diagram has some missing state transitions (again, the Disabled state has been removed for clarity only):

To manage all the events that can occur and properly transition between different states, several event handlers must be defined:
Paint+=new PaintEventHandler(BitmapButton_Paint); MouseDown+=new MouseEventHandler(BitmapButton_MouseDown); MouseUp+=new MouseEventHandler(BitmapButton_MouseUp); GotFocus+=new EventHandler(BitmapButton_GotFocus); LostFocus+=new EventHandler(BitmapButton_LostFocus); MouseEnter+=new EventHandler(BitmapButton_MouseEnter); MouseLeave+=new EventHandler(BitmapButton_MouseLeave); KeyDown+=new KeyEventHandler(BitmapButton_KeyDown); KeyUp+=new KeyEventHandler(BitmapButton_KeyUp); EnabledChanged+=new EventHandler(BitmapButton_EnabledChanged);
| Paint | Responsible for painting the button in all its different states. |
| MouseDown | Transitions into the "Clicked" state. |
| MouseUp | Transitions into the "Has Focus" state. |
| GotFocus | Transitions into the "Has Focus" state (got focus through keyboard, for example) |
| LostFocus | Transitions into the "Button Up" or "Mouse Over" state. |
| MouseEnter | If in the "Button Up" state, transitions to the "Mouse Over" state. |
| MouseLeave | If in the "Mouse Over" state, transitions to the "Button Up" state. |
| KeyDown | Transitions to the "Clicked" state when the user presses the spacebar while the button has focus. |
| KeyUp | Transitions to the "Has Focus" state when the user releases the spacebar while the button has focus. |
| EnabledChanged | Transitions to the "Disabled" state or back to the "Button Up" state when the Enabled state of the button is changed. |
While double buffering is not required, since the entire state image is drawn on the surface of the button, it is implemented in case the control is enhanced to include additional drawing effects. Double buffering is specified with the SetStyle method, which is a protected member, because someone decided that, since the control will have its own Paint handler, it should not be settable without sub-classing the control. Never mind that the Paint event handler could be implemented in a completely separate class!
SetStyle(ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.DoubleBuffer, true);
The button image is displayed in the Paint event handler. Given the state, it determines the index of the requested image. The bitmap does not need to include all the image states, as long as the image states provided are contiguous (meaning, you can't have button up, button down, and disabled image states, leaving focused and mouse-over empty--if you want an image for the disabled state, then you have to provide images for all the other states as well). private void BitmapButton_Paint(object sender, PaintEventArgs e) { Graphics gr=e.Graphics; int indexWidth=Size.Width*(int)imgState; if (Image.Width > indexWidth) { gr.DrawImage(Image, 0, 0, new Rectangle(new Point(indexWidth, 0), Size), GraphicsUnit.Pixel); } else { gr.DrawImage(Image, 0, 0, new Rectangle(new Point(0, 0), new Size(Size.Width, Size.Height)), GraphicsUnit.Pixel); } }
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 2 Jul 2003 Editor: Marc Clifton |
Copyright 2003 by Marc Clifton Everything else Copyright © CodeProject, 1999-2009 Web13 | Advertise on the Code Project |