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("置頂應用失敗");
}
}
轉載請注明出處,歡迎交流。