首页 > 其他分享 >如何触发OnDrawItem事件?

如何触发OnDrawItem事件?

时间:2022-11-13 09:22:22浏览次数:38  
标签:ami 触发 strfmt Text 事件 MenuItem new OnDrawItem diea

OnDrawItem: WM_DRAWITEM

 子控件有自画属性且控件需重画时,父窗口会调用该函数

  在具有Owner Draw属性的控件需要重画的时候,就会激发OnDrawItem

以上引用自:https://m.tsingfun.com/it/cpp/1460.html

----------------------------------------------------------------------------------------------------------

下面通过实例来理解一下

 

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Drawing;
  6 using System.Windows.Forms;
  7 using System.Drawing.Text;
  8 
  9 namespace OwnerDrawMenu
 10 {
 11     class OwnerDrawMenu:Form
 12     {
 13         const int iFontPointSize = 18;  //用于菜单项目
 14         MenuItem miFacename;
 15 
 16         static void Main(string[] args)
 17         {
 18             Application.Run(new OwnerDrawMenu());
 19         }
 20         public OwnerDrawMenu()
 21         {
 22             Text = "Owner Draw Menu";
 23 
 24             //Top Level items
 25             Menu = new MainMenu();
 26             Menu.MenuItems.Add("&Facename");
 27 
 28             //子菜单项的内容
 29             string[] astrText = { "&Times New Roman","&Arial","&Courier New"};
 30             MenuItem[] ami = new MenuItem[astrText.Length];
 31 
 32             EventHandler ehOnClick = new EventHandler(MenuFacenameOnClick);
 33             MeasureItemEventHandler ehOnMeasureItem =
 34                 new MeasureItemEventHandler(MenuFacenameOnMeasureItem);
 35             DrawItemEventHandler ehOnDrawItem =
 36                 new DrawItemEventHandler(MenuFacenameOnDrawItem);
 37 
 38             for (int i = 0; i < ami.Length; i++)
 39             {
 40                 ami[i] = new MenuItem(astrText[i]);
 41                 //ami[i].OwnerDraw = true;
 42                 ami[i].RadioCheck = true;
 43                 ami[i].Click += ehOnClick;
 44                 ami[i].MeasureItem += ehOnMeasureItem;
 45                 ami[i].DrawItem += ehOnDrawItem;
 46             }
 47             miFacename = ami[0];
 48             miFacename.Checked = true;
 49 
 50             Menu.MenuItems[0].MenuItems.AddRange(ami);
 51         }
 52 
 53         void MenuFacenameOnClick(object obj, EventArgs ea)
 54         {
 55             miFacename.Checked = false;
 56             miFacename = (MenuItem)obj;
 57             miFacename.Checked = true;
 58 
 59             Invalidate();
 60         }
 61 
 62         void MenuFacenameOnMeasureItem(object obj, MeasureItemEventArgs miea)
 63         {
 64             MenuItem mi = (MenuItem)obj;
 65             Font font = new Font(mi.Text.Substring(1),iFontPointSize);
 66 
 67             StringFormat strfmt = new StringFormat();
 68             strfmt.HotkeyPrefix = HotkeyPrefix.Show;
 69 
 70             SizeF sizef = miea.Graphics.MeasureString(mi.Text,font,1000,strfmt);
 71 
 72             miea.ItemWidth = (int)Math.Ceiling(sizef.Width);
 73             miea.ItemHeight = (int)Math.Ceiling(sizef.Height);
 74 
 75             miea.ItemWidth += SystemInformation.MenuCheckSize.Width * 
 76                                 miea.ItemHeight / 
 77                                     SystemInformation.MenuCheckSize.Height;
 78             miea.ItemWidth -= SystemInformation.MenuCheckSize.Width;
 79         }
 80 
 81         void MenuFacenameOnDrawItem(object obj, DrawItemEventArgs diea)
 82         {
 83             MenuItem mi = (MenuItem)obj;
 84             Graphics grfx = diea.Graphics;
 85             Brush brush;
 86 
 87             //创建字体和格式
 88             Font font = new Font(mi.Text.Substring(1),iFontPointSize);
 89             StringFormat strfmt = new StringFormat();
 90             strfmt.HotkeyPrefix = HotkeyPrefix.Show;
 91 
 92             //计算选择标记和文字矩形
 93             Rectangle rectCheck = diea.Bounds;
 94 
 95             rectCheck.Width = SystemInformation.MenuCheckSize.Width * rectCheck.Height / SystemInformation.MenuCheckSize.Height;
 96             Rectangle rectText = diea.Bounds;
 97             rectText.X += rectCheck.Width;
 98 
 99             //绘制
100             diea.DrawBackground();
101             if ((diea.State & DrawItemState.Checked) != 0)
102                  ControlPaint.DrawMenuGlyph(grfx,rectCheck,MenuGlyph.Arrow);   //此行代码为绘制菜单前的三角形“箭头”
103 
104             //测试diea.state
105             Console.WriteLine("对应的菜单 is {0}",obj.ToString());
106             Console.WriteLine("(diea.State & DrawItemState.Checked) is {0}", (diea.State & DrawItemState.Checked));
107             
108             if ((diea.State & DrawItemState.Checked) != 0)
109             
110                 brush = new SolidBrush(Color.Red);              //如果选中菜单的某一项内容,则此项内容的文字就变为红色;
111             else
112                 brush = new SolidBrush(Color.Yellow);           //未选中的其它菜单项内容,其文字就为黄色;
113 
114             grfx.DrawString(mi.Text,font,brush,rectText,strfmt);
115         }
116 
117         protected override void OnPaint(PaintEventArgs pea)
118         {
119             Graphics grfx = pea.Graphics;
120             Font font = new Font(miFacename.Text.Substring(1),12);
121             StringFormat strfmt = new StringFormat();
122             strfmt.Alignment = strfmt.LineAlignment = StringAlignment.Center;
123 
124             grfx.DrawString(Text,font,new SolidBrush(ForeColor),0,0);
125         }
126     }
127 }

 

