将当前过程窗口移到最前面

时间:2020-02-25 19:52:44

标签: c# .net vb.net

我每小时都会调用一个线程来截屏。 但是问题在于激活窗口或将窗口移到最前面。 如果前面有其他应用,则在截取屏幕快照时它们会显示在前面。 怎么了?

<Runtime.InteropServices.DllImport("user32.dll")>
Private Function SetForegroundWindow(ByVal hWnd As IntPtr) As Integer
End Function

<Runtime.InteropServices.DllImport("user32.dll")>
Private Function ShowWindow(ByVal hWnd As IntPtr, ByVal nCmdShow As Integer) As IntPtr
End Function

Public Sub TakeScreenshot()
        Dim thread As New Threading.Thread(AddressOf TakeScreenShotThread)
        thread.Start()
End Sub

Public Function TakeScreenShotThread() As Integer
        Dim proc As Process = Process.GetCurrentProcess
        Call SetForegroundWindow(proc.MainWindowHandle)
        Call ShowWindow(proc.MainWindowHandle, 5)

                    'GIVE IT TIME TO DISPLAY THE APP AND ACTIVATE WINDOW
        Dim t = Threading.Tasks.Task.Run(Async Function()
                                             Await Threading.Tasks.Task.Delay(TimeSpan.FromMilliseconds(200))
                                             Return 1
                                         End Function)

        t.Wait()

                    'SAVE SCREENSHOT IMAGE CODE HERE
End Function

1 个答案:

答案 0 :(得分:0)

不幸的是(或者如果有人幸运地从用户的角度考虑)SetForegroundWindow不是无条件的“使此窗口成为最重要/最活跃的窗口”命令。

它有一组restrictions

系统限制可以设置前景窗口的进程。仅当满足以下条件之一时,进程才能设置前景窗口:

该过程是前台过程。
该过程由前台过程启动。
该进程收到了最后一个输入事件。
没有前台流程。
该进程正在调试中。
前台进程不是现代应用程序或“开始”屏幕。
前景未锁定(请参见LockSetForegroundWindow)。
前台锁定超时已到期(请参阅SystemParametersInfo中的SPI_GETFOREGROUNDLOCKTIMEOUT)。
没有菜单处于活动状态。

因此,尽管有一些不建议使用的方法可以克服此限制,但在正常情况下,除非满足上述条件之一,否则SetForegroundWindow将不起作用。

P.S .:另外,建议阅读-https://devblogs.microsoft.com/oldnewthing/20090220-00/?p=19083

PS1:虽然此限制可能是原始解决方案失败的原因,但我也想指出,proc.MainWindowHandle可能是IntPtr.Zero或陈旧的句柄(某些原因)。并没有从check WIN API函数中返回值called,这非常重要并且实际上可能有助于解决问题...