Implement VS.NET or Office XP-style menu with C # and VB.NET
The god of the small gas 2001.08.18
3. "MenuItemStyle" interface and VS.NET style menu item
This Project will switch to the C # language. I think so: First define a unified interface (Interface), including the three cases of the ordinary menu, Office200, and the VS.NET style, including the drawseparator, painted menu background (DrawBackground ), Writing menu items (Draw GeneNutexT); ordinary, office2000 and vs.net implement this interface Drawxxx function according to different situations. Then inherit a subclass from MenuItem, two functions of the Overrides menu item as the second part: OnMeasureItem and OndrawItem, the Drawxxx function in the interface implemented above according to different styles can be called. Finally, I separated this part in a .cs file, compile it into a vsnet.Menu.dll, you only use using vsnet.Menu; then you can use ordinary menuitem as you like in the first part. In the Demo source code, you can also see that I define the class of iconMenuItem, which has a method: MenuItemCreator (VsNet.Menu.iconMenustyle Stype, String Stext, Bitmap BMP, System.EventHandler EH) can complete the MenuItem that generates needs. I would like to use resource files or put resources such as pictures in a specialized file, then by this class to get resource CreateMenuItem from the resource file or externally. But it is the first edition, you will see that I still use the original new bitmap () to take resources directly from the hard disk. When I saw it Show, I was very happy first, then I found that there were many improvements. I also need to spend a lot of mind to do a professional menu.
Ok, let's take a look at the main implementation code about the part of the VS.NET style menu item:
Public Class VsnetStyle: MenuItemStyledRawer
{
Static Color Bgcolor = Color.Fromargb (246, 246, 246);
Static color ibgcolor = color.fromargb (202, 202, 202);
Static Color Sbcolor = Color.Fromargb (173, 173, 209);
Static Color Sbbcolor = Color.Fromargb (0, 0, 128);
Static int textStart = 20;
Public Void Drawcheckmark (Graphics G, Rectangle Bounds, Bool SELECTED)
{
Controlpaint.drawmenuglyph (g, new rectangle (bounds.x 2, bounds.y 2, 14), menuglyph.checkmark;
}
Public Void Drawicon (Graphics G, Image Icon, Rectangle Bounds, Bool SELECTED, BOOL Enabled, Bool Ischecked)
{
IF (enabled)
{
IF (SELECTED)
{
ControlPaint.drawImageDisabled (G, Icon, Bounds.Left 2, Bounds.top 2, Color.Black);
g.drawimage (icon, Bounds.Left 1, Bounds.top 1);
}
Else
{
g.drawImage (icon, Bounds.Left 2, Bounds.top 2);
}
}
Else
Controlpaint.drawimagedisabled (g, icon, bounds.left 2, bounds.top 2, systemcolors.highlighttext);
}
Public Void Drawseparator (Graphics G, Rectangle Bounds)
{
Int y = bounds.y bounds.height / 2;
g.drawline (New Pen (SystemColors.control), Bounds.x SystemInformation.smalliconsize.width 7, Y, Bounds.x Bounds.Width - 2, Y);
}
Public Void DrawBackground (Graphics G, Rectangle Bounds, DrawItemState State, Bool TopLevel, Bool Hasicon)
{
Bool SELECTED = (State & DrawItemState.Selected> 0;
IF (STATE & DRAWITEMSTATE.HOTLIGHT> 0)))
{
IF (TopLevel && SELECTED)
{// Draw topLevel, SELECTED MENUITEM
G.FillRectangle (New Solidbrush (IBGColor), Bounds;
Controlpaint.drawborder3d (g, Bounds.wid, Bounds.top, Bounds.Width, Bounds.Height, Border3DStyle.flat, Border3Dside.top | Border3Dside.right | border3dside.right);
}
Else
{// Draw Menuitem, Selected or topLevel, Hotlighted
G.FillRectangle (New Solidbrush (Sbcolor), Bounds;
G. DrawRectangle (New Pen (sbbcolor), Bounds.x, Bounds.y, Bounds.Width - 1, Bounds.Height - 1);
}
}
Else
{
IF (! TopLevel)
{// Draw MenuItem, Unselected
G.FillRectangle (New Solidbrush (IBGColor), Bounds;
Bounds.x = systemInformation.smalliconsize.width 5;
Bounds.width - = systeminformation.smalliconsize.width 5;
G. FillRectangle (New Solidbrush (BGColor), Bounds;
}
Else
{
// Draw Toplevel, Unselected MenuItem
g.fillRectangle (Systembrushes.Menu, Bounds);
}
}
Public void DrawMenutext (Graphics G, Rectangle Bounds, String Text, String Shortcut, Bool Enabled, Bool TopLevel, DrawItemState State)
{
StringFormat stringFormat = new stringFormat ();
StringFormat.HotKeyPrefix = (State & DrawItemState.NoAccelerator)> 0)? HotkeyPrefix.Hide: HotKeyPrefix.Show;
INT textWidth = (int) (g.MeasureString (text, systeminformation.Menufont) .width;
INT X = TopLevel? Bounds.Left (Bounds.width - TextWidth) / 2: Bounds.Left TextStart;
INT Y = bounds.top 2;
Brush brush = NULL;
IF (! enabled)
Brush = new solidbrush (color.fromargb (120, systemcolors.menutext);
Else
Brush = new solidbrush (color.black);
g.drawstring (Text, SystemInformation.MenuFont, Brush, X, Y, StringFormat);
g.drawstring (Shortcut, SystemInformation.Menufont, Brush, Bounds.left 130, Bounds.top 2, StringFormat);
}
}
MenuItemStyledRawer is the public interface class, regardless of normal style, office2000 or VS.NET style to implement its own interface, including DrawCheckmark, Drawicon, DrawMenuteXT, DrawBackground, DrawSeparator, etc., you can implement various functions required for menu items . After completing this part, you can inherit a subclass from MenuItem to be processed as the second part. Look at the following code, specifically examine the familiar ONMeasureItem and OnDrawItem:
Protected Override Void OnMeasureItem (MeasureItem "e)
{
Base.onMeasureItem (e);
// make Shortcut text omitted this part of the code.
IF (Menustyle! = iconMenuStyle.standard)
{
IF (Text == "-")
{
E.ItemHeight = 8;
E.Itemwidth = 4;
Return;
}
Int textWidth = (int) (Text ShortcutText, SystemInformation.Menufont) .width);
E.ItemHeight = systeminformation.MenuHeiGHT;
IF (Parent == Parent.getmainMenu ())
E.Itemwidth = TextWidth - 5; // 5 is a Magic Numberelse
E.ItemWidth = Math.max (160, TextWidth 50);
}
}
IconMenuStyle.standard is an enum indicating that it is normal, office2000 or vs. Net style. This part is nothing different from our second part.
Protected Override Void OnDrawItem (DrawiteMeventargs E)
{
Base.ondrawItem (E);
Graphics g = E.Graphics;
Rectangle Bounds = E.BOUNDs;
Bool SELECTED = (E.State & DrawItemState.selected> 0;
Bool topLevel = (PARENT == Parent.getmainMenu ());
Bool Hasicon = icon! = NULL;
Style.drawBackground (G, Bounds, E.STATE, TOPLEVEL, Hasicon);
IF (Hasicon)
Style.drawicon (G, Icon, Bounds, SELECTED, Enabled, Checked);
Else
IF (checked)
Style.drawcheckmark (G, Bounds, SELECTED);
IF (Text == "-")
{
Style.drawseParetor (G, Bounds);
}
Else
{
Style.drawMenutext (G, Bounds, Text, Shortcuttext, Enabled, TopLevel, E.State);
}
}
The benefits of the MenuitemstyleDrawer interface we said are displayed here, and the whole process is simple, and the specific implementation code is not a lot. When this class is complete, the remaining is used, this part of the first part of the first part, you can declare the iConMenu type in a top-level menu item, which is the type of ICONMENU type, simple Code like this:
Private system.windows.Forms.MenuItem mitems1; system.drawing.bitmap bitmap1 = new bitmap (bmppathstr "open.bmp");
MItems1 = iMenuitem.MenuItemCreator (MenuStyle, "& Open", Bitmap1,
This mitem1 is a VS.NET style menu item. Specific processes and screenshots that can be viewed.