アプリケーションのウィンドウを常に別のアプリケーションのウィンドウの上に表示したい場合、その機能は間違いなくあなたが望むものではありません. まず、お気づきのように、タイマーを使用して関数を繰り返し呼び出す必要があります。それが間違った API であるという最初の手がかりになるはずです。別の問題は、システムで実行されている他のすべてのプロセスではなく、そのプロセスの Z オーダーの先頭にウィンドウを移動するだけであることです。ドキュメントで説明されているように、BringWindowToTop
SetWindowPos
この関数を呼び出すことは、Z オーダーでウィンドウの位置を変更する関数を呼び出すことに似ています。BringWindowToTop
ウィンドウをトップレベル ウィンドウにしません。
その最後の文は、より良い方法があることを示しているはずです。Windows には、最上位ウィンドウ (つまり、常に他のウィンドウの上に表示されるウィンドウ) のサポートが組み込まれています。これらは最上位ウィンドウと呼ばれます。これはまさにあなたが望むものです。最上位のウィンドウは常に最上位以外のウィンドウの上に表示されます。
Raymond Chen は、彼のブログで混乱の一部を説明しようとしています。この場合、HWND_TOP
は と同等であることに注意してくださいBringWindowToTop
。代わりに、必要ですHWND_TOPMOST
。
ウィンドウを最前面にする最も簡単な方法は、ウィンドウWS_EX_TOPMOST
を作成するときにフラグを指定することです。.NET Framework は、ほとんどのウィンドウ作成作業を舞台裏で隠しますが、フォーム クラスのCreateParams
プロパティをオーバーライドすることで、必要に応じてパラメーターをカスタマイズできます。
フォームを常に一番上に表示するサンプル コードを次に示します。
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
Const WS_EX_TOPMOST As Integer = &H00000008
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or WS_EX_TOPMOST
Return cp
End Get
End Property
実行時にウィンドウの最上位の状態を切り替えたい場合、これは機能しません。そのためには、関数を P/Invoke する必要がありSetWindowPos
ます。P/Invoke は、ステートメントを使用して VB6 で行っていたものと似ていますが、.NET の世界ではセマンティクスがわずかに変更されています。そのため、古い VB6ステートメントを VB.NET でDeclare
使用することはできません。Declare
VB.NET のコードは次のようになります。
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As Integer) As Boolean
End Function
Private Const SWP_NOSIZE As Integer = &H1
Private Const SWP_NOMOVE As Integer = &H2
Private Shared ReadOnly HWND_TOPMOST As New IntPtr(-1)
Private Shared ReadOnly HWND_NOTOPMOST As New IntPtr(-2)
Public Function MakeTopMost()
SetWindowPos(Me.Handle(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
End Function
Public Function MakeNormal()
SetWindowPos(Me.Handle(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
End Function