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

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

                                                              周银辉

 

有时候想禁用/移除/添加一些系统菜单项目,那么你可能会用到下面的API,以C#平台调用为例:

[DllImport("User32.dll")]
internal static extern IntPtr GetSystemMenu(IntPtr hWnd, Int32 bRevert); 

该函数用于获取系统菜单句柄。hwnd参数是窗口句柄,表明你想要获取哪个窗口的系统菜单;bRevert ,bool值,如果为假,那么整个函数将返回原窗口的系统菜单的句柄拷贝;如果为真,则原窗口的系统菜单将被重置,函数将返回0,很显然这个函数就演变成“重置窗口系统菜单”了。

 

[DllImport("User32.dll")]
internal static extern int GetMenuItemCount(IntPtr hMenu);

该函数用于获取系系统菜单中的Item数目, hMenu为系统菜单句柄

 

[DllImport("User32.dll")]
internal static extern bool EnableMenuItem(IntPtr hMenu, Int32 uIDEnableItem, Int32 uEnable);

该函数用于启用或禁用系统菜单。hMenu为菜单句柄。uIDEnableItem表示操作项的Id或位置等(具体的取决与第三个参数)。uEnable,一些标志它可以是:

internal const UInt32 MF_ENABLED      =0x00000000;
internal const UInt32 MF_GRAYED       =0x00000001;
internal const UInt32 MF_DISABLED     =0x00000002;
internal const UInt32 MF_BYCOMMAND    =0x00000000;
internal const UInt32 MF_BYPOSITION   =0x00000400;

如果uEnable是MF_BYPOSITION则uIDEnableItem应该传入Index信息(0,1.....),如果是MF_BYCOMMAND则应该传入Id

 

[DllImport("user32.dll",CharSet=CharSet.Auto)]
 internal static extern int AppendMenu(int hMenu, int Flagsw, int IDNewItem, string lpNewItem);

该换上用于在系统菜单中追加项目。hMenu为菜单句柄,IDNewItem参数需要你为新添加的Item创建的ID,lpNewItem则是菜单文本,而嘛则是一些标志:

Flagsw
/*
下列标志可被设置在参数uFlags里:
  MF_BITMAP:将一个位图用作菜单项。参数lpNewltem里含有该位图的句柄。
  MF_CHECKED:在菜单项旁边放置一个选取标记。如果应用程序提供一个选取标记,位图(参见SetMenultemBitmaps),则将选取标记位图放置在菜单项旁边。
  MF_DISABLED:使菜单项无效,使该项不能被选择,但不使菜单项变灰。
  MF_ENABLED:使菜单项有效,使该项能被选择,并使其从变灰的状态恢复。
  MF_GRAYED:使菜单项无效并变灰,使其不能被选择。
  MF_MENUBARBREAK:对菜单条的功能同MF_MENUBREAK标志。对下拉式菜单、子菜单或快捷菜单,新列和旧列被垂直线分开。
  MF_MENUBREAK:将菜单项放置于新行(对菜单条),或新列(对下拉式菜单、子菜单或快捷菜单)且无分割列。
  MF_OWNERDRAW:指定该菜单项为自绘制菜单项。菜单第一次显示前,拥有菜单的窗口接收一个WM_MEASUREITEM消息来得到菜单项的宽和高。然后,只要菜单项被修改,都将发送WM_DRAWITEM消息给菜单拥有者的窗口程序。
  MF_POPUP:指定菜单打开一个下拉式菜单或子菜单。参数uIDNewltem下拉式菜单或子菜单的句柄。此标志用来给菜单条、打开一个下拉式菜单或于菜单的菜单项、子菜单或快捷菜单加一个名字。
  MF_SEPARATOR:画一条水平区分线。此标志只被下拉式菜单、于菜单或快捷菜单使用。此区分线不能被变灰、无效或加亮。参数IpNewltem和uIDNewltem无用。
  MF_STRING:指定菜单项是一个正文字符串;参数lpNewltem指向该字符串。
  MF_UNCHECKED:不放置选取标记在菜单项旁边(缺省)。如果应用程序提供一个选取标记位图(参见SetMenultemBitmaps),则将选取标记位图放置在菜单项旁边。
  下列标志组不能被一起使用:
  MF_DISABLED,MF_ENABLED和MF_GRAYED;MF_BITMAP,MF_STRING和MF_OWNERDRAW
  MF_MENUBARBREAK和MF_MENUBREAK;MF_CHECKED和MF_UNCHECKED
  Windows CE环境下,不支持参数fuFlags使用下列标志:
  MF_BITMAP;MF_DOSABLE;MF_GRAYED
  MF_GRAYED可用来代替MF_DISABLED和MFS_GRAYED。
  Windows CE 1.0不支持层叠式菜单。在使用Windows CE 1.0时,不能将一个MF_POPUP菜单插入到另一个下拉式菜单中。Window CE 1.0不支持下列标志:
  MF_POPUP;MF_MENUBREAK;MF_MENUBARBREAK
  Windows CE 2.0或更高版本中,支持上述标志,也支持层叠式菜单。
*/

 

 

 [DllImport("user32.dll")]
  internal static extern bool DeleteMenu(IntPtr hMenu, uint uPosition, uint uFlags);
该函数用于删除系统菜单项。hMenu为菜单句柄。uPosition表示操作项的Id或位置等(具体的取决与第三个参数)。uFlags,一些标志它可以是:

internal const UInt32 MF_DISABLED     =0x00000002;
internal const UInt32 MF_BYCOMMAND    =0x00000000;

如果uEnable是MF_BYPOSITION则uIDEnableItem应该传入Index信息(0,1.....),如果是MF_BYCOMMAND则应该传入Id

 

[DllImport("User32.dll")]
internal static extern int DrawMenuBar(IntPtr hWnd);

该函数用于重绘菜单,hWnd的菜单句柄。禁用/移除/添加一些系统菜单项目后,别忘了调用该函数重绘一下。

 

下面是一段示例代码:

 

        internal static bool RemoveUnwantedSystemMenuItems(this Window window)
        {
            
if (window == null)
            {
                
return false;
            }

            var winHelper 
= new WindowInteropHelper(window);
            IntPtr hwnd 
= winHelper.Handle;
            IntPtr sysMenu 
= GetSystemMenu(hwnd, 0);

            
// 6 close, 5 splite line, 4 Maximize, 3 Minimize, 2 Size, 1 Move, 0 Restore
            
// notes that, delete from bigger index to smaller
            bool deletedAll = DeleteMenu(sysMenu, 5, MF_BYPOSITION) &
                              DeleteMenu(sysMenu, 
4, MF_BYPOSITION) &
                              DeleteMenu(sysMenu, 
3, MF_BYPOSITION) &
                              DeleteMenu(sysMenu, 
0, MF_BYPOSITION);

            DrawMenuBar(sysMenu);

            
return deletedAll;
        }

 

 

posted @ 2010-03-24 11:14  周银辉  阅读(5184)  评论(1编辑  收藏  举报