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