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);
}