Windows任务管理器是单例模式的一个很好的例子,在当前登录用户下我们只能打开一个它的实例。如它没有运行,点击“任务管理器”会启动这个程序,如果最小化了,点击“任务管理器”会激活它并显示在最小化之前的位置;如果当前激活并显示,会重新激活。这篇文章将要介绍在WinForm应用程序中如何实现这一模式。
大多数的winform程序实现这一效果都采用了互斥体,我们这里也不例外,只不过更加完善了。
1、首先创建一个WinForm应用程序,设计窗体:
2、 获取并保存窗口句柄
为了方便控制窗口,每次窗体打开时,我们还需要记录窗口的句柄。
记录到Settings.settings中是一个不错的方法 。
当用户双击程序图标或者调用程序启动命令后,程序首先需要判断是不是可以拥有互斥体初始所有权,如果OK,则启动窗口;
如果不OK,则判断窗口是否最小化了,如果最小化,则激活并显示窗口;如果正常显示,则重新激活窗口。
看看代码吧:
//该函数设置由不同线程产生的窗口的显示状态; [DllImport("user32.dll")] private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); //判断窗口是否已最小化 [DllImport("user32.dll")] private static extern bool IsIconic(IntPtr hWnd) private const int SW_SHOW = 5;//激活窗口的命令代码 private const int SW_RESTORE = 9;//从最小化恢复时的命令代码 /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { bool initiallyOwned = true;//是否应拥有互斥体的初始所有权 bool bCreatedNew = false;//是否被授予互斥体的初始所有权 //初始化互斥体 Mutex m = new Mutex(initiallyOwned, "TTAPasswordBox", out bCreatedNew); //如果为false,则程序已经启动 if (!(initiallyOwned && bCreatedNew)) { m.Close(); //获取窗口的句柄 Settings s = new Settings(); IntPtr i = (IntPtr)s.CurrentIntPtr; if (IsIconic(i))//如果窗口是最小化状态,激活并显示窗口 { ShowWindowAsync(i, SW_RESTORE); } else//如果不是最小化状态,弹出提示,并设置窗口 { //这个提示不是必要的 MessageBox.Show(new WindowWrapper(i), "程序已经运行,请勿重复启动!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error); ShowWindowAsync(i, SW_SHOW); } } else//可以启动程序 { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Form1 login = new Form1(); Application.Run(new Form1()); //释放互斥体 m.ReleaseMutex(); } } } /// <summary> /// 包装一个窗口,公开Win32句柄 /// </summary> public class WindowWrapper : System.Windows.Forms.IWin32Window { public WindowWrapper(IntPtr handle) { _hwnd = handle; } public IntPtr Handle { get { return _hwnd; } } private IntPtr _hwnd; }
这里调用了几个Windows的API,用于判断及设置窗口状态,参数用到了前边设置的窗口句柄:CurrentIntPtr。
4、现在运行程序就能看到效果了。
最后,点击这里下载这个例子
发表评论
相关文章
国内AI资源汇总,AI聊天、AI绘画、AI写作、AI视频、AI设计、AI编程、AI音乐等,国内顺畅访问,无需科学上网。
扫码或点击进入:萤火AI大全
文章分类
最新评论