Если вы хотите, чтобы окно в вашем приложении всегда отображалось поверх окна другого приложения, то функция BringWindowToTop
определенно не то, что вам нужно. Для начала, как вы заметили, вы должны повторно вызывать функцию, используя таймер. Это должно быть вашей первой подсказкой, что это неправильный API. Другая проблема заключается в том, что он только выводит ваше окно на вершину Z-порядка для своего процесса, а не на все другие процессы, работающие в системе. Как объясняет документация ,
Вызов этой функции аналогичен вызову функции SetWindowPos
для изменения положения окна в Z-порядке. BringWindowToTop
не делает окно окном верхнего уровня.
Это последнее предложение должно указывать, что есть лучший способ. В Windows имеется встроенная поддержка окон верхнего уровня (то есть тех, которые должны всегда отображаться поверх других окон): они называются top-most windows. Это именно то, что вы хотите. Самые верхние окна всегда отображаются над не верхними окнами.
Раймонд Чен пытается объяснить некоторую путаницу в своем блоге . Обратите внимание, что в этом случае 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 с оператором Declare
, но семантика немного изменилась для мира .NET - поэтому вы не можете использовать свои старые операторы VB6 Declare
в VB.NET .
Вот как может выглядеть этот код для 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