Skip to content

Commit 016fa4b

Browse files
authored
Merge pull request #467 from HandyOrg/pr/458
Pr/458
2 parents db8ce28 + 652bdf9 commit 016fa4b

3 files changed

Lines changed: 46 additions & 7 deletions

File tree

src/Shared/HandyControl_Shared/Interactivity/Commands/PushMainWindow2TopCommand.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
using System;
22
using System.Windows;
33
using System.Windows.Input;
4-
using System.Windows.Interop;
5-
using HandyControl.Tools.Interop;
4+
using HandyControl.Tools;
65

76
namespace HandyControl.Interactivity
87
{
@@ -15,11 +14,7 @@ public void Execute(object parameter)
1514
if (Application.Current.MainWindow != null && Application.Current.MainWindow.Visibility != Visibility.Visible)
1615
{
1716
Application.Current.MainWindow.Show();
18-
var hwndSource = (HwndSource)PresentationSource.FromDependencyObject(Application.Current.MainWindow);
19-
if (hwndSource != null)
20-
{
21-
InteropMethods.SetForegroundWindow(hwndSource.Handle);
22-
}
17+
WindowHelper.SetWindowToForeground(Application.Current.MainWindow);
2318
}
2419
}
2520

src/Shared/HandyControl_Shared/Tools/Helper/WindowHelper.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,5 +152,42 @@ public static Thickness WindowMaximizedPadding
152152
public static IntPtr GetHandle(this Window window) => new WindowInteropHelper(window).EnsureHandle();
153153

154154
public static HwndSource GetHwndSource(this Window window) => HwndSource.FromHwnd(window.GetHandle());
155+
156+
/// <summary>
157+
/// 让窗口激活作为前台最上层窗口
158+
/// </summary>
159+
/// <param name="window"></param>
160+
public static void SetWindowToForeground(Window window)
161+
{
162+
// [WPF 让窗口激活作为前台最上层窗口的方法 - lindexi - 博客园](https://www.cnblogs.com/lindexi/p/12749671.html)
163+
var interopHelper = new WindowInteropHelper(window);
164+
var thisWindowThreadId = InteropMethods.GetWindowThreadProcessId(interopHelper.Handle, out _);
165+
var currentForegroundWindow = InteropMethods.GetForegroundWindow();
166+
var currentForegroundWindowThreadId = InteropMethods.GetWindowThreadProcessId(currentForegroundWindow, out _);
167+
168+
// [c# - Bring a window to the front in WPF - Stack Overflow](https://stackoverflow.com/questions/257587/bring-a-window-to-the-front-in-wpf )
169+
// [SetForegroundWindow的正确用法 - 子坞 - 博客园](https://www.cnblogs.com/ziwuge/archive/2012/01/06/2315342.html )
170+
/*
171+
  1.得到窗口句柄FindWindow
172+
    2.切换键盘输入焦点AttachThreadInput
173+
    3.显示窗口ShowWindow(有些窗口被最小化/隐藏了)
174+
    4.更改窗口的Z Order,SetWindowPos使之最上,为了不影响后续窗口的Z Order,改完之后,再还原
175+
    5.最后SetForegroundWindow
176+
*/
177+
178+
InteropMethods.AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, true);
179+
180+
window.Show();
181+
window.Activate();
182+
// 去掉和其他线程的输入链接
183+
InteropMethods.AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, false);
184+
185+
// 用于踢掉其他的在上层的窗口
186+
if (window.Topmost != true)
187+
{
188+
window.Topmost = true;
189+
window.Topmost = false;
190+
}
191+
}
155192
}
156193
}

src/Shared/HandyControl_Shared/Tools/Interop/InteropMethods.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ internal static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddr
4343
[DllImport(InteropValues.ExternDll.User32, SetLastError = true, CharSet = CharSet.Auto)]
4444
internal static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
4545

46+
[DllImport(InteropValues.ExternDll.User32, SetLastError = true, CharSet = CharSet.Auto)]
47+
internal static extern bool AttachThreadInput(in uint currentForegroundWindowThreadId,
48+
in uint thisWindowThreadId, bool isAttach);
49+
50+
[DllImport(InteropValues.ExternDll.User32, SetLastError = true, CharSet = CharSet.Auto)]
51+
internal static extern IntPtr GetForegroundWindow();
52+
4653
[DllImport(InteropValues.ExternDll.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
4754
internal static extern IntPtr OpenProcess(InteropValues.ProcessAccess dwDesiredAccess,
4855
[MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessId);

0 commit comments

Comments
 (0)