.NET中的自绘机制

2016-01-29 12:06 4 1 收藏

.NET中的自绘机制,.NET中的自绘机制

【 tulaoshi.com - C语言心得技巧 】

.NET中的自绘机制

原著:Dino Esposito

翻译:Abbey

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)


原文出处:MSDN Magazine Feb 2004(Cutting Edge)

原代码下载:CuttingEdge0402.exe (182KB)

  每次 Microsoft 推出象 Office 或者 Visual Studio 这样拳头产品的新版本时,都会推出一些新的特性,其中包括了新的菜单样式(Menu Style)。当新的菜单样式以各自的方式集成到成品中后,第三方的开发商便会掀起一阵模仿浪潮,利用一些定制控件和组件来仿效它。如果你正在使用这些产品,那么你惟有升级到新版本才能享受提供的新的特性。否则,你的应用程序将继续使用大约十年前随 Windows 95 上市时的那种 Windows 经典菜单用户界面。
  虽然 Microsoft 在其主要产品中定期更新菜单样式,但其可用来定制应用程序的菜单 API 却自 Windows 3.x 和 文件管理器以来一直没有发生太大的变化。从 Win16 平台开始,应用程序就已经可以有权自已绘制一个个的菜单项来实现自定义菜单。这种技术今天称作自绘(Owner-drawing),并已大量用于其它一些系统组件与控件上,包括列表框、按钮和组合框。

Figure 1 自绘控制示例
Figure 1 自绘控件

  自定义控件的绘图在 Win16 和 Win32 平台下是很无聊的事情。从功能上讲并不是特别复杂,但是代码的编写和维护着实令人讨厌。在本期栏目中,我将深入研究 .NET框架为窗口菜单提供的自绘机制。最终目的是创建一个自定义的组件——只要你将它拖放到某个 Windows 窗体的组件托盘(Component Tray)上,它就允许你按照给定的主题定制菜单的外观。作为例子,我将混合使用 Visual Studio.NET 和 Office 2003 的菜单样式。如 Figure 1 所示,一旦你理解了 .NET 中的自绘控件,那么你也能完成这个示例。

自定义菜单的显示
  在.NET框架中,与窗口菜单相关的类包括 MainMenu、ContextMenu 和 MenuItem,这些类都是从公共类——Menu 类派生而来 的。某个窗体的最顶层菜单总是一个 MainMenu 类实例。应用程序的菜单包括了一个弹出式菜单的列表,每个弹出式菜单又由若干个菜单项和子菜单组成。ContextMenu 类对应动态上下文菜单,应用程序中所有活动可见的对象都可以显示这样的一个菜单。 上下文菜单是一个独立的子菜单,并且没有办法与顶层菜单显示的其它子菜单区分开来。最后,MenuItem对象则对应在MainMenu 或者 ContextMenu 对象 内显示的某个独立的菜单项。总之,任何.NET框架下的菜单都是一个 MenuItem 对象集合——无论它在哪里、以及如何被显示。
  Win32平台下的自绘功能比较容易通过其 MenuItem 类为数不多的属性和事件来实现。如果你已是一位熟练的 Win32 程序员,你应该赏识.NET下自绘编程模型 的简捷与效率。如果你从未接触过 Win32的自绘控件,你将无法想象它会有多痛苦。再回到.NET的自绘菜单,只要你简单地把在 MenuItems 属性中找到的每一个MenuItem对象的 OwnerDraw 属性设置为真(TRUE)即可。此外,每个 MenuItem 对象都能处理一对事件-DrawItem 和 MeasureItem,它们 收集用于 Win32 平台的底层信息。下面的Visual Basic.NET 代码演示了如何将一个菜单项变成自绘菜单项。

Sub MakeItemOwnerDraw(ByVal item As MenuItem) item.OwnerDraw = True AddHandler item.DrawItem, AddressOf StdDrawItem AddHandler item.MeasureItem, AddressOf StdMeasureItem End Sub
  在绘制菜单之前,当菜单需要知道某个菜单项的大小时,便触发 MeasureItem 事件,当菜单需要绘制特定项目时,则触发 DrawItem 事件 。Windows 使菜单足够大以适应最大的菜单项。MeasureItem 事件处理函数根据给定的菜单字体大小计算并返回菜单项的文本大小,而 DrawItem 事件处理函数则将 某些菜单文本及其位图、花哨的背景,甚或是你想在菜单上显示的任何东西绘制在给定的Graphics对象上。

重写窗体菜单
  重写某个窗体菜单,使之更多彩、更直观的步骤很简单:只要设置每个 MenuItem 对象的OwnerDraw 属性为True,并为关键事件编写适当的事件处理函数。怎样 以最佳方式实现这些呢?你会选择从Menu或MainMenu类派生一个新的类吗?甚至创建一个新的组件与这些缺省的菜单

来源:http://www.tulaoshi.com/n/20160129/1484659.html

延伸阅读
本页内容 调试器 条件编译 跟踪和 TraceSwitch 断言 TraceListener — Listeners 正在侦听 ...
俗话说佛要金装、人要衣装,作软件的当然得要个好界面啦^_^。网上提供的控件自绘基本上是MFC或WTL封装好的类,对于不想用MFC的人来说是一无是处的,我可是WIN32API的坚决拥护者。因为MFC等也是用WIN32API封装起来的,学好了WIN32API,可以深入的了解WINDOWS内部的机制,编写出来的程序才能得到更好的优化。 下面分析一下自绘按钮的原...
环境:Microsoft .NET Framework SDK v1.1 OS:Windows Server 2003 中文版ASP.Net生成静态HTML页在Asp中实现的生成静态页用到的FileSystemObject对象!在.Net中涉及此类操作的是System.IO 以下是程序代码 注:此代码非原创!参考别人代码//生成HTML页 public static bool WriteFile(string strText,string strContent,string strAuthor) { string ...
本文对“组件”这个术语进行定义并提供特别是与组件编程相关的 .NET 框架编程概念的概述。虽然“组件”这个术语有多种含义,但在 .NET 框架中,组件是指实现 System.ComponentModel.IComponent 接口的一个类,或从实现该接口的类中直接或间接导出的类。 如果想要您的组件或控件在其他编程语言中可以使用,您必须以符合公共语言规范 (CLS) 的语...
标签: vb
By Steven Smith from aspalliance.com Yknow, theres this really cool library in .NET for dynamically creating images on the fly. However, this article has nothing to do with that, so if thats what youre looking for, stop now. What this article is about is very simple -- how to use a single line of code (via a compo...

经验教程

624

收藏

16
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部