WPF アプリケーションの Window を Alt+Tab ダイアログに表示されないようにするためには、どうすればいいのでしょうか。
Window を Alt+Tab ダイアログに表示させない方法
WPF でも Alt+Tab ダイアログに表示させないためのプロパティはありません。Windows Forms アプリケーションのころと同様に、WindowStyle プロパティの中に表示されないスタイルが存在します。また、表示されないようにするためにはタスクバーにウィンドウが表示されていないことが条件になります。
WindowStyle |
Alt+Tab ダイアログへの表示可否 |
None | 表示される |
SingleBorderWindow | 表示される |
ThreeDBorderWindow | 表示される |
ToolWindow | 表示されない |
結果としては ShowInTaskbar = False で WindowStyle が ToolWindow の時のみ、Alt+Tab ダイアログに表示されなくなります。ToolWindow の時に表示されないということは、拡張ウィンドウスタイルの WS_EX_TOOLWINDOW (0x00000080) が設定されていると Alt+Tab ダイアログに表示されなくなるということだと思います。
ということは WindowStyle が None の時でも WS_EX_TOOLWINDOW を設定してあげれば、Alt+Tab ダイアログには表示されなくなるということです。これは、レイヤードウィンドウを表示する時に WindowStyle を None にする必要があるので、その時に有効です。
他の SingleBorderWindow と ThreeDBorderWindow の時に WS_EX_TOOLWINDOW を設定すると、見た目が ToolWindow と同じ状態になってしまうため、これらの WindowStyle では Alt+Tab ダイアログに表示させないようにするのは無理のようです。
Imports System.Windows.Interop
Partial Public Class Window1
Private Sub Window1_Initialized(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Initialized
Me.WindowStyle = Windows.WindowStyle.None
Me.ShowInTaskbar = False
End Sub
Private Sub Window1_SourceInitialized(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SourceInitialized
Dim wndHelper As WindowInteropHelper = New WindowInteropHelper(Me)
Dim exStyle As Integer = NativeMethod.GetWindowLongPtr(wndHelper.Handle, NativeMethod.GetWindowLongFields.GWL_EXSTYLE).ToInt32
exStyle = exStyle Or NativeMethod.ExtendedWindowStyles.WS_EX_TOOLWINDOW
NativeMethod.SetWindowLongPtr(wndHelper.Handle, NativeMethod.GetWindowLongFields.GWL_EXSTYLE, New IntPtr(exStyle))
End Sub
End Class
Imports System.Runtime.InteropServices
Public Class NativeMethod
<Flags()> _
Public Enum ExtendedWindowStyles As Integer
WS_EX_TOOLWINDOW = &H80
End Enum
Public Enum GetWindowLongFields As Integer
GWL_EXSTYLE = (-20)
End Enum
<DllImport("user32.dll", EntryPoint:="GetWindowLong")> _
Private Shared Function GetWindowLongPtr32(ByVal hWnd As IntPtr, ByVal nIndex As Integer) As IntPtr
End Function
<DllImport("user32.dll", EntryPoint:="GetWindowLongPtr")> _
Private Shared Function GetWindowLongPtr64(ByVal hWnd As IntPtr, ByVal nIndex As Integer) As IntPtr
End Function
Public Shared Function GetWindowLongPtr(ByVal hWnd As IntPtr, ByVal nIndex As Integer) As IntPtr
If IntPtr.Size = 8 Then
Return GetWindowLongPtr64(hWnd, nIndex)
Else
Return GetWindowLongPtr32(hWnd, nIndex)
End If
End Function
<System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="SetWindowLong")> _
Private Shared Function SetWindowLong32(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal dwNewLong As Integer) As Integer
End Function
<System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="SetWindowLongPtr")> _
Private Shared Function SetWindowLongPtr64(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal dwNewLong As IntPtr) As IntPtr
End Function
Public Shared Function SetWindowLongPtr(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal dwNewLong As IntPtr) As IntPtr
If IntPtr.Size = 8 Then
Return SetWindowLongPtr64(hWnd, nIndex, dwNewLong)
Else
Return New IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32))
End If
End Function
End Class
WindowStyle に関係なく、Alt+Tab ダイアログに表示させない方法もあります。それは、Alt+Tab ダイアログに表示されない Window をオーナーに設定することです。この時も ShowInTaskbar は False に設定する必要があります。オーナーウィンドウを非表示にしておけば、SingleBorderWindow や ThreeDBorderWindow の Window が Alt+Tab ダイアログに表示されないようにすることができます。
Dim owner As New Window
owner.WindowStyle = Windows.WindowStyle.ToolWindow
owner.ShowInTaskbar = False
owner.Left = -100
owner.Height = 0
owner.Width = 0
owner.Show()
Dim w As New Window
w.Owner = owner
w.ShowInTaskbar = False
w.Show()
owner.Hide()
End Sub
まとめ
- Alt+Tab ダイアログに表示させないためには ShowInTaskbar = False が必須条件になる。
- WindowStyle が ToolWindow の時だけ表示されなくなる。
- WindowStyle が None でも WS_EX_TOOLWINDOW を設定すると表示されなくなる。
- Alt+Tab ダイアログに表示されない Window をオーナーにした場合は WindowStyle に関係なく表示されなくなる。
WPF でも Window を Alt+Tab ダイアログに表示させないようにするには、WindowStyle に依存してしまうようです。これは Windows OS 側の性だと思うのですが、WS_EX_TOOLWINDOW とは別に Alt+Tab ダイアログに表示するかどうかのスタイルも用意してくれているとうれしかったです。この辺の動きは Windows OS で前から同じだと思いますから、今後も変わらないんでしょうね。