摘要:Process.MainWindowHandle无法获取已最小化的窗口的句柄,可以用FindWindow传入窗口标题文字来获取窗口句柄
我最近做一个软件,需要只有一个进程运行,并且第二次点击程序后,要显示之前运行程序的窗口,再关掉当前进程。
不过在使用Process.MainWindowHandle获取主窗体句柄时,发现无法获取已最小化窗体的句柄
网上找了点资料,发现可以通过WindowsAPI来获取。
思路如下
1.使用Process.GetProcessesByName() 获取已运行的程序进程
2.和当前进程对比,如果id不同,即为之前已开启的程序
3.获取已开启进程的MainWindowHandle,如果为0,则使用FindWindow获取窗口句柄,并用GetWindowThreadProcessId函数来验证句柄属否属于该进程
下面是代码
/// <summary>
/// 根据窗口标题查找窗体
/// </summary>
/// <param name="lpClassName"></param>
/// <param name="lpWindowName"></param>
/// <returns></returns>
[System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
/// <summary>
/// 根据句柄查找进程ID
/// </summary>
/// <param name="hwnd"></param>
/// <param name="ID"></param>
/// <returns></returns>
[System.Runtime.InteropServices.DllImport("User32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
/// <summary>
/// 打开该程序主窗口
/// </summary>
public static void RaiseOtherProcess()
{
System.Diagnostics.Process proc = System.Diagnostics.Process.GetCurrentProcess();
Process[] Proes = System.Diagnostics.Process.GetProcessesByName(proc.ProcessName);
foreach (System.Diagnostics.Process otherProc in Proes)
{
if (proc.Id != otherProc.Id)
{
IntPtr hWnd = otherProc.MainWindowHandle;
if (hWnd.ToInt32() == 0)
{
hWnd = FindWindow(null, "程序主窗口标题");
int id = -1;
GetWindowThreadProcessId(hWnd, out id);
if (id == otherProc.Id)
break;
}
//此处获取的hWnd即为之前运行程序的主窗口句柄,再使用其他函数打开窗体
break;
}
}
}
|