[VB.NET] WPFでコントロールボックスを消去する

2013年11月30日


 Windows Forms だと Me.ControlBox = False 一発で消せるコントロールボックスですが、WPF だとそのようなプロパティは用意されておらず、結局のところ Win32API に頼る以外に方法がない模様です。

 ということで、その方法を列挙。

  1. タイトルバー右側のコントロールボックス(最大化/最小化/閉じるボタン)と、タイトルバー左側のシステムメニューボタンの消去。
    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
    
  2. 最大化ボタンの無効化。
    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
    
  3. 最小化ボタンの無効化。

     最大化無効と最小化無効の両方を実行すると、ボタンそのものが消去されます。
     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
    
  4. 閉じるボタンの無効化。

     閉じるボタンの無効化だけ、他と違って 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 宣言は以下。

  1. コントロールボックスの消去、最大化/最小化ボタンを無効にするときに必要な 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
    
  2. 閉じるボタンを無効にするときに必要な 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 の各部の名称






カテゴリー: Program, VB.NET, WPF

Follow comments via the RSS Feed | Leave a comment | Trackback URL

コメントを投稿する

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


«   »
 
Powered by Wordpress and MySQL. Theme by Shlomi Noach, openark.org