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 ダイアログに表示させないようにするのは無理のようです。

WindowStyle が None の時に 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
        ' WS_EX_TOOLWINDOW を設定し Alt + Tab 画面に表示されないようにする
        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 ダイアログに表示されないようにすることができます。

WindowStyle に関係なく Alt+Tab ダイアログに表示させない例
' 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()

' WindowStyle に関係なく Alt+Tab ダイアログに表示させないウィンドウを作成
Dim w As New Window
w.Owner = owner ' Alt+Tab ダイアログに表示されないウィンドウをオーナーに設定
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 で前から同じだと思いますから、今後も変わらないんでしょうね。