フォームの「閉じる」ボタンを無効にするWindowsフォームの右上にある「閉じる」ボタン(Xボタン)を無効にする方法を幾つか紹介します。 ControlBoxをFalseにする方法まず一番単純なのは、フォームのControlBoxプロパティをFalseにしたり、FormBorderStyleプロパティをNoneにしたりすることにより、「閉じる」ボタンを消す方法です。この場合は、最小化、最大化ボタン、コントロールボックスも消えてしまうという欠点があります。 閉じられる原因を調べて判断する方法また、「フォームが閉じられる時その原因を知る」と「条件によりフォームが閉じられないようにする」により、「閉じる」ボタンが押されてフォームが閉じられる場合に、フォームを閉じないようにする方法もあります。 この方法を使った例は、次のようなものです。なおこの例では、システムメニューの「閉じる」や、「Alt」+「F4」キーも無効になります。
<System.Security.Permissions.SecurityPermission( _
System.Security.Permissions.SecurityAction.LinkDemand, _
Flags:=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)> _
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Const WM_SYSCOMMAND As Integer = &H112
Const SC_CLOSE As Long = &HF060L
If m.Msg = WM_SYSCOMMAND AndAlso _
(m.WParam.ToInt64() And &HFFF0L) = SC_CLOSE Then
Return
End If
MyBase.WndProc(m)
End Sub
[System.Security.Permissions.SecurityPermission(
System.Security.Permissions.SecurityAction.LinkDemand,
Flags = System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)]
protected override void WndProc(ref Message m)
{
const int WM_SYSCOMMAND = 0x112;
const long SC_CLOSE = 0xF060L;
if (m.Msg == WM_SYSCOMMAND &&
(m.WParam.ToInt64() & 0xFFF0L) == SC_CLOSE)
{
return;
}
base.WndProc(ref m);
}
補足:上の例では「条件によりフォームが閉じられないようにする」は使いませんでした。これを使う場合は、「閉じる」ボタンが押された時にフラッグを立てて、Closingイベントで閉じないようにします。
補足:.NET Framework 2.0以降では、次のようにFormClosingイベントを使うと簡単そうに思われます。ただし、フォームのCloseメソッドで閉じる場合もCloseReasonがUserClosingとなりますので、Application.Exitメソッドなどで閉じなければならなくなります。
'フォームのFormClosingイベントハンドラ Private Sub Form1_FormClosing(ByVal sender As Object, _ ByVal e As FormClosingEventArgs) Handles MyBase.FormClosing If e.CloseReason = CloseReason.UserClosing Then e.Cancel = True End If End Sub //フォームのFormClosingイベントハンドラ private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (e.CloseReason == CloseReason.UserClosing) e.Cancel = true; } CreateParamsをオーバーライドする方法さらに、GotDotNetの掲示板の「Disabling the close button?」(リンク切れ)にMickDohertyさんがとてもおもしろい投稿をされています。これはフォームのCreateParamsプロパティをオーバーライドするという方法で、「閉じる」ボタンが無効状態となり、押すことができなくなります。システムメニューの「閉じる」も表示されなくなり、「Alt」+「F4」キーも無効になります。 以下にそのコードを引用させていただきます。 Protected Overrides ReadOnly Property CreateParams() As _ System.Windows.Forms.CreateParams <System.Security.Permissions.SecurityPermission( _ System.Security.Permissions.SecurityAction.LinkDemand, _ Flags:=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)> _ Get Const CS_NOCLOSE As Integer = &H200 Dim cp As CreateParams = MyBase.CreateParams cp.ClassStyle = cp.ClassStyle Or CS_NOCLOSE Return cp End Get End Property protected override CreateParams CreateParams { [System.Security.Permissions.SecurityPermission( System.Security.Permissions.SecurityAction.LinkDemand, Flags = System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)] get { const int CS_NOCLOSE = 0x200; CreateParams cp = base.CreateParams; cp.ClassStyle = cp.ClassStyle | CS_NOCLOSE; return cp; } } Win32 APIによる方法最後にWin32 APIを使う方法も紹介しておきます。下記の方法では、「閉じる」ボタンが無効状態となり、システムメニューの「閉じる」が表示されなくなりますが、「Alt」+「F4」キーは有効です。
<System.Runtime.InteropServices.DllImport("user32.dll")> _
Shared Function GetSystemMenu(ByVal hWnd As IntPtr, _
ByVal bRevert As Boolean) As IntPtr
End Function
<System.Runtime.InteropServices.DllImport("user32.dll")> _
Shared Function GetMenuItemCount(ByVal hMenu As IntPtr) As Integer
End Function
<System.Runtime.InteropServices.DllImport("user32.dll")> _
Shared Function DrawMenuBar(ByVal hWnd As IntPtr) As Boolean
End Function
<System.Runtime.InteropServices.DllImport("user32.dll")> _
Shared Function RemoveMenu(ByVal hMenu As IntPtr, _
ByVal uPosition As Integer, _
ByVal uFlags As Integer) As Boolean
End Function
Protected Overrides Sub OnLoad(ByVal e As EventArgs)
MyBase.OnLoad(e)
Const MF_BYPOSITION As Int32 = &H400
Const MF_REMOVE As Int32 = &H1000
Dim menu As IntPtr = GetSystemMenu(Me.Handle, False)
Dim menuCount As Integer = GetMenuItemCount(menu)
If menuCount > 1 Then
'メニューの「閉じる」とセパレータを削除
RemoveMenu(menu, menuCount - 1, MF_BYPOSITION Or MF_REMOVE)
RemoveMenu(menu, menuCount - 2, MF_BYPOSITION Or MF_REMOVE)
DrawMenuBar(Me.Handle)
End If
End Sub
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern int GetMenuItemCount(IntPtr hMenu);
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern bool DrawMenuBar(IntPtr hWnd);
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern bool RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags);
protected override void OnLoad(EventArgs e)
{
base.OnLoad (e);
const Int32 MF_BYPOSITION = 0x400;
const Int32 MF_REMOVE = 0x1000;
IntPtr menu = GetSystemMenu(this.Handle, false);
int menuCount = GetMenuItemCount(menu);
if (menuCount > 1)
{
//メニューの「閉じる」とセパレータを削除
RemoveMenu(menu, (uint) (menuCount - 1), MF_BYPOSITION | MF_REMOVE);
RemoveMenu(menu, (uint) (menuCount - 2), MF_BYPOSITION | MF_REMOVE);
DrawMenuBar(this.Handle);
}
}
(この記事は、「.NETプログラミング研究」で紹介したものを基にしています。) 注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。
|
|
Copyright(C) DOBON!. All rights reserved.
|