如何定制对话框系统菜单

背景

系统菜单是每个 Windows 程序的标准特性。通常系统菜单由 Windows 系统来管理,所以我们平时编成时很少去碰它。但是,有的时候,我们确实想定制自己的系统菜单项。这样就涉及到定制菜单的处理问题,因为 Windows 无法自动处理我们定制的系统菜单。而且,系统菜单的处理方式与常规的菜单处理是不同的。那么我们如何实现定制的系统菜单呢?相信看完本文的介绍,你会得到满意的答案。

本文例子是一个典型的C++/MFC对话框程序,设置了 EX_WM_TOOLWINDOW 扩展式样,因此在标题栏左上角看不到系统菜单图标,但通过 Ctrl+Space 或者在标题栏单击鼠标右键可以调出系统菜单。例子程序对系统菜单进行了定制,在原有菜单基础上添加了两个菜单命令:一个是显示“关于”对话框;另一个是“退出”。之所以要加一个“退出”菜单命令,是因为例子程序改写了对话框原来默认的“关闭”菜单命令行为(Alt-F4),用来隐藏对话框。因此必须加一个程序的“退出”出口。此外,例子程序利用一个第三方的系统托盘处理类,利用系统托盘图标可以显示/隐藏对话框。 下面我们就来看看用 C++/MFC 实现的细节。

添加菜单

首先在资源定义文件 resource.h 中定义菜单项标示,也可以在标准头文件中定义。菜单项标示必须具有唯一性。其次,Windows 对系统菜单的处理与常规菜单的处理方法是不同的,不管是缺省的菜单还是定制的菜单,它们都没有象常规菜单命令那样的消息处理例程。假设我们要添加两个定制的系统单:

#define IDM_ABOUT 16
#define IDM_EXIT 17

IDM_的意思是该定义为菜单项ID。添加菜单命令是在对话框的初始化例程以及窗口创建函数(OnInitDialog(), OnCreate())中进行的。如:BOOL CBabelOnDlg::OnInitDialog()
{
  CDialog::OnInitDialog();
// 在系统菜单中添加 "关于..." 和 "退出" 菜单项
// 解决 Windows 95 中的 bug
  ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
// 命令 IDs 必须在预定义的系统菜单之后
  ASSERT(IDM_ABOUTBOX < 0xF000);
// 解决 Windows 95 中的 bug
  ASSERT((IDM_EXIT & 0xFFF0) == IDM_EXIT);
// 命令 IDs 必须在预定义的系统菜单之后
  ASSERT(IDM_EXIT < 0xF000);
  CMenu* pSysMenu = GetSystemMenu(FALSE);
  if (pSysMenu != NULL)
  {
   pSysMenu->AppendMenu(MF_STRING,IDM_EXIT,"退出(&x)");
   pSysMenu->AppendMenu(MF_SEPARATOR);
   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, "关于(&A)...");
   ......
  }
  ......
  //other initialization
}

这里在添加每个菜单前都有两个 ASSERT 语句,第一个 ASSERT 的目的是修复 Windows 95 中存在的 Bug,第二个 ASSERT 保证定制的命令 IDs 是在预定义的系统菜单之后,以免发生冲突。查一下 MSDN 库的 MFC 文档关于系统菜单的描述,你会发现下面的内容:“......所有预定义的控制菜单项(也就是系统菜单)的ID号必须大于 0xF000。如果某个应用程序要添加系统菜单,其系统菜单的 ID 号必须小于F000。”

接下来,用 GetSystemMenu 函数获取系统菜单指针。调用时使用参数 FALSE 获取指针。如果用 TRUE 作为参数,那么该函数会将菜单重置回缺省状态。

如果得到的指针有效,接着调用菜单添加命令在系统菜单后面添加菜单项,传递菜单IDs以及菜单显示时所用的字符串。

时间: 2024-11-05 16:39:24

如何定制对话框系统菜单的相关文章

C++Builder定制系统菜单

通常在应用程序的主窗体中,利用鼠标左键点击左上角的图标,会弹出一个菜单,称之为"系统菜单". 在窗体中并没有系统菜单对应的组件,所以有时我们需要定制系统菜单时就比较麻烦.具体可以能过下面的步骤实现: .在系统菜单上添加所需的菜单项. .为新添加的菜单项定义OnClick事件的处理过程. 下面的例程中,在系统菜单中添加了一个"前端显示(A)"菜单项,通过该菜单项,可以使窗体始终显示在最前端或为普通窗体模式.具体实现过程如下: 1)通过菜单File|New Applic

浏览器扩展系列————在WPF中定制WebBrowser快捷菜单

