C#编写.net风格的菜单。

juqiang 2002-01-31 05:35:09
//原创,随便copy,呵呵!

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace OwnerDrawMenu
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.MainMenu mainMenu1;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.MenuItem menuItem2;
private System.Windows.Forms.MenuItem menuItem3;
private System.Windows.Forms.MenuItem menuItem4;
private System.Windows.Forms.MenuItem menuItem5;
private System.Windows.Forms.MenuItem menuItem6;
private System.Windows.Forms.MenuItem menuItem7;
private System.Windows.Forms.MenuItem menuItem8;
private System.Windows.Forms.MenuItem menuItem9;
private System.Windows.Forms.ImageList imageList1;
private System.ComponentModel.IContainer components;

static Color bgcolor = Color.FromArgb(246, 246, 246);
static Color ibgcolor = Color.FromArgb(192,192,192);//Color.FromArgb(202, 202, 202);好似左面的图标底色
static Color sbcolor = Color.FromArgb(173, 173, 209); //蓝条
static Color sbbcolor = Color.FromArgb( 0, 0, 128);
private System.Windows.Forms.MenuItem menuItem10;
private System.Windows.Forms.MenuItem menuItem11;
private System.Windows.Forms.MenuItem menuItem12; //深蓝色

static int TEXTSTART = 24;

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call
//
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1));
this.mainMenu1 = new System.Windows.Forms.MainMenu();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.menuItem2 = new System.Windows.Forms.MenuItem();
this.menuItem3 = new System.Windows.Forms.MenuItem();
this.menuItem4 = new System.Windows.Forms.MenuItem();
this.menuItem5 = new System.Windows.Forms.MenuItem();
this.menuItem6 = new System.Windows.Forms.MenuItem();
this.menuItem7 = new System.Windows.Forms.MenuItem();
this.menuItem8 = new System.Windows.Forms.MenuItem();
this.menuItem9 = new System.Windows.Forms.MenuItem();
this.menuItem10 = new System.Windows.Forms.MenuItem();
this.menuItem11 = new System.Windows.Forms.MenuItem();
this.menuItem12 = new System.Windows.Forms.MenuItem();
this.imageList1 = new System.Windows.Forms.ImageList(this.components);
//
// mainMenu1
//
this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem1,
this.menuItem8,
this.menuItem10});
//
// menuItem1
//
this.menuItem1.Index = 0;
this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem2,
this.menuItem6,
this.menuItem7});
this.menuItem1.Text = "文件(&F)";
//
// menuItem2
//
this.menuItem2.Index = 0;
this.menuItem2.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem3,
this.menuItem4,
this.menuItem5});
this.menuItem2.Text = "新建(&N)";
//
// menuItem3
//
this.menuItem3.Index = 0;
this.menuItem3.MergeOrder = 1;
this.menuItem3.Shortcut = System.Windows.Forms.Shortcut.AltF4;
this.menuItem3.Text = "&1.文本文件";
//
// menuItem4
//
this.menuItem4.Checked = true;
this.menuItem4.Index = 1;
this.menuItem4.Shortcut = System.Windows.Forms.Shortcut.CtrlShiftH;
this.menuItem4.Text = "C#脚本";
//
// menuItem5
//
this.menuItem5.Index = 2;
this.menuItem5.Shortcut = System.Windows.Forms.Shortcut.F7;
this.menuItem5.Text = "ASP&X脚本";
//
// menuItem6
//
this.menuItem6.Index = 1;
this.menuItem6.Text = "-";
//
// menuItem7
//
this.menuItem7.Index = 2;
this.menuItem7.Text = "退出(&X)";
this.menuItem7.Click += new System.EventHandler(this.menuItem7_Click);
//
// menuItem8
//
this.menuItem8.Index = 1;
this.menuItem8.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem9});
this.menuItem8.Text = "帮助(&H)";
//
// menuItem9
//
this.menuItem9.Index = 0;
this.menuItem9.MergeOrder = 2;
this.menuItem9.Text = "关于(A)...";
//
// menuItem10
//
this.menuItem10.Index = 2;
this.menuItem10.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem11,
this.menuItem12});
this.menuItem10.Text = "编辑(&E)";
//
// menuItem11
//
this.menuItem11.Index = 0;
this.menuItem11.MergeOrder = 3;
this.menuItem11.Shortcut = System.Windows.Forms.Shortcut.CtrlZ;
this.menuItem11.Text = "取消";
//
// menuItem12
//
this.menuItem12.Index = 1;
this.menuItem12.MergeOrder = 4;
this.menuItem12.Text = "重做";
//
// imageList1
//
this.imageList1.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit;
this.imageList1.ImageSize = new System.Drawing.Size(16, 16);
this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Menu = this.mainMenu1;
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

