Win32 提供了 SetForegroundWindow 办法能够将利用设置到前台并激活,然而在某些场景下,只调用该接口会返回 0,即设置失败。比方如下场景:
以后前台利用为一个全屏的利用,非前台利用的过程应用 Process.Start()
办法启动截图工具,尝试应用 SetForegroundWindow()
将窗口设置到前台,此时会概率性设置失败。
尝试了多种办法后,最终应用如下办法解决了该问题:
public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
public const int SWP_NOSIZE = 0x1;
public const int SWP_NOMOVE = 0x2;
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hwnd);
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern bool SetWindowPos(IntPtr hwnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
public void StartSnippingTool()
{if (!Envronment.Is64BitProcess)
{Process.Start(@"C:\Windows\sysnative\SnippingTool.exe");
}
else
{Process.Start(@"C:\Windows\system32\SnippingTool.exe");
}
Thread.Sleep(500);
IntPtr snippingToolHandle = FindWindow("Microsoft-Windows-SnipperToolbar", "截图工具");
if (snippingToolHandle != IntPtr.Zero)
{SetForegroundWindowCustom(snippingToolHandle);
}
}
private void SetForegroundWindowCustom(IntPtr hwnd)
{IntPtr currentWindow = GetForegroundWindow();
if (currentWindow == hwnd)
{Console.WriteLine("利用已在顶层");
return;
}
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
bool result = SetForegroundWindow(hwnd);
if (result)
{Console.WriteLine("置顶利用胜利");
}
else
{Console.WriteLine("置顶利用失败");
}
}