【问题标题】:Bring VB.Net window on top of all windows将 VB.Net 窗口置于所有窗口之上
【发布时间】:2011-12-17 09:17:13
【问题描述】:

我有一个窗口应该位于 Power point 幻灯片放映的顶部。所以它应该在所有窗口的顶部。我使用 VB 6 使用 Lib "user32" 轻松做到了这一点,但它似乎对 VB.net 来说很困难。

Me.TopMost = True

这似乎不起作用,因为它只在程序中起作用。

  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

这也会报错! 任何帮助是极大的赞赏! 提前致谢,

问候

曼朱拉

【问题讨论】:

  • 什么是错误,你能告诉我们你用来调用 API 的 .Net 代码吗?
  • 那个声明语句只适用于vb6。使用 pinvoke.net 为 vb.net 找到正确的

标签: vb.net winforms stayontop


【解决方案1】:

如果您希望您的 应用程序中的窗口始终显示在不同 应用程序的窗口顶部,那么BringWindowToTop 函数绝对不是您想要的.对于初学者,正如您所注意到的,您必须使用计时器重复调用该函数。这应该是您的第一个线索,即它是错误的 API。另一个问题是它只是将您的窗口带到其进程的 Z 顺序顶部,而不是系统上运行的所有其他进程。正如documentation 解释的那样,

调用此函数类似于调用SetWindowPos 函数来更改窗口在Z 顺序中的位置。 BringWindowToTop 不会使窗口成为顶级窗口。

最后一句应该表明有更好的方法。 Windows 内置了对顶级窗口的支持(即那些应该总是出现在其他窗口之上的窗口):这些被称为 top-most 窗口。这正是你想要的。最顶层的窗口总是出现在非最顶层的窗口之上。

Raymond Chen 试图解释on his blog 的一些困惑。请注意,在这种情况下,HWND_TOP 等效于 BringWindowToTop。相反,你想要HWND_TOPMOST

使窗口置顶的最简单方法是在创建窗口时指定WS_EX_TOPMOST 标志。 .NET Framework 将大部分窗口创建工作隐藏在幕后,但您可以在需要时通过覆盖表单类的 CreateParams property 来自定义参数。

这里有一些示例代码可以让表单始终处于最顶层:

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 世界中语义发生了轻微变化——这就是为什么您不能在 VB.NET 中使用旧的 VB6 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

【讨论】:

  • 哇,科迪·格雷!精湛的解释和很好的例子。像魅力一样工作,最重要的是我了解它是如何工作的。非常感谢。
  • @fedmich Your edit 还没来得及复习就被其他人拒绝了。事实证明你是对的,我编辑了我的答案。我错过了一些括号,CharSet 属性是不必要的,因为SetWindowPos 不接受字符串参数。只是为了将来参考,很难让其他人的代码接受更改。您不能指望审稿人对语言的了解足以知道您是否正确。你应该发表评论。如果同意您的意见,大多数用户会自行更正。
  • 如果版主没有知识,则不应审查编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-07
  • 2012-05-04
  • 1970-01-01
  • 1970-01-01
  • 2018-05-24
  • 2018-07-17
  • 1970-01-01
相关资源
最近更新 更多