在做WinFrom开发的时候,很多时候我们想只有一个例程(routine)在运行。就像是设计模式中的Single Pattern,其原理大致相同。
那么我们看一下Single Pattern的实现原理。
在这样的一个最基本的单例模式中,使用了静态变量instance来保存SinglePattern的实例。无论如何在我们的应用程序中都只有一个分instance,并且以此确定了SinglePattern.Instance()方法返回的实例是单一实例。
那么我们又怎么在WinForm中,给Form创建单一的窗口呢?
比葫芦画瓢,我们需要寻找一个跟静态变量类似的东西来确认只有一份存在。
如何用文件实现WinFrom的单例在这儿就不多说了。举例说一下如何使用Mutex实现WinForm的单例。
当名字为testForm的Mutext存在时,isNew为False,否则为True。现在看来实现单例的WinFrom就有了理论依据。但是总部能再WinForm的构造函数中写这样的判断吧,这样只是完成了一个窗口的单例。我们现在想要是应用程序级别的单例。从何处下手呢?
不要着急Main()函数是所有应用程序的入口函数。这要在这里加入判断就行了。
- @H_301_8@usingSystem;
- @H_301_8@usingSystem.Collections.Generic;
- @H_301_8@usingSystem.Linq;
- @H_301_8@usingSystem.Windows.Forms;
- @H_301_8@usingSystem.Runtime.InteropServices;
- @H_301_8@usingSystem.Threading;
- @H_301_8@usingSystem.Diagnostics;
- @H_301_8@namespaceYoung.Winfrom.Singleton
- {
- @H_301_8@static@H_301_8@classProgram
- {
- //把句柄hWnd设置为以cmdShow的模式显示出来
- [DllImport("user32.dll",EntryPoint="ShowWindowAsync")]
- @H_301_8@public@H_301_8@static@H_301_8@extern@H_301_8@intShowWindowAsync(IntPtrhWnd,@H_301_8@intcmdShow);
- //把句柄hWnd放置到所有窗口的最前端
- [DllImport("user32.dll",EntryPoint="SetForegroundWindow")]
- @H_301_8@public@H_301_8@static@H_301_8@extern@H_301_8@intSetForegroundWindow(IntPtrhWnd);
- @H_301_8@staticMutexme;
- @H_301_8@private@H_301_8@const@H_301_8@intSHOWNORMAL=1;//正常显示
- @H_301_8@private@H_301_8@const@H_301_8@intCLOSE=0;//关闭
- @H_301_8@private@H_301_8@const@H_301_8@intMINISIZE=2;//最小化
- @H_301_8@private@H_301_8@const@H_301_8@intMAXSIZE=3;//最大化
- ///<summary>
- ///应用程序的主入口点。
- ///</summary>
- [STAThread]
- @H_301_8@static@H_301_8@voidMain()
- {
- @H_301_8@boolisNew=@H_301_8@false;
- me=@H_301_8@newMutex(@H_301_8@true,@H_301_8@outisNew);
- @H_301_8@if(!isNew)
- {
- Processpro=GetProcess();
- @H_301_8@if(pro!=@H_301_8@null)
- {
- IntPtrfromHandle=pro.MainWindowHandle;
- ShowWindowAsync(fromHandle,SHOWNORMAL);
- SetForegroundWindow(fromHandle);
- }
- @H_301_8@return;
- }
- @H_301_8@else
- {
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(@H_301_8@false);
- Application.Run(@H_301_8@newForm1());
- }
- }
- @H_301_8@staticProcessGetProcess()
- {
- Processpro=Process.GetCurrentProcess();
- @H_301_8@stringcurrent=pro.MainModule.FileName;
- Process[]pros=Process.GetProcessesByName(pro.ProcessName);
- @H_301_8@intl=pros.Length;
- @H_301_8@foreach(Processp@H_301_8@inpros)
- {
- @H_301_8@if(p.MainModule.FileName.Equals(current,StringComparison.CurrentCultureIgnoreCase))
- {
- @H_301_8@if(p.Id!=pro.Id)
- @H_301_8@returnp;
- }
- }
- @H_301_8@return@H_301_8@null;
- }
- }
- }
上边的例子中使用了Windows的API,激活已经启动例程并将窗口移动到最顶端。