我知道这个问题已经很老了,但我刚遇到这种情况并想分享我实现的解决方案。
正如在本页面上的评论中提到的,一些提出的解决方案在我需要支持XP的情况下不起作用。虽然我同意@Matthew Xavier所表达的观点,通常这是一个糟糕的用户体验实践,但有时候它完全是一个合理的用户体验。
将WPF窗口置于顶层的解决方案实际上是由提供全局热键的相同代码提供给我的。Joseph Cooney的博客文章包含指向他的代码示例链接的原始代码。
我已经清理和修改了一些代码,并将其实现为System.Windows.Window的扩展方法。 我已在XP 32位和Win7 64位上进行了测试,两者都能正常工作。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Interop;
using System.Runtime.InteropServices;
namespace System.Windows
{
public static class SystemWindows
{
#region Constants
const UInt32 SWP_NOSIZE = 0x0001;
const UInt32 SWP_NOMOVE = 0x0002;
const UInt32 SWP_SHOWWINDOW = 0x0040;
#endregion
public static void GlobalActivate(this Window w)
{
var interopHelper = new WindowInteropHelper(w);
var thisWindowThreadId = GetWindowThreadProcessId(interopHelper.Handle, IntPtr.Zero);
var currentForegroundWindow = GetForegroundWindow();
var currentForegroundWindowThreadId = GetWindowThreadProcessId(currentForegroundWindow, IntPtr.Zero);
AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, true);
SetWindowPos(interopHelper.Handle, new IntPtr(0), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, false);
if (w.WindowState == WindowState.Minimized) w.WindowState = WindowState.Normal;
w.Show();
w.Activate();
}
#region Imports
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
[DllImport("user32.dll")]
private static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
[DllImport("user32.dll")]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
#endregion
}
}
我希望这段代码能够帮助其他遇到这个问题的人。