Demo code on how to disable the X button in menu bar in a window. I found a lot of posts on this in VB, but none for C#. So if you are a C# fan like me, this is for you...

1. There is no direct way to disbale the X button, like there is a property for Maximize button called MaximizeBox = false.

2. This is implemented by importing unmanaged dll "user32" and calling it's functions.

3. Before you use this code, make sure to add a Close button in your form so that you can close your app. See the attached screen shot Disabled.jpg. Below is the code for this form.

Add the following library

using System.Runtime.InteropServices;

Declare the following as class level variable

const int MF_BYPOSITION = 0x400;

[DllImport("User32")]

private static extern int RemoveMenu(IntPtr hMenu, int nPosition, int wFlags);

[DllImport("User32")]

private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

[DllImport("User32")]

private static extern int GetMenuItemCount(IntPtr hWnd);

In the Form_Load() event, write the following code:

private void Form1_Load(object sender, EventArgs e)

{

        IntPtr hMenu = GetSystemMenu(this.Handle, false);

        int menuItemCount = GetMenuItemCount(hMenu);

        RemoveMenu(hMenu, menuItemCount - 1, MF_BYPOSITION);

}

4. Run it. Voila! you are done. If you know of a ay to do it without calling unmanaged code, please do let me know.

 

首先必须对一些固定变量进行声明赋,它们的名称和列表如下:

MF_POPUP := 16

MF_BYCOMMAND := 0

MF_BYPOSITION := 1024

MF_SEPARATOR := 2048

MF_ENABLED := 0

MF_GRAYED := 1

MF_DISABLED := 2

MF_UNCHECKED := 0

MF_CHECKED := 8

MF_USECHECKBITMAPS := 512

MF_STRING := 0

MF_BITMAP := 4

MF_OWNERDRAW := 256

MF_MENUBARBREAK := 32

MF_MENUBREAK := 64

MF_UNHILITE := 0

MF_HILITE := 128
函数功能:该函数使指定的菜单项有效、无效或变灰。

  函数原型:BOOL EnableMenutem(HMENU hMenu,UINT ulDEnablttem,UINT uEnable;

  参数

  hMenu:菜单句柄。

  ulDEnableltem:指定将使其有效、无效或变灰的菜单项,按参数uEnable确定的含义。此参数可指定菜单条、菜单或子菜单里的菜单项。

  uEnable:指定控制参数uIDEnableltem如何解释的标志,指示菜单项有效、无效或者变灰。此参数必须是MF_BYCOMMAND或MF_BYPOSITION,MF_ENABLED和MF_DISABLE或MF_GRAYED的组合。

  MF_BYCOMMAND:表明参数uIDEnableltem给出了菜单项的标识符。如果MF_BYCOMMAND和MF_POSITION都没被指定,则MF_BYCOMMAND为缺省标志。

  MF_BYPOSITION:表明参数uIDEnableltem给出了菜单项的以零为基准的相对位置。

  MF_DISABLED:表明菜单项无效,但没变灰,因此不能被选择。

  MF_ENABLED:表明菜单项有效,并从变灰的状态恢复,因此可被选择。

  MF_GRAYED:表明菜单项无效并且变灰,因此不能被选择。

  返回值:返回值指定菜单项的前一个状态(MF_DISABLED,MF_ENABLED或MF_GRAYED)。如果此菜单项不存在,则返回值是OXFFFFFFFF。

  备注:一个应用程序必须用MF_BYPOSITION来指定正确的菜单句柄。如果菜单条的菜单句柄被指定,顶层菜单项(菜单条上的菜单项)将受到影响。若要根据位置来设置下拉菜单中的菜单项或子菜单的状态,应用程序指定下拉菜单或子菜单的句柄。当应用程序指定MF_BYCOMMAND标志时,系统在由指定菜单句柄标识的菜单里选取那些打开了子菜单的菜单项。因此除非要复制菜单项,指定菜单条的句柄就足够了。函数InsertMenu,InsertMenultem,LoadMenulndirect,ModifyMenu和 SetMenultemlnfo也可设置菜单项的状态(有效、无效或变灰)。Windows CE:Windows CE不支持参数uEnable取MF_DISABLED标志。如果没有变灰,菜单项不能无效。要使菜单项无效,用MF_RAYED标志。

  速查:Windows NT:3.1及以上版本;Windows:95的及以上版本;Windows CE:1.0及以上版本;头文件:winuser.h;输入库:user32.lib。

 

http://support.microsoft.com/kb/300688/zh-cn

 

 

            if (this.Modal.Equals(false))
            {
                IntPtr hMenu = GetSystemMenu(this.Handle, 0);
                //RemoveMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
                UInt32 menuItemCount = GetMenuItemCount(hMenu);


                //RemoveMenu(hMenu, menuItemCount - 1, MF_BYPOSITION);

                EnableMenuItem(hMenu, menuItemCount - 1, MF_BYPOSITION | MF_DISABLED);
            }
            else
            {
                IntPtr hMenu = GetSystemMenu(this.Handle, 0);
                //RemoveMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
                UInt32 menuItemCount = GetMenuItemCount(hMenu);


                //RemoveMenu(hMenu, menuItemCount - 1, MF_BYPOSITION);

                EnableMenuItem(hMenu, menuItemCount - 1, MF_BYPOSITION | MF_DISABLED);
            }

 

 

 

posted on 2009-04-14 16:38  AlexusLi  阅读(1062)  评论(0编辑  收藏  举报