0

我在系统托盘中运行了一个小型 Windows 窗体程序(代理)。编写此代理的目的C#是启动其他程序,将它们聚焦并将它们置于前台。

该代理从浏览器接收启动其他程序的命令,并将成功启动报告给它。这意味着浏览器始终处于启动和运行状态。

从代理启动外部程序工作正常,但我很难让焦点和前景主题工作。似乎浏览器始终处于焦点位置,并且从代理启动的程序被移动到浏览器窗口的正后方。

我从User32.dll没有成功尝试过以下方法:

  • SetForegroundWindow(IntPtr handle)
  • SwitchToThisWindow(IntPtr hWnd, bool fAltTab)

奇怪的是,如果我在我的 Visual Studio 中运行代理,焦点就完美了!

非常感谢您的帮助,因为我是 Windows 内部的新手。

更新 1:我注意到,例如,如果一个 powershell 窗口(可以是任意的)覆盖在浏览器窗口上,则聚焦已启动的进程窗口按预期工作。

更新 2:我能够通过调用获得正确的焦点

SetWindowPos(browserProcess.MainWindowHandle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);

在浏览器进程窗口和

SetWindowPos(process.MainWindowHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);

在已启动的进程窗口上。但我认为这是一种不好的方法,因为浏览器窗口可能会消失在其他打开的窗口后面。我也试过

SetWindowPos(browserProcess.MainWindowHandle, process.MainWindowHandle, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);

切换浏览器窗口和进程窗口的Z顺序,但没有成功。

问题:如何切换浏览器进程和启动进程的Z顺序?

4

2 回答 2

1

似乎SendKeys.SendWait("%");是我需要的魔法。%是 ALT 键。

从文档LockSetForegroundWindow

如果用户按下 ALT 键或采取一些导致系统本身更改前台窗口的操作(例如,单击背景窗口),系统会自动启用对 SetForegroundWindow 的调用。

首先调用AllowSetForegroundWindow返回FALSE,所以我无法设置前台窗口。调用GetLastError显示错误代码ERROR_ACCESS_DENIED。调用SendKeys.SendWait("%")之前User32dll.SetForegroundWindow(windowHandle)使调用SetForegroundWindow成功。

把它放在一起看起来像这样:

var windowHandle = User32dll.FindWindow(null, nameOfWindow);
SendKeys.SendWait("%");
User32dll.SetForegroundWindow(windowHandle);

如果窗口最小化,使用User32dll.ShowWindow(windowHandle, User32dll.SW_RESTORE)就足够了。

于 2018-07-17T07:37:45.677 回答
0

您如何检索该窗口的句柄?

这对我有用:

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SetForegroundWindow(IntPtr hWnd);


    SetForegroundWindow((IntPtr)handle);
于 2018-06-28T14:38:23.820 回答