检查外部程序是否为活动窗口

时间:2018-07-04 06:41:17

标签: vb.net winforms events

我正在制作一个使用屏幕键盘的表单,并且如果外部存在click事件,也希望关闭该表单。 为此,我使用了dectivate事件,但是如果单击屏幕键盘,则会为该表单触发deactivate事件。因此,我想问是否有一种方法可以检测osk是否为活动窗口,以便为该非活动事件设置if条件以在这种情况下不关闭该窗体。 有什么方法可以解决这种情况吗?

1 个答案:

答案 0 :(得分:0)

您可以使用Platform Invocation(简称为 P / Invoke )来访问WinAPI函数GetForegroundWindow()GetWindowThreadProcessId()

您可以使用GetForegroundWindow()来获取当前焦点/活动窗口的窗口句柄,然后调用GetWindowThreadProcessId()来获取该窗口的进程ID。然后,您可以使用该ID来获取.NET Process class的实例,通过该实例,您可以轻松访问进程的名称等。

首先创建一个名为NativeMethods的类。在这里,我们将声明所有P / Invoked函数:

Imports System.Runtime.InteropServices

Public NotInheritable Class NativeMethods
    Private Sub New() 'Private constructor as we're not supposed to create instances of this class.
    End Sub

    <DllImport("user32.dll")> _
    Public Shared Function GetForegroundWindow() As IntPtr
    End Function

    <DllImport("user32.dll")> _
    Public Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, <Out()> ByRef lpdwProcessId As UInteger) As UInteger
    End Function
End Class

然后,您可以在代码中创建一个函数,使用这些函数来获取活动的进程:

Public Function GetActiveProcess() As Process
    Dim hWnd As IntPtr = NativeMethods.GetForegroundWindow()
    Dim ProcessID As UInteger = 0

    NativeMethods.GetWindowThreadProcessId(hWnd, ProcessID)

    Return If(ProcessID <> 0, Process.GetProcessById(ProcessID), Nothing)
End Function

现在您可以像这样使用

Dim ActiveProcess As Process = GetActiveProcess()

If ActiveProcess IsNot Nothing AndAlso ActiveProcess.ProcessName = "osk" Then
    'Active process is "osk", do something...
End If