首页 > 开发 > 综合 > 正文

用c#绘制Office2003样式的菜单

2024-07-21 02:18:29
字体:
来源:转载
供稿:网友
我的方法是重写menuitem类,在写的过程中发现用gdi+实际测量出来的文本的大小不是很准确,还有文本也不能很好对齐,固在代码里可以时常看到很多多加上去的数字.我想原理就不用我讲了吧,下面的代码注释的很
清楚了:
using system;
using system.drawing;
using system.drawing.drawing2d;
using system.windows.forms;
namespace officemenu
{
/// <summary>
/// class1 的摘要说明。
/// </summary>
public class officemenuitem:menuitem
{
public officemenuitem(bool isapplyofficemenu,string itemtext)
{
if(isapplyofficemenu)
{
this.text=itemtext;
this.ownerdraw=true;
font=new font("宋体",9f,graphicsunit.point);
}
else
{
this.text=itemtext;
this.ownerdraw=false;
}
}

private font font;
private stringformat strformat=new stringformat();
private string itemtext="";
private string iconpath="";

//定义绘制的时候的各种笔刷
private lineargradientbrush topmenuhostlightbrush;
private solidbrush topmenudefaultbrush;
private solidbrush fontdefaultbrush;
private lineargradientbrush topmenuselectedbrush;
private solidbrush menudefaultbrush;
private solidbrush menudefaultselectedbrush;
private solidbrush menucheckbrush;
private lineargradientbrush menusidebarbrush;
private solidbrush menudefaultgrayedbrush;
//定义绘制的时候所需的各种线条
private pen topmenupen;
private pen menudefaultpen;
//定义需要的矩形结构
private rectangle sidebarrect;
private rectangle checkedrect;
private rectangle topmenurect;
private rectangle shortcutrect;



//定义图标
public string iconpath
{
get
{
return iconpath;
}
set
{
iconpath=value;
}
}

//判断菜单是否是顶级菜单
private bool checkistop()
{
if(typeof(mainmenu)==this.parent.gettype())
{
return true;
}
else
{
return false;
}
}
//获取菜单的快捷键
private string getshortcut()
{
string shortcut="";
try
{
if(this.showshortcut==true && (!this.isparent) && (!(this.shortcut==shortcut.none)))
{
shortcut=this.shortcut.tostring();
shortcut=shortcut.replace("ctrl","ctrl+");
shortcut=shortcut.replace("alt","alt+");
shortcut=shortcut.replace("shift","shift+");
}
}
catch
{
return "";
}
return shortcut;
}
//重写测量函数
protected override void onmeasureitem(measureitemeventargs e)
{
base.onmeasureitem (e);

try
{
itemtext=this.text;
sizef sizemenutext;
if(this.itemtext=="-") //设置分割线的高度
{
e.itemheight=5;
return;
}

string getedshortcut=this.getshortcut();
if(!this.checkistop()) //如果不是顶级菜单
{
sizemenutext=e.graphics.measurestring(itemtext+"".padright(4,' ')+getedshortcut,this.font);
e.itemwidth=convert.toint32(sizemenutext.width)+26;
}
else
{
sizemenutext=e.graphics.measurestring(itemtext,this.font);
e.itemwidth=convert.toint32(sizemenutext.width)-4;
}
if(this.visible)
{
e.itemheight=convert.toint32(sizemenutext.height)+6;
}
else
{
e.itemheight=0;
}

}
catch
{
e.itemheight=20;
e.itemwidth=80;
}
}
//重写绘图函数
protected override void ondrawitem(drawitemeventargs e)
{
if(this.visible)
{
base.ondrawitem (e);
rectangle menurect=e.bounds;
itemtext=this.text;
graphics g=e.graphics;

//绘制边框时需要的特殊矩形
sidebarrect=new rectangle(menurect.x,menurect.y,25,menurect.height);
//绘制选择框时需要的矩形
checkedrect=new rectangle(menurect.x+1,menurect.y+1,24,menurect.height-2);
//绘制顶菜单时需要的矩形
topmenurect=new rectangle(menurect.x+1,menurect.y+3,menurect.width,menurect.height);
//绘制shortcut用到的矩形
shortcutrect=new rectangle(menurect.x,menurect.y+4,menurect.width-10,menurect.height);

//定义绘制的时候的各种笔刷
topmenuhostlightbrush=new lineargradientbrush(menurect,color.white,color.fromargb(220,134,56),90f); //顶级菜单发生hotlight 时显示的颜色
topmenudefaultbrush=new solidbrush(systemcolors.control); //顶级菜单默认的颜色
fontdefaultbrush=new solidbrush(color.black); //字体默认的颜色
topmenuselectedbrush=new lineargradientbrush(menurect,color.white,color.fromargb(95,109,126),90f); //顶级菜单选中时的颜色
menudefaultbrush=new solidbrush(color.white); //默认菜单的颜色
menudefaultselectedbrush=new solidbrush(color.fromargb(247,218,157)); //菜单选中时的颜色
menucheckbrush=new solidbrush(color.fromargb(225,143,70)); //当菜单checked属性为真的时显示的颜色
menusidebarbrush=new lineargradientbrush(sidebarrect,color.white,color.fromargb(149,160,174),0f);//绘制侧栏
menudefaultgrayedbrush=new solidbrush(color.fromargb(105,105,105));//菜单不可用时
//定义绘制的时候所需的各种线条
topmenupen=new pen(brushes.black,1f); //顶级菜单的边框
menudefaultpen=new pen(new solidbrush(color.fromargb(60,60,115)),1f); //正常选择时的边框

//开始绘制****************************************************
if(this.checkistop() && this.itemtext!="-") //如果是顶级菜单
{
bool isdraw=false;//定义一个变量保证正常显示的只绘制一次 避免浪费资源
strformat.alignment=stringalignment.center;
if(isdraw==false) //绘制正常显示时的图像
{
g.fillrectangle(topmenudefaultbrush,menurect);
g.drawstring(itemtext,this.font,fontdefaultbrush,topmenurect,strformat);
}

//绘制hotlight时的图像
if((e.state & drawitemstate.hotlight)==drawitemstate.hotlight) //突出显示时
{
g.fillrectangle(topmenuhostlightbrush,menurect);
g.drawrectangle(topmenupen,menurect.x,menurect.y,menurect.width-1,menurect.height-1);
g.drawstring(itemtext,this.font,fontdefaultbrush,topmenurect,strformat);
isdraw=true;
}
//绘制菜单选中时的图像
if((e.state & drawitemstate.selected)==drawitemstate.selected)
{
g.fillrectangle(topmenuselectedbrush,menurect);
g.drawrectangle(topmenupen,menurect.x,menurect.y,menurect.width-1,menurect.height-1);
g.drawstring(itemtext,this.font,fontdefaultbrush,topmenurect,strformat);
isdraw=true;
}
}
else //非顶级菜单时
{
if(this.itemtext!="-")
{
bool isdraw=false;
if(isdraw==false) //正常显示时
{
g.fillrectangle(menudefaultbrush,menurect);
g.fillrectangle(menusidebarbrush,menurect.x,menurect.y,25,menurect.height);
g.drawstring(itemtext,this.font,fontdefaultbrush,menurect.x+26,menurect.y+4);
//绘制shortcut
string shortcut=this.getshortcut();
strformat.alignment=stringalignment.far;
g.drawstring(shortcut,this.font,fontdefaultbrush,shortcutrect,strformat);
//绘制图标
this.drawicon(g);
}

if((e.state & drawitemstate.selected)==drawitemstate.selected) //选中时
{
this.drawitem_selected(g,menurect,itemtext);
isdraw=true;
}

if((e.state & drawitemstate.grayed)==drawitemstate.grayed) //不可用时
{
g.drawstring(itemtext,this.font,menudefaultgrayedbrush,menurect.x+26,menurect.y+4);
isdraw=true;
}

if(!this.isparent)
{
if((e.state & drawitemstate.checked)==drawitemstate.checked) //选择时
{
g.fillrectangle(menucheckbrush,checkedrect);
g.drawrectangle(new pen(brushes.black,1f),menurect.x+1,menurect.y+1,23,menurect.height-3);
g.drawstring("√",this.font,fontdefaultbrush,menurect.x+3,menurect.y+4);
isdraw=true;
}

if(this.checked==true && ((e.state & drawitemstate.selected)==drawitemstate.selected)) //选中且checked属性为真时
{
g.fillrectangle(new solidbrush(color.fromargb(255,91,91)),checkedrect);
g.drawrectangle(new pen(brushes.black,1f),menurect.x+1,menurect.y+1,23,menurect.height-3);
g.drawstring("√",this.font,fontdefaultbrush,menurect.x+3,menurect.y+4);
isdraw=true;
}
}
}
else //画分割线
{
solidbrush partitionlinebrush=new solidbrush(color.fromargb(128,128,128));
pen partitionpen=new pen(partitionlinebrush,1f);
g.fillrectangle(menudefaultbrush,menurect);
g.fillrectangle(menusidebarbrush,menurect.x,menurect.y,25,menurect.height);
g.drawline(partitionpen,new point(menurect.x+27,menurect.y+2),new point(menurect.x+27+(menurect.width-26),menurect.y+2));
}


}
}
}

//画图标
private void drawicon(graphics g)
{
if(this.checkistop()==false && this.iconpath!="" && this.isparent==false && this.checked==false)
{
try
{
bitmap iconimage=new bitmap(this.iconpath);
int imagewidth=iconimage.width;
int imageheight=iconimage.height;
if(imagewidth<=checkedrect.width && imageheight<=checkedrect.height)
{
int imagerecwidthmistake=checkedrect.width-imagewidth;
float mistake_2=(float)imagerecwidthmistake/2f;
g.drawimage(iconimage,checkedrect.x+(int)mistake_2,checkedrect.y,imagewidth,imageheight);
}
else
{
g.drawimage(iconimage,checkedrect);
}
}
catch
{
throw new iconnotfindexception("不能创建图标,可能是路径不能也可能是不支持此格式");
}
}
}
//由于再绘制的过程中选中的动作时需要执行两次一样的代码 固在这里用了一个函数
private void drawitem_selected(graphics g,rectangle rec,string itemtext)
{
solidbrush tmpbrush;
if(this.enabled)
{
tmpbrush=fontdefaultbrush;
}
else
{
tmpbrush=menudefaultgrayedbrush;
}

//正常显示
g.fillrectangle(menudefaultselectedbrush,rec);
g.drawrectangle(menudefaultpen,rec.x,rec.y,rec.width-1,rec.height-1);
g.drawstring(itemtext,this.font,tmpbrush,rec.x+26,rec.y+4);

//显示shortcut
string shortcut=this.getshortcut();
strformat.alignment=stringalignment.far;
g.drawstring(shortcut,this.font,tmpbrush,shortcutrect,strformat);
//画图标
this.drawicon(g);
}
}


//自定义异常
public class iconnotfindexception:applicationexception
{
public iconnotfindexception(string message)
:base(message)
{
}
}
}



商业源码热门下载www.html.org.cn

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表