public void DrawCheckmark(Graphics g, Rectangle bounds, bool selected)
{
// ControlPaint.DrawMenuGlyph(g, new Rectangle(bounds.X + 2, bounds.Y + 4, 14, 14), MenuGlyph.Checkmark);
Pen myPen1 = new Pen(Color.Black,2);
Pen myPen2 = new Pen(Color.Black,1);
g.DrawRectangle(myPen2,bounds.Left+1,bounds.Top+1,18,20);
g.DrawLine(myPen1,bounds.Left+8,bounds.Top+12,bounds.Left+12,bounds.Top+16);
g.DrawLine(myPen1,bounds.Left+12,bounds.Top+16,bounds.Left+16,bounds.Top+6);
myPen1.Dispose();
myPen2.Dispose();
}

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 + 4, Color.Black);
g.DrawImage(icon, bounds.Left + 1, bounds.Top + 3);
}
else
{
g.DrawImage(icon, bounds.Left + 2, bounds.Top + 4);
}
}
else
ControlPaint.DrawImageDisabled(g, icon, bounds.Left + 2, bounds.Top + 4, SystemColors.HighlightText);
}

public void DrawSeparator(Graphics g, Rectangle bounds)
{
int y = bounds.Y + bounds.Height / 2;
g.DrawLine(new Pen(SystemColors.ControlDark), 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 (selected || ((state & DrawItemState.HotLight) > 0))
{
if (toplevel && selected)
{ // draw toplevel, selected menuitem
g.FillRectangle(new SolidBrush(ibgcolor), bounds);
ControlPaint.DrawBorder3D(g, bounds.Left, bounds.Top, bounds.Width, bounds.Height, Border3DStyle.Flat, Border3DSide.Top | Border3DSide.Left | 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)
{
Text = state.ToString();
StringFormat stringformat = new StringFormat();
stringformat.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show;//((state & DrawItemState.NoAccelerator)==DrawItemState.NoAccelerator) ? System.Drawing.Text.HotkeyPrefix.Hide : System.Drawing.Text.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 + 6;
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, y, stringformat);
textwidth = (int)(g.MeasureString(shortcut, SystemInformation.MenuFont).Width);
g.DrawString(shortcut, SystemInformation.MenuFont, brush, bounds.Right - 20 - textwidth, y, stringformat);
}

private string GetShortcutName(MenuItem item)
{
string shortcut,ret = "";

shortcut = item.Shortcut.ToString();
if(shortcut.IndexOf("Alt")>=0)
{
ret = "Alt+" + shortcut.Substring(3);
}
else if(shortcut.IndexOf("CtrlShift")>=0)
{
ret = "Ctrl+Shift+" + shortcut.Substring(9);
}
else if(shortcut.IndexOf("Ctrl")>=0)
{
ret = "Ctrl+" + shortcut.Substring(4);
}
else if(shortcut.IndexOf("Shift")>=0)
{
ret = "Shift+" + shortcut.Substring(5);
}

return ret;
}
private void MenuDrawItemEvent(object sender,System.Windows.Forms.DrawItemEventArgs e)
{
MenuItem item = (MenuItem)sender;
string shortcut = GetShortcutName(item);
Graphics g = e.Graphics;
Rectangle bounds = e.Bounds;
bool selected = (e.State & DrawItemState.Selected) > 0;
bool toplevel = (item.Parent == item.Parent.GetMainMenu());
bool hasicon = (item.MergeOrder>0);

DrawBackground(g, bounds, e.State, toplevel, hasicon);
if (hasicon)
{
Bitmap myBmp = new Bitmap(imageList1.Images[item.MergeOrder - 1]);
DrawIcon(g, (Image)(myBmp), bounds, selected, item.Enabled, item.Checked);
}
else
{
if (item.Checked)
{
DrawCheckmark(g, bounds, selected);
}
}

if (item.Text == "-")
{
DrawSeparator(g,bounds);
}
else
{
DrawMenuText(g, bounds, item.Text, shortcut, Enabled, toplevel, e.State);
}


// if(e.State==DrawItemState.NoAccelerator)return;
/*
int menuHeight = e.Bounds.Height;
int menuWidth = e.Bounds.Width;
int menuLeft = e.Bounds.Left;
int menuTop = e.Bounds.Top;

try
{
//填充每个menuItem的背景颜色
SolidBrush brush = new SolidBrush(Color.LightSteelBlue);
//填充左面放Icon或者bmp图片的区域
SolidBrush myIconBrush = new SolidBrush(Color.LightGray);
//填充menuItem的背景颜色,为了重画用
SolidBrush myFillBrush = new SolidBrush(Color.White);
//写字用的颜色
SolidBrush myFontBrush = new SolidBrush(Color.Black);

//清除背景色
e.Graphics.FillRectangle(myFillBrush,menuLeft,menuTop,menuWidth,menuHeight);
//画背景色
e.Graphics.FillRectangle(myIconBrush,menuLeft,menuTop,menuLeft+24,menuHeight);

//调试时,查看menu的各种状态响应。
Text = e.State.ToString();

if(((e.State&DrawItemState.Selected)==DrawItemState.Selected) || ((e.State&DrawItemState.HotLight)==DrawItemState.HotLight))
{
//填充
e.Graphics.FillRectangle(brush,menuLeft+1,menuTop+1,menuWidth-1,menuHeight-1);
Pen pen = new Pen(Color.Black);
//画边
e.Graphics.DrawRectangle(pen,menuLeft,menuTop,menuWidth-1,menuHeight-1);
}
//图形索引使用MergeOrder,有其他好用的吗?
if(item.MergeOrder>0)
{
//画图
Bitmap myBmp = new Bitmap(imageList1.Images[item.MergeOrder - 1]);
e.Graphics.DrawImage((Image)myBmp,menuLeft+3,menuTop+4);
}
//可能需要分离&符号,进行特殊的font处理!!!
if(item.Text!="-")
{
//对于“&”,怎么处理?自己分离,然后分别DrawString吗?
StringFormat myFormat = new StringFormat();
myFormat.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show;
e.Graphics.DrawString(item.Text,Font,myFontBrush,26,menuTop+6,myFormat);
if(item.Shortcut.ToString().ToUpper()!="NONE")
{
// e.Graphics.DrawString(item.Shortcut.ToString(),SystemInformation.MenuFont,myFontBrush,menuLeft+130,menuTop+6);//,myFormat);
}
}
else
{
//画分割线seperator。这种背景下,应该不用下面的pen1了,看.net或者officeXP中,只有一个灰色
Pen pen1 = new Pen(Color.White);
Pen pen2 = new Pen(Color.Gray);
e.Graphics.DrawLine(pen2,26,menuTop+menuHeight/2,menuLeft+menuWidth,menuTop+menuHeight/2);
e.Graphics.DrawLine(pen1,26,menuTop+menuHeight/2+1,menuLeft+menuWidth,menuTop+menuHeight/2+1);
}
}
catch
{

}
*/
}

private void MenuMeasureItemEvent(object sender, System.Windows.Forms.MeasureItemEventArgs e)
{
MenuItem item = (MenuItem)sender;
string shortcut = GetShortcutName(item);
if (item.Text == "-")
{
e.ItemHeight = 4;
}
else
{
e.ItemHeight = SystemInformation.MenuHeight+4;
}
int textwidth = (int)(e.Graphics.MeasureString(Text + shortcut, SystemInformation.MenuFont).Width);
if (item.Parent == item.Parent.GetMainMenu())
e.ItemWidth = textwidth - 5; // 5 is a magic number
else
e.ItemWidth = Math.Max(160, textwidth + 50);
/*
MenuItem item = (MenuItem)sender;
if(item.Text=="-")
{
e.ItemHeight = 4;
}
else
{
e.ItemHeight = 24;//这个高度有标准高度吗?
}

System.Drawing.Font myFont = new Font("宋体",9);
System.Drawing.SizeF mySize = e.Graphics.MeasureString(item.Text,myFont);
e.ItemWidth = 30 + Convert.ToInt16(mySize.Width);//左面图标留20,右面的箭头留20
myFont.Dispose();*/
}

private void SetMenuProperty(MenuItem item)
{
//递归设置每个menuItem的OwnerDraw的event
try
{
foreach(MenuItem tmp in item.MenuItems)
{
tmp.OwnerDraw = true;
tmp.DrawItem += new System.Windows.Forms.DrawItemEventHandler(MenuDrawItemEvent);
tmp.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(MenuMeasureItemEvent);
SetMenuProperty(tmp);
}
}
catch
{

}
}

private void Form1_Load(object sender, System.EventArgs e)
{
try
{
MainMenu myMainMenu = this.Menu;
foreach(MenuItem myItem in myMainMenu.MenuItems)
{
//如果屏蔽下面三句,那么mainmenu将不进行重画,下面的subMenuitems进行重画。但是如果不屏蔽,主菜单显示的焦点框不正确,怎么这么小?!
// myItem.OwnerDraw = true;
// myItem.DrawItem += new System.Windows.Forms.DrawItemEventHandler(MenuDrawItemEvent);
// myItem.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(MenuMeasureItemEvent);
SetMenuProperty(myItem);
}
}
catch
{

}
}

private void menuItem7_Click(object sender, System.EventArgs e)
{
Close();
}

private void DrawIt(PaintEventArgs e)
{
System.Drawing.Graphics g = e.Graphics;
Color []myColor={ Color.FromArgb(0x7f,0xff,0x00,0x00),
Color.FromArgb(0x99,0x33,0x00),
Color.FromArgb(0xff,0x33,0x33,0x00),
Color.FromArgb(0xff,0x00,0x33,0x00),
Color.FromArgb(0xff,0x00,0x33,0x66),
Color.FromArgb(0xff,0x00,0x00,0x80),
Color.FromArgb(0xff,0x33,0x33,0x99),
Color.FromArgb(0xff,0x33,0x33,0x33),

Color.FromArgb(0x80,0x00,0x00),
Color.FromArgb(0xFF,0x66,0x00),
Color.FromArgb(0x80,0x80,0x00),
Color.FromArgb(0x00,0x80,0x00),
Color.FromArgb(0x00,0x80,0x80),
Color.FromArgb(0x00,0x00,0xFF),
Color.FromArgb(0x66,0x66,0x99),
Color.FromArgb(0x80,0x80,0x80),

Color.FromArgb(0xFF,0x00,0x00),
Color.FromArgb(0xFF,0x99,0x00),
Color.FromArgb(0x99,0xCC,0x00),
Color.FromArgb(0x33,0x99,0x66),
Color.FromArgb(0x33,0xCC,0xCC),
Color.FromArgb(0x33,0x66,0xFF),
Color.FromArgb(0x80,0x00,0x80),
Color.FromArgb(0x96,0x96,0x96),

Color.FromArgb(0xFF,0x00,0xFF),
Color.FromArgb(0xFF,0xCC,0x00),
Color.FromArgb(0xFF,0xFF,0x00),
Color.FromArgb(0x00,0xFF,0x00),
Color.FromArgb(0x00,0xFF,0xFF),
Color.FromArgb(0x00,0xCC,0xFF),
Color.FromArgb(0x99,0x33,0x66),
Color.FromArgb(0xC0,0xC0,0xC0),

// Color.FromArgb(0x00,0xFF,0x99,0xCC),
Color.FromArgb(0xff,0xff,0xff),
Color.FromArgb(0xff,0xFF,0xCC,0x99),
Color.FromArgb(0xff,0xFF,0xFF,0x99),
Color.FromArgb(0xff,0x80,0x80,0x80),
Color.FromArgb(0xff,0xCC,0xFF,0xFF),
Color.FromArgb(0xff,0x99,0xCC,0xFF),
Color.FromArgb(0xff,0xCC,0x99,0xFF),
Color.FromArgb(0xff,0xFF,0xFF,0xFF)
};


for(int i=0;i<5;i++)
{
for(int j=0;j<8;j++)
{
SolidBrush myBrush = new SolidBrush(myColor[5*i+j]);
g.FillRectangle(myBrush,20+20*j,20+20*i,12,12);
myBrush.Dispose();
}
}

for(int i=0;i<255;i++)
{
Pen myPen = new Pen(Color.FromArgb(i,0x00,0x00,0xff));
g.DrawLine(myPen,0,i,Width,i);
myPen.Dispose();
}
}

private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
DrawIt(e);
}
}
}
...全文
101 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
juqiang 2002-02-04
  • 打赏
  • 举报
回复
呵呵,真没什么说明。去年出差的时候,闲着没事,写的。代码很好懂啊!你新建立一个C#的工程,存盘后,把上面这段代码全部复制到你的.cs文件中。
DL_ZSW 2002-02-02
  • 打赏
  • 举报
回复
关注中...
klxyz 2002-02-01
  • 打赏
  • 举报
回复
关注!!:)
zhaixd 2002-02-01
  • 打赏
  • 举报
回复
请问 在有多级子菜单的情况下,如何更改右面箭头的颜色(不想要黑色的箭头)呢??偶想了很久了,不知道如何实现?
wu4long 2002-02-01
  • 打赏
  • 举报
回复
hello,给个文档说明吧。
jhnhu 2002-01-31
  • 打赏
  • 举报
回复
要源文,最好是E文的
看得头都晕了,也不讲是怎么做的,拷贝了也没用
看样子是自己画的,也不封装一下就拿来贴,谁这么有空一个一个画过去啊!
请给连接
wenzm 2002-01-31
  • 打赏
  • 举报
回复
就是XP风格菜单吧
那样这么复杂??
我也有一份代码——不是我写的。

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