编辑:这个答案不适用于 MDI 应用程序。
我认为您真正想知道的是您的哪一个表单当前是前景窗口(如果有)。您需要了解的第一件事是表单实例存在于窗口中,但窗口的行为是在更高的地方控制的。类似于如何通过指向实例的变量来识别表单实例,可以通过所谓的窗口句柄来识别窗口。
知道了这一点,找出表单是否是“活动”表单的正确方法是:
- 找出包含我们的实例的窗口的窗口
Form1
句柄Form2
- 找出前台窗口的窗口句柄(可以是任何窗口)
- 将步骤 2 中找到的值与步骤 1 中找到的所有值进行比较
如果前台窗口发生变化,您可能希望触发一个事件,但我将把实际实现留给您。可能有几种方法可以执行第 1 步和第 2 步,但我想不出任何解决方案。希望我让你回到正确的轨道上。
编辑
或者,您可以使用表单的Containsfocus
属性。如果它的值为 True,您可以放心地假定您的窗体是前景窗口。直到我编写了自己的实现之后才发现这个属性,无论如何我都会向你展示:
一个仅包含 Windows API 调用的模块
Friend Module NativeMethods
Friend Declare Function GetForegroundWindow Lib "user32.dll" () As IntPtr
End Module
调用此方法将返回前景窗口的窗口句柄(如果有)。
Form
一个包含类扩展方法的模块
Imports System.Runtime.CompilerServices
Public Module FormExtensions
<Extension>
Public Function IsForeground(f As Form) As Boolean
Return (f.Handle = NativeMethods.GetForegroundWindow)
End Function
End Module
调用此方法返回指定的窗体f是否与前台窗口具有相同的窗口句柄。
使用示例
您可以使用Timer
定期检查表单是否为前台窗口的 a。
Public Class Form1
Private WithEvents timer As New Timer With {.Enabled = True}
Private Sub timer_Tick(sender As Object, e As EventArgs) Handles timer.Tick
If Me.IsForeground() Then
Console.WriteLine("this instance of Form1 is the foreground window")
End If
End Sub
End Class
就像我之前说的,你可以使用Me.ContainsFocus
我的扩展方法来代替它,它会工作得很好。