说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

利用delphi美化你的菜单

HTML文档下载 WORD文档下载 PDF文档下载
利用delphi美化你的菜单

windows下的很多程序都有十分漂亮的菜单,例如windows“开始”菜单左方从上到下的长条形的windows banner 又或者是向word那样在每一个菜单条左边都有一个小图标,看到这些很cool的菜单,你是否觉得自己的菜单显得单调乏味呢?不需要第三方控件,利用delphi就可以实现上面的功能。

如果要实现自定义菜单就需要在绘制菜单时改变菜单的大小以适应在菜单上绘制图形,然后再在上面绘制自己所需要的菜单效果。在delphi中,每一个菜单项对应一个tmenuitem控件,这类控件都有两个事件:ondrawitem和onmeasureitem,要实现自定义菜单,首先要介绍一下这两个事件:

onmeasureitem事件的定义如下:

type tmenumeasureitemevent = procedure (sender: tobject; acanvas: tcanvas;

var width

height: integer) of object;

property onmeasureitem: tmenumeasureitemevent;

该事件在菜单条监测自身的尺寸时产生,其中参数acanvas定义绘制的绘图对象,参数width、height制定菜单项的默认尺寸,注意到这两个定义前的var了吗,说明你可以在onmeasureitem事件处理函数中改变这两个值,也就是改变菜单的大小。

ondrawitem事件的定义如下:

type tmenudrawitemevent = procedure (sender: tobject; acanvas: tcanvas;

arect: trect; selected: boolean) of object;

property ondrawitem: tmenudrawitemevent;

该事件在菜单绘制时引发,其中参数acanvas定义菜单绘制对象,参数arect制定菜单的绘制区域,参数selected定义当前菜单项是否被选中。

从上面的介绍可以看到,要实现自定义的菜单,只要在onmeasureitem事件中编写代码改变菜单项的尺寸,然后在ondrawitem事件中绘制自己需要的效果就可以了。

下面我痛过具体的范例来做说明,这个范例是使自己的菜单实现象windows开始菜单一样的显示banner条的功能。同时这个程序还能实现对被选中的菜单条进行渐变色填充(就象3721中文网址软件的任务栏菜单那样)。程序的思路是这样的,首先建立一个长条型的位图,然后在每一个菜单条的onmeasureitem事件中根据要显示在菜单上的文本和图像以及程序的需要改变菜单项的宽度和高度,然后在ondrawitem事件中将位图中的相应部分拷贝到菜单项上。如果该菜单条被选中,首先要改变acanvas参数的画刷颜色,然后再依次填充菜单条上的相应部分,这样就实现了对选中的菜单条实现渐变色填充。最后将文本输出到菜单条上。

下面来介绍具体的程序,首先利用图像软件建立一个长条型的位图文件(你可以根据你的需要设定图像的高宽比,在我的图像中是10:1)。在delphi中建立一个新的工程,在form1中加入一个timage控件,将控件的autosize属性设置为true。然后在form1中加入一个tmainmenu控件,将它的ownerdraw属性设置为true(这一点很重要,否则程序无法实现)在该tmainmenu下加入6个tmenuitem对象(鼠标右健点击tmainmenu控件,然后点击弹出菜单的menu designer 项,就可以在设计窗口中添加菜单条了),将它们的name属性分别设置为 caption1、caption2、…、caption6。

下面是具体的程序清单:

unit ownermenu;

interface

uses

windows

messages

sysutils

classes

graphics

controls

forms

dialogs

menus

extctrls

stdctrls

imglist;

type

tform1 = class(tform)

mainmenu1: tmainmenu;

main1: tmenuitem;

caption1: tmenuitem;

caption2: tmenuitem;

caption3: tmenuitem;

caption4: tmenuitem;

caption5: tmenuitem;

caption6: tmenuitem;

image1: timage;

procedure caption1measureitem(sender: tobject; acanvas: tcanvas;

var width

height: integer);

procedure caption2measureitem(sender: tobject; acanvas: tcanvas;

var width

height: integer);

procedure caption3measureitem(sender: tobject; acanvas: tcanvas;

var width

height: integer);

