当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 用C#实现office2003风格的菜单组件

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 用C#实现office2003风格的菜单组件


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 92 ::
收藏到网摘: n/a

用C#实现office2003风格的菜单组件

作者:阿才

下载源代码

参考原文:http://www.codeproject.com/cs/menu/MhOffice2003Menus.asp

简介
仅仅使用一行简单的程序,你就能够使你的Windows窗体的所有菜单和上下文菜单具有office2003的菜单外观。同样地,你也可以只用一行程序,就能为你的菜单加上漂亮的图标。本文实现的是一个具有该功能的组件。如果你想让你的菜单恢复原来的外观,也只须调用End方法即可。



组件的使用
要正确使用组件,必须先将你的组件加入到工具箱中。然后将该组件从工具箱中拖放放到form窗体中。这时会看到你的form的设计页中多出了一个名为OfficeMenus1的图标,说明已经将菜单组件加入到了form中。紧接着调用如下方法:

//开始显示office 2003菜单OfficeMenus1.Start( FormName ); 注:FormName为要改变菜单风格的窗口名称。
同样,你也可以通过调用如下方法终止菜单的office2003风格,使之回到原始外观:
// 改变菜单的外观风格到原始状态OfficeMenus1.End();
为菜单顶添加图标也很简单,只须为工程添加一个ImageList(图像列表控件),然后将OfficeMenu组件的ImageList属性更改为你添加的ImageList,使用如下代码实现:
// 为菜单添加图像// OfficeMenus.AddPicture( MenuItem MenuItemToAddPictureTo, int ImageIndex );OfficeMenus1.ImageList = imageList1;OfficeMenus1.AddPicture(menuItem2, 1);

可以看出,只须如此几行代码就能轻松让你的菜单实现office2003风格。

组件的实现方法及原理
组件由三个类实现,这三个类分别为OfficeMenus,MainMenuItemDrawing和MenuItemDrawing,都位于命名空间Dev4Arabs中。由于实现代码较长,所以在此只给出了组件实现的思路。
组件实现的第一步是从System.ComponentModel.Component类派生类OfficeMenus。定义如下:
public class OfficeMenus : System.ComponentModel.Component
然后在类中定义两静态变量:

//图像列表用来存储菜单中用到的图标
static ImageList _imageList;
// 存储图片细节的一个名称集合,NameValueCollection的详细说明请查阅MSDN,该类主要用来使每个菜单的句柄与每个图标形成一一对应的关系,以便后面绘制菜单顶的图标时快速地找到某个菜单所对应的图标。
static NameValueCollection picDetails = new NameValueCollection();
接下来定义公共接口方法start和End。
公共接口方法Start的实现原理如下:
public void Start(Form form){	先从Start传入的参数中获得该窗口的主菜单。接下来为每一个主菜单下的MenuItem添加MeasureItem事件	处理mainMenuItem_MeasureItem和DrawItem事件处理mainMenuItem_DrawItem,	将MenuItem的OwnerDraw属性设置为true,并使用InitMenuItem(Menu mi)方法对每个MenuItem应用改变。	然后再从form参数中获取该窗口的上下文菜单对象,对其调用InitMenuItem(Menu mi)应用改变。	最后循环查找窗口中包含的每个子控件的上下文菜单,对其应用改变。	System.Windows.Forms.MainMenu menu = form.Menu;	foreach ( MenuItem mi in menu.MenuItems )	{	mi.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(mainMenuItem_MeasureItem);	mi.DrawItem += new System.Windows.Forms.DrawItemEventHandler(mainMenuItem_DrawItem);	mi.OwnerDraw = true;	InitMenuItem(mi);	}	ContextMenu cmenu = form.ContextMenu;	if ( cmenu != null ) {InitMenuItem(cmenu);}	foreach ( Control c in form.Controls ) {	if ( c.ContextMenu != null )	InitMenuItem(c.ContextMenu);}	catch {}}

End方法与这类似,只须将InitMenuItem换为UninitMenuItem,这里就不再举出了。具体实现代码请到http://www.codeproject.com/cs/menu/MhOffice2003Menus.asp下载。
为每个菜单应用改变的InitMenuItem方法的实现如下:
private void InitMenuItem(Menu mi){循环查找mi中的每个MenuItem,为其添加MeasureItem事件处理menuItem_MeasureItem和DrawItem事件处理menuItem_DrawItem(注意,此处的事件处理方法名称与Start中对主菜单的事件处理方法名称不同),并将OwnerDraw属性设置为true。使用递归调用对每个查找到的MenuItem调用InitMenuItem方法,这样便可以对菜单项下的所有级别的子菜单项都应用到改变