本次代码注释掉了第41行//ami[i].OwnerDraw = true;

运行代码,效果如下:

 

从上面的运行结果可以看到,菜单使用的是系统自带的菜单格式与字体,字体也没有颜色显示;

使用调试程序,也可以看到,程序没有进入MenuFacenameOnDrawItem函数,也就是说没有激发OnDrawItem事件。

 

标签:ami,触发,strfmt,Text,事件,MenuItem,new,OnDrawItem,diea
From: https://www.cnblogs.com/chenlight/p/16885411.html

相关文章

  • 事件查看器
    事件查看器日志位置:%SystemRoot%\System32\Winevt\Logs\Windows的事件查看器可以查看各种日志,对应的可执行程序是eventvwr.exe。相应的命令行工具为wevtutil.exe,功......
  • 【Azure 事件中心】 org.slf4j.Logger 收集 Event Hub SDK(Java) 输出日志并以文件形
    问题描述在使用AzureEventHub的SDK时候,常规情况下,发现示例代码中并没有SDK内部的日志输出。因为在Java项目中,没有添加SLF4J依赖,已致于在启动时候有如下提示:SLF4J:Fa......
  • 事件在 react 中的处理方式?(必会)
    事件在react中的处理方式?(必会)点击查看代码React元素的事件处理和DOM元素类似,但有一点语法上的不同:React事件绑定属性的命名采用驼峰式写法,而不是小写如果采用JSX的......
  • 一文学会JavaScript计时事件
    文章目录​​JavaScript计时事件​​​​setInterval()方法​​​​clearInterval()方法​​​​setTimeout()方法​​​​clearTimeout()方法​​JavaScript计时事件......
  • Android 点击触发音效
    还是以那个木鱼举例吧点击木鱼(ImageButton),发出敲击声首先准备一段音频,muyu.mp3,在res文件夹下新建一个资源文件夹raw,将muyu.mp3扔进去  然后新建一个类用来播放音......
  • windows socket网络编程--事件选择模型
    目录事件选择模型概述API详解工作原理代码实现事件选择模型概述Winsock提供了另一种有用的异步事件通知I/O模型——WSAEventSelect模型。这个模型与WSAAsyncSelect模型类......
  • sql触发器(insert,update,delete)
    --insert触发器createtriggertri_insertonstudent  --将要进行更改的表名forinsert  --给表插入一条数据的时候触发asdeclare@student_idchar(10) --定义一个......
  • 【MySQL(二十一)】binlog 事件
    binlog时机事务提交时写入binlog,但是binlog持久化到磁盘与sync_binlog参数有关:0:只fwrite写入操作系统cache,由操作系统决定什么时候持久化到磁盘,及fsync;1:fsync直接写入磁盘;n:......
  • 自定义顶部标题栏和其事件监听设置
    iOS系统上方的工具栏很漂亮,也很实用,下面让我们来仿制一下吧。首先新建一个布局文件title.xml:<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://......
  • 事件溯源
    PS:原创文章,如需转载,请注明出处,谢谢!   ​ 前几天团队内做了DDD如何有效指导拆分微服务的分享,中间关于微服务集成提到了“事件溯源”,今天就此做下整理。 1、关于事件......