procedure caption4measureitem(sender: tobject; acanvas: tcanvas;

var width

height: integer);

procedure caption5measureitem(sender: tobject; acanvas: tcanvas;

var width

height: integer);

procedure caption6measureitem(sender: tobject; acanvas: tcanvas;

var width

height: integer);

procedure caption1drawitem(sender: tobject; acanvas: tcanvas;

arect: trect; selected: boolean);

procedure caption2drawitem(sender: tobject; acanvas: tcanvas;

arect: trect; selected: boolean);

procedure caption3drawitem(sender: tobject; acanvas: tcanvas;

arect: trect; selected: boolean);

procedure caption4drawitem(sender: tobject; acanvas: tcanvas;

arect: trect; selected: boolean);

procedure caption5drawitem(sender: tobject; acanvas: tcanvas;

arect: trect; selected: boolean);

procedure caption6drawitem(sender: tobject; acanvas: tcanvas;

arect: trect; selected: boolean);

private

{ private declarations }

public

procedure drawitem(sender: tmenuitem; acanvas: tcanvas;arect: trect;

selected: boolean;strout:string);

{ public declarations }

end;

var

form1: tform1;

i

ih

ind

iw

irate:integer;

rtemp:trect;

ig1

ig2:integer;

implementation

{$r *.dfm}

procedure tform1.drawitem(sender: tmenuitem; acanvas: tcanvas;arect: trect;

selected: boolean;strout:string);

var

j:integer;

begin

i:=arect.bottom -arect.top; //获得贴图的高度和宽度

ind:=sender.menuindex;

ih:=round(image1.height/6*ind); //获得贴图位置

//将image上相应位置的位图复制到菜单上

stretchblt(acanvas.handle

arect.left

arect.top

iw

i

image1.canvas.handle

0

ih

image1.width

round(image1.height/6)

srccopy);

if selected then begin //该菜单项被选中

acanvas.font.color := clwhite;

rtemp:=arect;

rtemp.left := rtemp.left+iw;

ig1:=round((rtemp.right - rtemp.left)/10);

rtemp.right := rtemp.left +ig1;

for j:= 0 to 9 do begin //通过循环设置色彩渐变效果

acanvas.brush.color := rgb(0

0

j*25);

acanvas.fillrect(rtemp);

rtemp.left := rtemp.left +ig1;

rtemp.right := rtemp.left +ig1;

end;

end

else begin //该菜单项没有被选中

acanvas.brush.color := cl3dlight; //设置背景色为浅灰

rtemp:=arect;

rtemp.left := rtemp.left+iw;

acanvas.fillrect(rtemp);

acanvas.font.color := clblack;

end;

//设置canvas的画笔填充模式为透明

acanvas.brush.style:=bsclear;

//在菜单上输出文字

acanvas.textout(arect.left+iw+5

arect.top

strout);

end;

procedure tform1.caption1measureitem(sender: tobject; acanvas: tcanvas;

var width

height: integer);

begin

//在onmeasureitem事件中改变菜单的宽度和高度,下面5个程序同

//改变菜单的宽度和高度以容纳文本

height:=acanvas.textheight('caption1')+5;

width:=acanvas.textwidth('caption1')+5;

irate:=round(image1.height/(height*6));

iw:=round(image1.width /irate);

width:=width+iw; //根据计算改变菜单宽度以容纳附加的文本

end;

procedure tform1.caption2measureitem(sender: tobject; acanvas: tcanvas;

var width

height: integer);

begin

height:=acanvas.textheight('caption1')+5;

width:=acanvas.textwidth('caption1')+5;

irate:=round(image1.height/(height*6));

iw:=round(image1.width /irate);

width:=width+iw;

end;

procedure tform1.caption3measureitem(sender: tobject; acanvas: tcanvas;

var width

height: integer);

begin

height:=acanvas.textheight('caption1')+5;

width:=acanvas.textwidth('caption1')+5;

irate:=round(image1.height/(height*6));

iw:=round(image1.width /irate);

width:=width+iw;

end;

procedure tform1.caption4measureitem(sender: tobject; acanvas: tcanvas;

var width

height: integer);

