当应用程序失去焦点时将焦点放在应用程序控制上
Give focus to application control when application loses focus
我有一个应用程序设计为 运行 持续全屏显示。这通常工作正常,但是,当后台出现 运行 时,例如,防病毒更新可以使 window 高于我的应用程序。很好,因为我可以使用类似的东西:
- 设置前景窗口
- 显示窗口
- 切换到这个窗口
所有这些都让我能够将我的申请重新带到前台。但是,在应用程序内部是一个隐藏的文本框,当应用程序加载时它会被聚焦。当我使用上面的 pInvoke 调用之一,同时将应用程序带回到前面时,焦点仍然在现有应用程序上。
我目前正在努力寻找将焦点返回给控件的最佳方法。
我可以使用 Control.FromHandle,但如果特定的标签页位于最前面,要获得我需要的控件和提供焦点似乎相当复杂。有没有更好的方法,欢迎任何想法/想法。
我在 Windows 10 LTSB 单元上 运行 并且如前所述,SetForegroundWindow 和 Show 函数无法与我在 pInvoke 上找到的许多其他函数一起使用。我设法 select 正确的流程,如果有其他事情排在首位,我会把它带到最前沿。问题是无论我怎么尝试它都不会激活。
最后,我实现了以下代码,每 5 秒检查一次,如果我的应用不是最重要的且未最大化,则最小化/最大化 window,这将重新激活并重新聚焦应用:
Public Declare Function FindWindow Lib "user32.dll" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Public Declare Function ShowWindowAsync Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal nCmdShow As Integer) As IntPtr
Private Declare Function GetWindowPlacement Lib "user32.dll" (ByVal hWnd As IntPtr, ByRef lpwndpl As WINDOWPLACEMENT) As Boolean
Private Declare Function GetForegroundWindow Lib "user32.dll" () As IntPtr
<Serializable>
Friend Structure WINDOWPLACEMENT
Public length As Integer
Public flags As Integer
Public showCmd As ShowWindowCommands
Public ptMinPosition As System.Drawing.Point
Public ptMaxPosition As System.Drawing.Point
Public rcNormalPosition As System.Drawing.Rectangle
End Structure
Friend Enum ShowWindowCommands
Hide = 0
Normal = 1
Minimized = 2
Maximized = 3
End Enum
Private Async Function CheckCurrentApp() As Task
Try
' Try and locate the core process
Dim coreHandle = FindWindow(Nothing, "Name of window")
If coreHandle = IntPtr.Zero Then
' Can't find the core. Exit here.
Exit Try
End If
' Get information about the Core window
Dim currentWindowInfo As WINDOWPLACEMENT
GetWindowPlacement(coreHandle, currentWindowInfo)
' If the core is not the foreground window or isn't maximised then send a minimise (6) and maximise (3) request.
' Activate functions in user32 don't work - I spent a day trying to make it so. I could get the foreground window as the core but the input would
' remain in a different application.
If coreHandle <> GetForegroundWindow() OrElse currentWindowInfo.showCmd <> ShowWindowCommands.Maximized Then
ShowWindowAsync(coreHandle, 6)
ShowWindowAsync(coreHandle, 3)
End If
Catch ex As Exception
' DO SOMETHING WITH THE EXCEPTION.
End Try
Await Task.Delay(TimeSpan.FromSeconds(5))
Await CheckCurrentApp()
End Function
我有一个应用程序设计为 运行 持续全屏显示。这通常工作正常,但是,当后台出现 运行 时,例如,防病毒更新可以使 window 高于我的应用程序。很好,因为我可以使用类似的东西:
- 设置前景窗口
- 显示窗口
- 切换到这个窗口
所有这些都让我能够将我的申请重新带到前台。但是,在应用程序内部是一个隐藏的文本框,当应用程序加载时它会被聚焦。当我使用上面的 pInvoke 调用之一,同时将应用程序带回到前面时,焦点仍然在现有应用程序上。
我目前正在努力寻找将焦点返回给控件的最佳方法。
我可以使用 Control.FromHandle,但如果特定的标签页位于最前面,要获得我需要的控件和提供焦点似乎相当复杂。有没有更好的方法,欢迎任何想法/想法。
我在 Windows 10 LTSB 单元上 运行 并且如前所述,SetForegroundWindow 和 Show 函数无法与我在 pInvoke 上找到的许多其他函数一起使用。我设法 select 正确的流程,如果有其他事情排在首位,我会把它带到最前沿。问题是无论我怎么尝试它都不会激活。
最后,我实现了以下代码,每 5 秒检查一次,如果我的应用不是最重要的且未最大化,则最小化/最大化 window,这将重新激活并重新聚焦应用:
Public Declare Function FindWindow Lib "user32.dll" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Public Declare Function ShowWindowAsync Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal nCmdShow As Integer) As IntPtr
Private Declare Function GetWindowPlacement Lib "user32.dll" (ByVal hWnd As IntPtr, ByRef lpwndpl As WINDOWPLACEMENT) As Boolean
Private Declare Function GetForegroundWindow Lib "user32.dll" () As IntPtr
<Serializable>
Friend Structure WINDOWPLACEMENT
Public length As Integer
Public flags As Integer
Public showCmd As ShowWindowCommands
Public ptMinPosition As System.Drawing.Point
Public ptMaxPosition As System.Drawing.Point
Public rcNormalPosition As System.Drawing.Rectangle
End Structure
Friend Enum ShowWindowCommands
Hide = 0
Normal = 1
Minimized = 2
Maximized = 3
End Enum
Private Async Function CheckCurrentApp() As Task
Try
' Try and locate the core process
Dim coreHandle = FindWindow(Nothing, "Name of window")
If coreHandle = IntPtr.Zero Then
' Can't find the core. Exit here.
Exit Try
End If
' Get information about the Core window
Dim currentWindowInfo As WINDOWPLACEMENT
GetWindowPlacement(coreHandle, currentWindowInfo)
' If the core is not the foreground window or isn't maximised then send a minimise (6) and maximise (3) request.
' Activate functions in user32 don't work - I spent a day trying to make it so. I could get the foreground window as the core but the input would
' remain in a different application.
If coreHandle <> GetForegroundWindow() OrElse currentWindowInfo.showCmd <> ShowWindowCommands.Maximized Then
ShowWindowAsync(coreHandle, 6)
ShowWindowAsync(coreHandle, 3)
End If
Catch ex As Exception
' DO SOMETHING WITH THE EXCEPTION.
End Try
Await Task.Delay(TimeSpan.FromSeconds(5))
Await CheckCurrentApp()
End Function