XK8ER
XK8ER

Reputation: 780

Moving the current process window to the front

I am calling a thread every hour to take a screenshot. but the issue is with activating the window or moving the window to the front. if there are other apps in the front then while taking the screenshot they appear in the front. Whats going on?

<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

Upvotes: 0

Views: 740

Answers (1)

Eugene Podskal
Eugene Podskal

Reputation: 10401

Unfortunately(or if one thinks from the user's point of view fortunately) SetForegroundWindow is not an unconditional "make this window the foremost/active one" command.

It has a set of restrictions:

The system restricts which processes can set the foreground window. A process can set the foreground window only if one of the following conditions is true:

The process is the foreground process.
The process was started by the foreground process.
The process received the last input event.
There is no foreground process.
The process is being debugged.
The foreground process is not a Modern Application or the Start Screen.
The foreground is not locked (see LockSetForegroundWindow).
The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
No menus are active.

So while there are some not recommended ways to overcome this restriction, under normal circumstances, unless one of those conditions is true, SetForegroundWindow won't work.

P.S.: Also, recommended reading - https://devblogs.microsoft.com/oldnewthing/20090220-00/?p=19083

P.S.1: While this restriction is probably the reason why the original solution fails, I'd also like to point that there is a chance that proc.MainWindowHandle can be IntPtr.Zero or be a stale handle (from some starting window or etc.) and that you do not check return values from the called WIN API functions, that is both very important and may actually assist in troubleshooting the issue...

Upvotes: 1

Related Questions