begin

height:=acanvas.textheight('caption1')+5;

width:=acanvas.textwidth('caption1')+5;

irate:=round(image1.height/(height*6));

iw:=round(image1.width /irate);

width:=width+iw;

end;

procedure tform1.caption5measureitem(sender: tobject; acanvas: tcanvas;

var width

height: integer);

begin

height:=acanvas.textheight('caption1')+5;

width:=acanvas.textwidth('caption1')+5;

irate:=round(image1.height/(height*6));

iw:=round(image1.width /irate);

width:=width+iw;

end;

procedure tform1.caption6measureitem(sender: tobject; acanvas: tcanvas;

var width

height: integer);

begin

height:=acanvas.textheight('caption1')+5;

width:=acanvas.textwidth('caption1')+5;

irate:=round(image1.height/(height*6));

iw:=round(image1.width /irate);

width:=width+iw;

end;

procedure tform1.caption1drawitem(sender: tobject; acanvas: tcanvas;

arect: trect; selected: boolean);

begin

drawitem(tmenuitem(sender)

acanvas

arect

selected

'caption1');

end;

procedure tform1.caption2drawitem(sender: tobject; acanvas: tcanvas;

arect: trect; selected: boolean);

begin

drawitem(tmenuitem(sender)

acanvas

arect

selected

'caption2');

end;

procedure tform1.caption3drawitem(sender: tobject; acanvas: tcanvas;

arect: trect; selected: boolean);

begin

drawitem(tmenuitem(sender)

acanvas

arect

selected

'caption3');

end;

procedure tform1.caption4drawitem(sender: tobject; acanvas: tcanvas;

arect: trect; selected: boolean);

begin

drawitem(tmenuitem(sender)

acanvas

arect

selected

'caption4');

end;

procedure tform1.caption5drawitem(sender: tobject; acanvas: tcanvas;

arect: trect; selected: boolean);

begin

drawitem(tmenuitem(sender)

acanvas

arect

selected

'caption5');

end;

procedure tform1.caption6drawitem(sender: tobject; acanvas: tcanvas;

arect: trect; selected: boolean);

begin

drawitem(tmenuitem(sender)

acanvas

arect

selected

'caption6');

end;

end.