原文:浏览器扩展系列----在WPF中定制WebBrowser快捷菜单 关于如何定制菜单可以参考codeproject上的这篇文章:http://www.codeproject.com/KB/books/0764549146_8.aspx?fid=13574&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=26#xx0xx 本文主要讲述如何在这篇文章中的ShowContextMenu方法中弹出自己的Conte

Windows 2008系统菜单的简单设置方法

相信许多人在与Windows Server 2008系统进行过一次"零距离"接触之后,都会对它的许多功能心动不已.这 不,在普通操作系统下看似十分平常的系统菜单或右键菜单,在Windows Server 2008系统环境下却能演绎出别样 的精彩.现在,本文就为各位朋友贡献几则Windows Server 2008系统环境下调教菜单的技巧,希望这些内容能对 大家有用! 挖掘右键菜单中的隐藏功能 在Windows Server 2008系统中,当我们用鼠标任意选中某一个文件夹,之后按下键盘

在系统菜单里添加菜单项和相应事件

有时候我们经常在程序中实现菜单项的重画,已有好多文章已经加以介绍,在此不再赘述.但是有时我们需要加新菜单项到系统菜单中,并希望给其增加相应的事件.笔者通过运用WindowAPI的AppendMenu函数和C++BUIDER的相关方法.属性,实现了往系统菜单中增加菜单项和事件. 下面介绍具体的实现方法,读者按照以下步骤操作,就可以实现在系统菜单中增加菜单项和事件: 1 首先创建一个新的空工程文件,存盘为project1.cpp和unit1.cpp. 2 使用菜单Tools中的Image Edito

Delphi为窗体的系统菜单中添加选项

通常在应用程序中,如果单击标题栏的左侧图标,就会弹出一个窗体的系统菜单,在其中可以完成最小化.最大化和关闭等操作.本实例将演示如何在窗体的系统菜单中添加自己的选项. 在窗体中添加一个TMainMenu组件,其中TMainMenu组件中的选项将要被添加到窗体的系统菜单中.添加组件后的窗体如图1所示. 图1 添加组件后的窗体 在TMainMenu组件生成的菜单中添加一个File菜单,在这个菜单下面添加一个Exit选项. 在本程序开始运行时就会把TMainMenu组件生成的菜单添加到窗体的系统菜单中,

[WPF疑难]如何禁用WPF窗口的系统菜单(SystemMenu)

点击窗口左上角图标时弹出来的菜单也就是这里所说的系统菜单(SystemMenu),有时需要禁用(移除)其中的某些或全部菜单项.刚才也有网友问到了这一点,OK,贴代码: 要全部禁用(移除)菜单项请调用SystemMenuManager.RemoveWindowSystemMenu(Window window)方法,想部分禁用(移除)菜单项则调用SystemMenuManager.RemoveWindowSystemMenuItem(Window window, int itemIndex)方法.

使用RadControls的RadMenu控件开发系统菜单

关于菜单这个话题我想应该是不讲则懂,所以本文不会多讲这些概念,则重关注RadControls控件中的RadMenu控件的使用,结合数据库来开 发一个系统菜单. 一.数据库设计 这里我就使用Access作为示例数据库,详细见下图: 开发系统菜单-radcontrols"> 表字段依次为:自动编号.菜单编码.菜单名称.请求地址.菜单上显示的图片地址.快捷键(RadMenu控件支持).菜单顺序.菜单级限. 是否为末级和父菜单编码. 整个设计中主要以菜单编码作为关联依据. 二.注册控件及使用控件皮

Swing中为文本组件定制统一的菜单

在很多软件中每个文本组件都有自定义的菜单,这个blogjava的编辑器就有这样的菜单如:Cut , Copy,Paste,Delete,Select All,在Swing中若也想在JTextField,JTextArea,JEditorPane,JTextPane等等这些组件中都提供如此自定义菜单的功能,每个都写继承类?或者加鼠标监听事件?但不管怎样弄都会实现效果,只不过这样动静很大,不好维护,今天在网上看到一个很是方便的方法. 大家都知道,Swing中所有的事件都是进入java.awt.Eve

对窗口的系统菜单(SystemMenu)的一些操作

有时候想禁用/移除/添加一些系统菜单项目,那么你可能会用到下面的API,以C#平台调用为例: [DllImport("User32.dll")] internal static extern IntPtr GetSystemMenu(IntPtr hWnd, Int32 bRevert); 该函数用于获取系统菜单句柄.hwnd参数是窗口句柄,表明你想要获取哪个窗口的系统菜单:bRevert ,bool值,如果为假,那么整个函数将返回原窗口的系统菜单的句柄拷贝:如果为真,则原窗口的系统菜