Разместите окно VB.Net поверх всех окон. - PullRequest
2 голосов
/ 17 декабря 2011

У меня есть окно, которое должно оставаться поверх слайд-шоу Power Point.Так должно быть поверх всех окон.Я сделал это легко, используя VB 6, используя Lib "user32", но, похоже, с VB.net это не так.

  Private Declare Function BringWindowToTop Lib "user32" Alias "BringWindowToTop" (ByVal hwnd As Long) As Long
    Private Sub frmTmr_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated
        BringWindowToTop(Me.Handle)
    End Sub

Это также дает ошибку!Любая помощь с благодарностью!Заранее спасибо,

С уважением

Манджула

1 Ответ

12 голосов
/ 17 декабря 2011

Если вы хотите, чтобы окно в вашем приложении всегда отображалось поверх окна другого приложения, то функция 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
...