Neither user nor current process错误 ListView的右边滚动滑块启用方法 Live Wallpaper动态壁纸开发 控制软键盘显示和隐藏 设置Activity大小不再全屏原理 Android面试题,看看你基础如何? Android Canvas绘图抗锯齿解决方法 Android xliff和字符串资源 android.hardware.USB类介绍 Android开发经验谈之应用间数据共享 android_asset这个URL详细使用方法 Android 2.3系统自带高清UI图标下载 设置ScrollView滚动条的颜色 WakeLock使用方法示例代码 Concurrent并发库常见问题总结 Android数据库SQLite性能优化技巧 Android开发之Java设计模式基础篇 Android开发之Java设计模式入门篇 Android开发之Java设计模式 Android开发之Java并发包集合类性能分析 Android开发之Java集合类性能分析 Android开发之Java虚拟机原理和内存分配 Android开发之Java基础系列教程目录 Android Theme主题样式开发注意点 Android 3.0开发用的平板推荐 android.resource://这个Uri你知道吗 ADT插件的10.0.1必须要Eclipse 3.5才能升级 Android线程优先级设置方法 Android Zip文件解压缩代码 Android开发之设置断点单步调试 Android裁剪图片最简单方法 那里有vs.net2003的vss6.0d版本? 有时候exe文件不能运行? 自己准备写一个工资发放和发布的程序,欢迎探讨. 襄儿妹妹还在吗?幸好偶这个马甲还有点分,全给你吧,这个ID密码她不知道呵呵~~~ 关于linux WEB服务器名的问题? 请教ATL中CBindStatusCallback的问题 我的IE不能打开新窗口?用鼠标左键点击超链接没有反应? 我的项目改变目录后打不开,怎么办? 多CPU机器,同时可有几个线程处于运行状态? 高分求高效高斯模糊算法。。 如何判断软件是否过期 是不是运行ASP.Net应用的服务器必须安装.Net FrameWork呢?还是只要有Win2000 Server和IIS就行。 谈情说爱 清除内存中用call调用的脚本文件? 一个很老的问题,如何避免CListCtrl闪烁。 请大家给看看程序:avi视频读取和重建 研究数字图像处理应该那些知识? 图片上传并显示实例(VB+SqlServer2000) SQL语言中 怎样将CHAR型转换成INT型? 級連更新... 怎么实现回车自动跳到下一个位置 如何在光标处插入字符? CSSCLASS高手关注,我想把ListBox、DropDownList样式改为平面,而且颜色边框为1颜色不为灰色,用CssClass具体怎么写呢?越详细越好?多谢 求一招:::怎么对付那些那了代码就不给钱的家伙???? =========发誓:远离csdn!================ phpmyadmin为何安装不成功? 谁有crystal reports的电子书。 这个radio的返回值是什么? 离开csdn,公布密码!!!!!!!!! 新手!求界面问题的答案! javascript面相对象的编程 IMail邮件系统的问题 七月七,我不在她身旁. 可是很想她.我爱她. 高分!求一简单问题。 今天七月七了,代表所有单身人员向全体女单身同胞问好,同时也祝成双成对的人永远快乐!! 请问php中二维数组怎么定义和初始化? 难题---SQL Panel2.Width/2;应该怎样改 求: Rational XDE 2003 (带破解的),分不够可以再加,要多少给多少,很急! 这个存储过程怎样调用? 在有限区域中打印文本,文本长度若超出,则压缩间距,否则正常显示 急,高手请进! 如何重新加载select? 怎样做一个网页编辑器(windows form)大家给个思路 强烈建议 删除 {{轰动上海大学的偷拍事件录像下载地址 (yy795188 ) }}的贴子,否则版主失职 用Authorware能够作出象隐藏在框架里的菜单吗? 我的程序需要定期执行一次,怎么写呢? 请各位大侠帮忙分析分析,我大概还有300分的可用分,解决的话,全送你了(300分) 日历 这是Mysql的BUG吗--彬、斌--如何分别查询 如何利用XML中的xsl进行信息的交换 把一个圆柱的侧面及展开得到一个正方形,正方形的周长是25.12厘米.表面积是多少, 世界一点也不稀奇的阅读答案 世界一点也不稀奇阅读答案 杨康到底是被谁杀死的?是怎么死的 求南方出版社《优化设计》化学必修一第一章第三节第一课时(摩尔质量和气体摩尔体积)答案 杨康到底怎么死的08版《射雕英雄传》是被欧阳锋杀死的,而刘亦菲版的《神雕侠侣》却说是被郭靖杀死的,而以往的《射雕英雄传》说是他打黄蓉时中蛇毒而死,究竟哪个最为准确? 演讲有什么特点? 负1是奇数吗? 请问有没有近年来水产大事件的总结? 我们与周围环境的调查表 高中与朋友分在一个班的几率大吗 杭州市中级法院招聘速录员属事业编制2013全国中小城市百强县市公布 义三星向中国消费者道歉 7款问题机型延俄媒议论“中国反腐经验” 称中国采取沙特再拒入“非常” 美否认与沙特关系韩要求日删除主张独岛主权视频伊朗绞不死的囚犯被免再行刑默克尔电话疑遭美安全机构窃听 致电奥奥巴马与默克尔通电话 否认情报机构窃韩国特种部队美国加州跳伞宣传独岛 (尼泊尔“世界最矮的人”的生活 (组图塔国总统拉赫蒙感谢特变电工成功建设沙伊犁号货运班列开行俄罗斯 新疆西行国乌鲁木齐市交警详解电子警察抓拍原理 沪指昨日缩量跳水,再失3400点新疆库尔勒一市民捡到中奖“会员卡”不老知青忆:下乡时住进新房 房顶上面有梦魇,梦魇,你赶快走吧,今天又是一个小斯:热火会让我出战重要比赛长文|疯子遇见佛陀:小河的“音乐肖像哈勒尔:我会模仿法里德的打法20151027唐师曾:八一学校 讲
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