【问题标题】:Check if an external program is the active window检查外部程序是否是活动窗口
【发布时间】:2018-07-04 06:41:17
【问题描述】:

我正在制作一个使用屏幕键盘的表单,并且我希望在表单之外有点击事件时关闭该表单。 为此,我使用了 dectivate 事件,但是如果我单击屏幕键盘,则会为表单触发 deactivate 事件。所以我问是否有办法检测 osk 是否是活动窗口,以便在这种情况下为非活动事件设置一个 if 条件以不关闭表单。 有什么办法可以做到这一点,或者有什么不同的方式来处理这种情况?

【问题讨论】:

  • 单击 OSK 按钮不会停用您的应用程序。但是点击它的标题就可以了。
  • 是的,问题是如果我想移动 osk。我应该以某种方式在我的应用程序中管理它

标签: vb.net winforms events


【解决方案1】:

您可以使用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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-27
    • 2011-03-16
    • 2020-06-20
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多