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大全
文章分类
最新评论