CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
IBM Rational 系统开发最佳实践工具包 WebSphere MQ 最佳实践 TOP 15
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  VCL组件开发及应用

动态彩色菜单(带图标)制作的问题?

楼主zyr76(Andy)2006-03-15 16:55:49 在 Delphi / VCL组件开发及应用 提问

各位大虾把我的下面的程序拷到unit1(新建一个Application,然后全部删除unit1单元内容,再拷贝,这也是为了大家节省点时间,呵呵)单元中调试一下,为什么主菜单(指的是显示在最前头的主菜单0,主菜单1……主菜单5等),没有响应我的N0DrawItem事件设置背景和字体大小等呢?而且只有主菜单5的一级子菜单和二级子菜单响应了我的N1DrawItem和N2DrawItem事件,这是为什么……,能不能帮忙看看,另外,如果要给每个菜单项(所有的,包括主菜单、一级子菜单和二级子菜单)添加一个图标,如何实现?请各位高手赐教,泻分100!  
   
  unit   Unit1;  
   
  interface  
   
  uses  
      Windows,   Messages,   SysUtils,   Variants,   Classes,   Graphics,   Controls,   Forms,  
      Dialogs,   Menus,   StdCtrls;  
   
  type  
      TForm1   =   class(TForm)  
          procedure   N0DrawItem(Sender:   TObject;   ACanvas:   TCanvas;   ARect:   TRect;  
              Selected:   Boolean);     //完绘成主菜单背景、字体颜色及制区域设置  
          procedure   N1DrawItem(Sender:   TObject;   ACanvas:   TCanvas;   ARect:   TRect;  
              Selected:   Boolean);     //完绘一级菜单背景、字体颜色及制区域设置  
          procedure   N2DrawItem(Sender:   TObject;   ACanvas:   TCanvas;   ARect:   TRect;  
              Selected:   Boolean);     //完绘二级菜单背景、字体颜色及制区域设置  
          procedure   FormCreate(Sender:   TObject);  
         
   
      private  
   
          objMenuItem,objSMenuItem,objSSMenuItem:TMenuItem;  
          objMainMenu:TMainMenu;  
   
          {MainMenu1:   TMainMenu;  
          M:   TMenuItem;   //主菜单  
          S1:TMenuItem;   //   一级子菜单  
          S2:TMenuItem;     //二级子菜单   }  
   
          {   Private   declarations   }  
      public  
          {   Public   declarations   }  
      end;  
   
  var  
      Form1:   TForm1;  
   
  implementation  
   
  {$R   *.dfm}  
   
  procedure   TForm1.N0DrawItem(Sender:   TObject;   ACanvas:   TCanvas;   ARect:   TRect;  
              Selected:   Boolean);  
  begin  
          ACanvas.Font.Color:=clRed;  
          ACanvas.Font.Size:=18;  
          if   Selected   then  
                  SetBkColor(ACanvas.Handle,clSkyBlue)  
          else  
                  SetBkColor(ACanvas.Handle,clWhite);  
          ACanvas.TextRect(ARect,ARect.Left,ARect.Top,(Sender   as   TMenuItem).Caption);  
  end;  
   
  procedure   TForm1.N1DrawItem(Sender:   TObject;   ACanvas:   TCanvas;  
      ARect:   TRect;   Selected:   Boolean);  
  begin  
          ACanvas.Font.Color:=clYellow;  
          ACanvas.Font.Size:=14;  
          if   Selected   then  
                  SetBkColor(ACanvas.Handle,clRed)         //设置选中时的背景色  
          else  
                  SetBkColor(ACanvas.Handle,clWhite);     //设置未选中时的背景色  
          ACanvas.TextRect(ARect,ARect.Left,ARect.Top,(Sender   as   TMenuItem).Caption);  
   
  end;  
   
  procedure   TForm1.N2DrawItem(Sender:   TObject;   ACanvas:   TCanvas;  
      ARect:   TRect;   Selected:   Boolean);  
  begin  
          ACanvas.Font.Color:=clLime;  
          ACanvas.Font.Size:=10;  
          if   Selected   then  
                  SetBkColor(ACanvas.Handle,clBlue)  
          else  
                  SetBkColor(ACanvas.Handle,clWhite);  
          ACanvas.TextRect(ARect,ARect.Left,ARect.Top,(Sender   as   TMenuItem).Caption);  
  end;  
   
  procedure   TForm1.FormCreate(Sender:   TObject);  
  var   i,j,k:Integer;  
  begin  
  objMainMenu:=TMainMenu.Create(self);  
  objMainMenu.AutoHotkeys:=maManual;  
  objMainMenu.OwnerDraw:=True;  
    for   i:=0   to   5   do  
    begin  
      objMenuItem:=TMenuItem.Create(self);  
      objMenuItem.Caption:='主菜单'+Inttostr(i);  
      objMenuItem.Name:='MenuE'+inttostr(i);  
      objMainMenu.Items.Add(objMenuItem);  
              for   j:=0   to   5   do  
        begin  
          objSMenuItem:=TMenuItem.Create(self);  
          objSMenuItem.Caption:='一级子菜单'+Inttostr(j);  
          objSMenuItem.Name:='SMenuEx'+Inttostr(i)+Inttostr(j);  
          objMainMenu.Items[i].add(objSMenuItem);  
              for   k:=0   to   5   do  
              begin  
              objSSMenuItem:=TMenuItem.Create(self);  
              objSSMenuItem.Caption:='二级子菜单'+inttostr(k);  
              objSSMenuItem.Name:='SSMenuExs'+Inttostr(i)+Inttostr(j)+Inttostr(k);  
                objMainMenu.Items[i].Items[j].add(objSSMenuItem);  
              end;  
        end;  
    end;  
   
        objMainMenu.Items.OnDrawItem:=   N0DrawItem;       //注意这句话不起作用,没有对主菜单进行相应设置,为什么?  
        for   i:=0   to   5   do  
        begin  
   
                objMenuItem.Items[i].OnDrawItem:=   N1DrawItem;  
                for   j:=0   to   5   do  
                      objMenuItem.Items[i].Items[j].OnDrawItem:=N2DrawItem;  
        end;  
                 
   
   
  end;  
   
   
   
  end. 问题点数:100、回复次数:22Top

1 楼jinjazz(近身剪)回复于 2006-03-15 17:02:26 得分 0

参考http://borland.mblogger.cn/jinjazz/posts/21287.aspxTop

2 楼zyr76(Andy)回复于 2006-03-15 17:16:15 得分 0

我已经参考过了,不过还没怎么弄明白,请问就这个问题怎么办?Top

3 楼zyr76(Andy)回复于 2006-03-16 09:44:28 得分 0

为什么没有人回答我呀,郁闷!请高手赐教吧Top

4 楼hahafan(注意!此人前途迷茫)回复于 2006-03-16 10:11:38 得分 100

添加DrawItem事件的方法不对,应该放在创建菜单的循环中  
  procedure   TForm1.FormCreate(Sender:   TObject);  
  var   i,j,k:Integer;  
  begin  
  objMainMenu:=TMainMenu.Create(self);  
  objMainMenu.AutoHotkeys:=maManual;  
  objMainMenu.OwnerDraw:=True;  
    for   i:=0   to   5   do  
    begin  
      objMenuItem:=TMenuItem.Create(self);  
      objMenuItem.Caption:='主菜单'+Inttostr(i);  
      objMenuItem.Name:='MenuE'+inttostr(i);  
      objMainMenu.Items.Add(objMenuItem);  
      objMenuItem.OnDrawItem   :=   N0DrawItem;     //一级菜单绘制  
              for   j:=0   to   5   do  
        begin  
          objSMenuItem:=TMenuItem.Create(self);  
          objSMenuItem.Caption:='一级子菜单'+Inttostr(j);  
          objSMenuItem.Name:='SMenuEx'+Inttostr(i)+Inttostr(j);  
          objMainMenu.Items[i].add(objSMenuItem);  
          objSMenuItem.OnDrawItem     :=   N1DrawItem;     //二级菜单绘制  
              for   k:=0   to   5   do  
              begin  
              objSSMenuItem:=TMenuItem.Create(self);  
              objSSMenuItem.Caption:='二级子菜单'+inttostr(k);  
              objSSMenuItem.Name:='SSMenuExs'+Inttostr(i)+Inttostr(j)+Inttostr(k);  
                objMainMenu.Items[i].Items[j].add(objSSMenuItem);  
              objSSMenuItem.OnDrawItem     :=   N2DrawItem;     //三级菜单绘制  
              end;  
        end;  
    end;  
   
  //       objMainMenu.Items.OnDrawItem:=   N0DrawItem;       //注意这句话不起作用,没有对主菜单进行相应设置,为什么?  
  //       for   i:=0   to   5   do  
  //       begin  
   
  //               objMenuItem.Items[i].OnDrawItem:=   N1DrawItem;  
  //               for   j:=0   to   5   do  
  //                     objMenuItem.Items[i].Items[j].OnDrawItem:=N2DrawItem;  
  //       end;  
                 
   
   
  end;  
  Top

5 楼zyr76(Andy)回复于 2006-03-21 09:38:18 得分 0

先感谢hahafan,此方法可行,再请教如果要改变菜单项的字体大小,并且在其前面加图标,怎么办?谢谢!,先给部分分,如何!Top

6 楼zyr76(Andy)回复于 2006-03-21 09:41:26 得分 0

hahafan,好像部分分给不了,您能否好人做到底,给我一个满意的答复,马上给分,也欢迎其他高手参与,同样给分,先谢了!Top

7 楼hahafan(注意!此人前途迷茫)回复于 2006-03-21 11:18:43 得分 0

图标可以在DrawItem画,比如你有个ImageList1,下面是给你的一级菜单画图标的方法:  
  procedure   TForm1.N0DrawItem(Sender:   TObject;   ACanvas:   TCanvas;   ARect:   TRect;  
              Selected:   Boolean);  
  begin  
          ACanvas.Font.Color:=clRed;  
          ACanvas.Font.Size:=18;  
          if   Selected   then  
                  SetBkColor(ACanvas.Handle,clSkyBlue)  
          else  
                  SetBkColor(ACanvas.Handle,clWhite);  
          ACanvas.TextRect(ARect,ARect.Left,ARect.Top,(Sender   as   TMenuItem).Caption);  
          ImageList1.Draw(ACanvas,   ARect.Left,   ARect.Top,0,   True);//画图标  
  end;  
  Top

8 楼zyr76(Andy)回复于 2006-03-28 09:21:16 得分 0

hahafan,我知道你是个高手,那就请问字体大小设置后,如何使菜单项适应其大小呢?这是最后一个问题了,答后马上给分!Thank   you   so   much……Top

9 楼hahafan(注意!此人前途迷茫)回复于 2006-03-28 10:42:22 得分 0

设置菜单大小可以在TMenuItem的OnMeasureItem中处理。  
  不过顶层菜单的高度可能会受限于标题栏的高度。Top

10 楼yq3woaini(哈哈镜 选择好心情)回复于 2006-03-28 21:59:52 得分 0

参看   raise控件的写法,里面都有Top

11 楼zyr76(Andy)回复于 2006-03-29 09:45:31 得分 0

不处理顶层菜单高度也可以,你能不能结合我的问题给个代码呢?raise控件在哪看呀?Top

12 楼hahafan(注意!此人前途迷茫)回复于 2006-03-29 11:02:54 得分 0

在创建菜单时把该方法赋给菜单的OnMeasureItem  
  procedure   TForm1.N1MeasureItem(Sender:   TObject;   ACanvas:   TCanvas;  
      var   Width,   Height:   Integer);  
  begin  
      ACanvas.Font.Size:=14;  
      Width   :=   ImageList1.Width   +   ACanvas.TextWidth(TMenuItem(Sender).Caption)   +   5;  
      Height   :=   Canvas.TextHeight(TMenuItem(Sender).Caption)   +   5;  
  end;  
  Top

13 楼yq3woaini(哈哈镜 选择好心情)回复于 2006-03-29 12:40:04 得分 0

2ccc.com  
  中国盟动力  
  下载一个看看里面有源代码Top

14 楼zyr76(Andy)回复于 2006-03-29 15:50:07 得分 0

hahafan,我试了一下你的方法,发现字体未变化(改变字体时),但菜单项的宽度有变化,为什么?另外,你的Width和Height参数代表菜单项的宽度和高度嘛?Top

15 楼hahafan(注意!此人前途迷茫)回复于 2006-03-29 17:28:43 得分 0

不太清除你说的是什么情况,能不能具体点或把代码贴出来看看。  
  Width和Height就是代表菜单的宽和高,就是通过设置他们来设置菜单大小。Top

16 楼reborter(www.xqblog.net我的博客)回复于 2006-03-29 20:54:18 得分 0

学习  
  Top

17 楼zyr76(Andy)回复于 2006-04-03 13:25:13 得分 0

hahafan,我按你的代码演示了一下,发现设置字体大小时(运行时字体大小不变)但菜单项的宽度有变化,为什么?代码如下:(新建一个APPLICATON后在FORM上添加IMAGELIST控件即可),下面的代码是Unit1单元代码:  
  -----------------------------------------  
  unit   Unit1;  
   
  interface  
   
  uses  
      Windows,   Messages,   SysUtils,   Variants,   Classes,   Graphics,   Controls,   Forms,  
      Dialogs,   Menus,   StdCtrls,   ImgList;  
   
  type  
      TForm1   =   class(TForm)  
          ImageList1:   TImageList;  
          procedure   N0DrawItem(Sender:   TObject;   ACanvas:   TCanvas;   ARect:   TRect;  
              Selected:   Boolean);     //完绘成主菜单背景、字体颜色及制区域设置  
          procedure   N1DrawItem(Sender:   TObject;   ACanvas:   TCanvas;   ARect:   TRect;  
              Selected:   Boolean);     //完绘一级菜单背景、字体颜色及制区域设置  
          procedure   N2DrawItem(Sender:   TObject;   ACanvas:   TCanvas;   ARect:   TRect;  
              Selected:   Boolean);     //完绘二级菜单背景、字体颜色及制区域设置  
        //   procedure   MenuMeasureItem(Sender:   TObject;   ACanvas:   TCanvas;   var   Width,   Height:   Integer);  
          procedure   N1MeasureItem(Sender:   TObject;   ACanvas:   TCanvas;  
              var   Width,   Height:   Integer);  
   
          procedure   FormCreate(Sender:   TObject);  
         
   
      private  
   
          objMenuItem,objSMenuItem,objSSMenuItem:TMenuItem;  
          objMainMenu:TMainMenu;  
   
          {MainMenu1:   TMainMenu;  
          M:   TMenuItem;   //主菜单  
          S1:TMenuItem;   //   一级子菜单  
          S2:TMenuItem;     //二级子菜单   }  
   
          {   Private   declarations   }  
      public  
          {   Public   declarations   }  
      end;  
   
  var  
      Form1:   TForm1;  
   
  implementation  
   
  {$R   *.dfm}  
  {procedure   TForm1.MenuMeasureItem(Sender:   TObject;   ACanvas:   TCanvas;   var   Width,   Height:   Integer);  
  begin  
          Height:=20;  
  end;   }  
  procedure   TForm1.N1MeasureItem(Sender:   TObject;   ACanvas:   TCanvas;  
      var   Width,   Height:   Integer);  
  begin  
      ACanvas.Font.Size:=14;   //修改字体大小可使菜单项宽度增加或减小,但运行时字体大小不变,为什么???  
      Width   :=   ImageList1.Width   +   ACanvas.TextWidth(TMenuItem(Sender).Caption)+   5   ;  
      Height   :=   Canvas.TextHeight(TMenuItem(Sender).Caption)+   5   ;  
  end;  
   
  procedure   TForm1.N0DrawItem(Sender:   TObject;   ACanvas:   TCanvas;   ARect:   TRect;  
              Selected:   Boolean);  
  begin  
          ACanvas.Font.Color:=clRed;  
          ACanvas.Font.Size:=12;  
          if   Selected   then  
                  SetBkColor(ACanvas.Handle,clSkyBlue)  
          else  
                  SetBkColor(ACanvas.Handle,clGray);  
          ACanvas.TextRect(ARect,ARect.Left,ARect.Top,(Sender   as   TMenuItem).Caption);  
          ImageList1.Draw(ACanvas,   ARect.Left,   ARect.Top,0,   true);//画图标  
  end;  
   
  procedure   TForm1.N1DrawItem(Sender:   TObject;   ACanvas:   TCanvas;  
      ARect:   TRect;   Selected:   Boolean);  
  begin  
          ACanvas.Font.Color:=clYellow;  
          ACanvas.Font.Size:=12;  
          if   Selected   then  
                  SetBkColor(ACanvas.Handle,clRed)         //设置选中时的背景色  
          else  
                  SetBkColor(ACanvas.Handle,clGray);     //设置未选中时的背景色  
          ACanvas.TextRect(ARect,ARect.Left,ARect.Top,(Sender   as   TMenuItem).Caption);  
          ImageList1.Draw(ACanvas,   ARect.Left,   ARect.Top,1,   true);//画图标  
  end;  
   
  procedure   TForm1.N2DrawItem(Sender:   TObject;   ACanvas:   TCanvas;  
      ARect:   TRect;   Selected:   Boolean);  
  begin  
          ACanvas.Font.Color:=clLime;  
          ACanvas.Font.Size:=12;  
          if   Selected   then  
                  SetBkColor(ACanvas.Handle,clBlue)  
          else  
                  SetBkColor(ACanvas.Handle,clGray);  
          ACanvas.TextRect(ARect,ARect.Left,ARect.Top,(Sender   as   TMenuItem).Caption);  
          ImageList1.Draw(ACanvas,   ARect.Left,   ARect.Top,2,   true);//画图标  
  end;  
   
  procedure   TForm1.FormCreate(Sender:   TObject);  
  var   i,j,k:Integer;  
  begin  
  objMainMenu:=TMainMenu.Create(self);  
  objMainMenu.AutoHotkeys:=maManual;  
  objMainMenu.OwnerDraw:=True;  
    for   i:=0   to   5   do  
    begin  
      objMenuItem:=TMenuItem.Create(self);  
      objMenuItem.Caption:='主菜单'+Inttostr(i);  
      objMenuItem.Name:='MenuE'+inttostr(i);  
      objMainMenu.Items.Add(objMenuItem);  
      objMenuItem.OnDrawItem   :=   N0DrawItem;   //主菜单单绘制  
      objMenuItem.OnMeasureItem:=N1MeasureItem;  
   
      //objMenuItem.OnMeasureItem:=MenuMeasureItem;  
              for   j:=0   to   5   do  
        begin  
          objSMenuItem:=TMenuItem.Create(self);  
          objSMenuItem.Caption:='一级子菜单'+Inttostr(j);  
          objSMenuItem.Name:='SMenuEx'+Inttostr(i)+Inttostr(j);  
          objMainMenu.Items[i].add(objSMenuItem);  
          objSMenuItem.OnDrawItem     :=   N1DrawItem;   //一级菜单绘制  
          objSMenuItem.OnMeasureItem:=N1MeasureItem;  
              for   k:=0   to   5   do  
              begin  
              objSSMenuItem:=TMenuItem.Create(self);  
              objSSMenuItem.Caption:='二级子菜单'+inttostr(k);  
              objSSMenuItem.Name:='SSMenuExs'+Inttostr(i)+Inttostr(j)+Inttostr(k);  
                objMainMenu.Items[i].Items[j].add(objSSMenuItem);  
                objSSMenuItem.OnDrawItem     :=   N2DrawItem;     //二级菜单绘制  
                objSSMenuItem.OnMeasureItem:=   N1MeasureItem;  
              end;  
        end;  
    end;  
   
   
   
  end;  
   
   
   
  end.Top

18 楼hahafan(注意!此人前途迷茫)回复于 2006-04-03 17:47:54 得分 0

MeasureItem设置字体大小是为了用来计算文字的长宽,对运行时字体大小没有影响,  
  设置运行时字体大小应该在DrawItem中,  
  所以你在MeasureItem设置字体大小同时应该在DrawItem也设置同样大小。Top

19 楼zyr76(Andy)回复于 2006-04-07 16:18:14 得分 0

hahafan,您好,请不要急,我会马上结贴了,但是,菜单的字体大了后,菜单项的高度又没变,导致菜单项有部分重叠现象,字体越大越明显,怎么设置来使菜单项的高度适应字体的变化?Top

20 楼hahafan(注意!此人前途迷茫)回复于 2006-04-07 17:02:26 得分 0

Height   :=   Canvas.TextHeight(TMenuItem(Sender).Caption)+   5;  
  不起作用?那改成下面试试:  
  Height   :=   Abs(ACanvas.Font.Height)   +   5;  
  Top

21 楼zyr76(Andy)回复于 2006-04-10 14:01:27 得分 0

hahafan,你好,你有没有电子邮件什么的,有机会再请教,先结贴,谢谢!Top

22 楼hahafan(注意!此人前途迷茫)回复于 2006-04-11 09:16:25 得分 0

hahafan1030@163.com  
  共同进步Top

相关问题

  • 求教关于真彩色图标菜单问题!
  • 菜单的图标
  • 动态菜单!
  • 菜单前面加图标。
  • 菜单前的图标????
  • 怎样给菜单项前加图标?
  • 如何产生带图标的菜单?
  • 如何在菜单中加入图标
  • 我怎样给POP菜单加图标??
  • 更改窗口(系统菜单)图标

关键词

  • 字体
  • acanvas
  • arect
  • 菜单
  • drawitem
  • tmenuitem
  • tcanvas
  • hahafan
  • objmenuitem
  • 菜单项

得分解答快速导航

  • 帖主:zyr76
  • hahafan

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo