Windows Forms だと Me.ControlBox = False 一発で消せるコントロールボックスですが、WPF だとそのようなプロパティは用意されておらず、結局のところ Win32API に頼る以外に方法がない模様です。
ということで、その方法を列挙。
- タイトルバー右側のコントロールボックス(最大化/最小化/閉じるボタン)と、タイトルバー左側のシステムメニューボタンの消去。
Shared Sub DisableControlBox(w As Window) Const GWL_STYLE = -16 Const WS_SYSMENU = &H80000 Dim hwnd = (New System.Windows.Interop.WindowInteropHelper(w)).Handle Dim currentValue = GetWindowLong(hwnd, GWL_STYLE) Dim oldValue = SetWindowLong(hwnd, GWL_STYLE, currentValue And (Not WS_SYSMENU)) End Sub
- 最大化ボタンの無効化。
Shared Sub DisableMaximizeBox(w As Window) Const GWL_STYLE = -16 Const WS_MAXIMIZEBOX = &H10000 Dim hwnd = (New System.Windows.Interop.WindowInteropHelper(w)).Handle Dim currentValue = GetWindowLong(hwnd, GWL_STYLE) Dim oldValue = SetWindowLong(hwnd, GWL_STYLE, currentValue And (Not WS_MAXIMIZEBOX)) End Sub
- 最小化ボタンの無効化。
最大化無効と最小化無効の両方を実行すると、ボタンそのものが消去されます。
Me.WindowStyle = Windows.WindowStyle.ToolWindow との違いは、システムメニューアイコンが残ることと、閉じるボタンが小さくならないことでしょうか。Shared Sub DisableMinimizeBOX(w As Window) Const GWL_STYLE = -16 Const WS_MINIMIZEBOX = &H20000 Dim hwnd = (New System.Windows.Interop.WindowInteropHelper(w)).Handle Dim currentValue = GetWindowLong(hwnd, GWL_STYLE) Dim oldValue = SetWindowLong(hwnd, GWL_STYLE, currentValue And (Not WS_MINIMIZEBOX)) End Sub
- 閉じるボタンの無効化。
閉じるボタンの無効化だけ、他と違って SetWindowLong ではなく EnableMenuItem で実現。
Public Shared Sub DisableCloseBox(w As Window) Const SC_CLOSE = &HF060 Const MF_BYCOMMAND = &H0 Const MF_GRAYED = &H1 Dim hwnd = (New System.Windows.Interop.WindowInteropHelper(w)).Handle Dim hMenu As IntPtr = GetSystemMenu(hwnd, False) If hMenu <> IntPtr.Zero Then EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND Or MF_GRAYED) End If End Sub
あと、上記を実行するために必要な Declare 宣言は以下。
- コントロールボックスの消去、最大化/最小化ボタンを無効にするときに必要な Declare 宣言。
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" ( ByVal hWnd As IntPtr, ByVal nIndex As Integer) As Integer Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" ( ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal dwNewLong As Integer) As Integer
- 閉じるボタンを無効にするときに必要な Declare 宣言。
Private Declare Function GetSystemMenu Lib "user32" ( ByVal hwnd As IntPtr, ByVal bRevert As Integer) As Long Private Declare Function EnableMenuItem Lib "user32" ( ByVal hWnd As IntPtr, ByVal uIDEnableItem As UInteger, ByVal uEnable As UInteger) As Boolean
あと、注意点としては、上記の方法で閉じるボタンを無効化/消去しただけでは、ALT+F4 を押すと Window は閉じてしまいます。
このため、Window を閉じたくない場合は、Window の Closing イベントで e.Cancel = True で閉じなくするなどの対策が必要になります。
しかし WPF・・・、このかゆいところに手が届かない感じは、早めになんとかしてほしいのではありますが(汗
参考) Window の各部の名称