首页 > 解决方案 > SetForegroundWindow 在对话框窗口中使用时不起作用

问题描述

我有一个使用该ShowDialog()方法从 WPF 应用程序显示的窗口。在这个对话框窗口中,我需要调用本机SetForegroundWindow以将其他应用程序带到前台,然后我需要SetForegroundWindow再次调用以将该窗口带回前台。

可以使用按钮(具有命令绑定)或键(处理和ShowDialog()调用 KeyUp 事件)打开对话框窗口。

单击按钮时一切正常(显示对话框-> 另一个应用程序进入前台-> 对话框再次进入前台)。但是,当使用该键时,对话窗口在其他应用程序上使用后不再被带到前台,SetForegroundWindow并且任务栏呈橙色闪烁(表示该窗口请求前台,但Windows阻止它,因为它认为对话窗口正在试图窃取焦点)。

这是我在打开对话框窗口时使用的代码:

try
{
  await BringApplicationIntoForegroundAsync(hWnd); // this code brings application into foreground at some point

  // do some work
}
finally
{
  SetForegroundWindow(hWnd);
}

如果我在调用之前发送任何键或单击对话框窗口BringApplicationIntoForegroundAsync(hWnd)一切正常(即使对话框是使用键打开的)。

如果对话框是使用一个键打开的并且用户在第一个之前没有与之交互,SetForegroundWindow那么第二个SetForegroundWindow不起作用(返回false)。

我的猜测是,当按钮用于打开对话框时,对话框以某种方式接收输入,Windows 允许它SetForegroundWindow第二次调用。

标签: c#.netwpfwindows

解决方案


如果您的最终目标是确保您的对话窗口是最顶层的窗口,而另一个应用程序是它下面的窗口,那么使用SetForegroundWindow两次将不是正确的选择,因为正如您所说,当您SetForegroundWindow第二次调用时,您的应用程序不再有焦点(另一个应用程序有),因此不能这样做。

相反,请尝试SetWindowPos。这将允许您在另一个窗口(您的对话窗口)之后专门设置一个窗口(另一个应用程序)。

例子:

SetWindowPos(OtherAppHandle, DialogWindowHandle, 0, 0, 0, 0, 
    (uint)(NativeMethods.SET_WINDOW_POSITION.SWP_NOSIZE |
    NativeMethods.SET_WINDOW_POSITION.SWP_NOMOVE |
    NativeMethods.SET_WINDOW_POSITION.SWP_NOACTIVATE |
    NativeMethods.SET_WINDOW_POSITION.SWP_NOREDRAW));

推荐阅读