当应用程序失去焦点时,将焦点交给应用程序控制。

问题描述 投票:0回答:1

我有一个应用程序被设计为持续全屏运行。这在正常情况下工作得很好,但是,当一些事情在后台运行时,例如,杀毒软件的更新,会使那个窗口在我的应用程序上面。这很好,因为我可以使用以下功能

  • SetForegroundWindow
  • 显示窗口
  • SwitchToThisWindow

所有这些都让我可以将我的应用程序带回前面。然而,在应用程序内部有一个隐藏的文本框,当应用程序加载时,这个文本框被聚焦。当我使用上面的一个pInvoke调用时,当应用程序被带回前面时,焦点仍然在现有的应用程序上。

我目前正在努力寻找将焦点还给控件的最佳方法。

我可以使用Control.FromHandle,但是如果一个特定的标签页在前面,要得到我需要的控件并提供焦点,似乎相当复杂。有没有更好的方法,欢迎提出任何想法。

vb.net pinvoke
1个回答
0
投票

我在Windows 10 LTSB装置上运行这个,如前所述,SetForegroundWindow和Show功能与我在pInvoke上发现的许多其他功能一起不工作。我设法选择正确的进程,并将其带到最前面,如果其他东西占据其位置到顶部。问题是无论我怎么尝试,它都无法激活。

最后,我实现了下面的代码,它每隔5秒检查一次,如果我的应用程序不是最前面的,没有最大化,那么最小化最大化窗口,这将重新激活并重新聚焦应用程序。

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
© www.soinside.com 2019 - 2024. All rights reserved.