Winform应用程序的单一例程

在做WinFrom开发的时候,很多时候我们想只有一个例程(routine)在运行。就像是设计模式中的Single Pattern,其原理大致相同。

那么我们看一下Single Pattern的实现原理。

  
  
  
  
  1. public class SinglePattern  
  2. {  
  3.     private static SinglePattern instance = null;  
  4.  
  5.     public static SinglePattern Instance()  
  6.     {  
  7.         if (instance == null)  
  8.         {  
  9.             instance = new SinglePattern();  
  10.         }  
  11.         return instance;  
  12.     }  

在这样的一个最基本的单例模式中,使用了静态变量instance来保存SinglePattern的实例。无论如何在我们的应用程序中都只有一个分instance,并且以此确定了SinglePattern.Instance()方法返回的实例是单一实例。

那么我们又怎么在WinForm中,给Form创建单一的窗口呢?

比葫芦画瓢,我们需要寻找一个跟静态变量类似的东西来确认只有一份存在。

  1. 文件系统中的文件,统一路径下没有重名的文件(包含扩展名)。
  2. 多线程中的Mutex,在操作系统级别也是唯一的。

如何用文件实现WinFrom的单例在这儿就不多说了。举例说一下如何使用Mutex实现WinForm的单例。

  
  
  
  
  1. bool isNew = false;  
  2. Mutex mutext = new Mutex(true"testFrom"out isNew); 

当名字为testForm的Mutext存在时,isNew为False,否则为True。现在看来实现单例的WinFrom就有了理论依据。但是总部能再WinForm的构造函数中写这样的判断吧,这样只是完成了一个窗口的单例。我们现在想要是应用程序级别的单例。从何处下手呢?

不要着急Main()函数是所有应用程序的入口函数。这要在这里加入判断就行了。

  
  
  
  
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Windows.Forms;  
  5. using System.Runtime.InteropServices;  
  6. using System.Threading;  
  7. using System.Diagnostics;  
  8.  
  9. namespace Young.Winfrom.Singleton  
  10. {  
  11.     static class Program  
  12.     {  
  13.         //把句柄hWnd设置为以cmdShow的模式显示出来  
  14.         [DllImport("user32.dll", EntryPoint = "ShowWindowAsync")]  
  15.         public static extern int ShowWindowAsync(IntPtr hWnd, int cmdShow);  
  16.  
  17.         //把句柄hWnd放置到所有窗口的最前端  
  18.         [DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]  
  19.         public static extern int SetForegroundWindow(IntPtr hWnd);  
  20.  
  21.         static Mutex me;  
  22.  
  23.         private const int SHOWNORMAL = 1;     //正常显示  
  24.         private const int CLOSE = 0;                      //关闭  
  25.         private const int MINISIZE = 2;                  //最小化  
  26.         private const int MAXSIZE = 3;                  //最大化  
  27.  
  28.         /// <summary>  
  29.         /// 应用程序的主入口点。  
  30.         /// </summary>  
  31.         [STAThread]  
  32.         static void Main()  
  33.         {  
  34.             bool isNew = false;  
  35.             me = new Mutex(true"testFrom"out isNew);  
  36.  
  37.             if (!isNew)  
  38.             {  
  39.                 Process pro = GetProcess();  
  40.                 if (pro != null)  
  41.                 {  
  42.                     IntPtr fromHandle = pro.MainWindowHandle;  
  43.                     ShowWindowAsync(fromHandle, SHOWNORMAL);  
  44.                     SetForegroundWindow(fromHandle);  
  45.                 }  
  46.                 return;  
  47.             }  
  48.             else 
  49.             {  
  50.                 Application.EnableVisualStyles();  
  51.                 Application.SetCompatibleTextRenderingDefault(false);  
  52.                 Application.Run(new Form1());  
  53.             }  
  54.  
  55.  
  56.  
  57.         }  
  58.  
  59.         static Process GetProcess()  
  60.         {  
  61.             Process pro = Process.GetCurrentProcess();  
  62.             string current = pro.MainModule.FileName;  
  63.             Process[] pros = Process.GetProcessesByName(pro.ProcessName);  
  64.             int l = pros.Length;  
  65.             foreach (Process p in pros)  
  66.             {  
  67.                 if (p.MainModule.FileName.Equals(current, StringComparison.CurrentCultureIgnoreCase))  
  68.                 {  
  69.                     if (p.Id != pro.Id)  
  70.                         return p;  
  71.                 }  
  72.             }  
  73.             return null;  
  74.         }  
  75.     }  
  76. }  

上边的例子中使用了Windows的API,激活已经启动例程并将窗口移动到最顶端。

本文出自 “李阳” 博客,谢绝转载!

你可能感兴趣的:(单例模式,职场,休闲,应用程序的单例,激活窗口)