在VC++ 中编程中,只运行一个实例的方法主要有两类:
1 遍历当前的所有窗口,查找相同的实例。为了便于查找,一般要事先设一个查找标志。
2 利用系统提供的互斥对象或信标,直接让系统抑制重复的实例。
在发现重复运行时,一般还有一个任务,就是激活已经存在的窗口。
一、 第一类方法的实现
下面是一个具体的例子,下图是示例代码运行的情况。
部分关键代码
1、在App的InitInstance()中枚举所有窗口,查找本程序实例
1 HWND oldHWnd = NULL; 2 3 EnumWindows(EnumWndProc,(LPARAM)&oldHWnd); //枚举所有运行的窗口 4 5 if(oldHWnd != NULL) 6 7 { 8 9 AfxMessageBox("本程序已经在运行了"); 10 11 ::ShowWindow(oldHWnd,SW_SHOWNORMAL); //激活找到的前一个程序 12 13 ::SetForegroundWindow(oldHWnd); //把它设为前景窗口 14 15 return false; //退出本次运行 16 17 }
2、添加EnumWndProc窗口过程函数://通过自定义的属性名查找同类实例窗口
1 CString g_szPropName = "Your Prop Name"; //自己定义一个属性名 2 3 HANDLE g_hValue = (HANDLE)1; //自己定义一个属性值 4 5 6 7 BOOL CALLBACK EnumWndProc(HWND hwnd,LPARAM lParam) 8 9 { 10 11 HANDLE h = GetProp(hwnd,g_szPropName); 12 13 if( h == g_hValue) 14 15 { 16 17 *(HWND*)lParam = hwnd; 18 19 return false; 20 21 } 22 23 return true; 24 25 }
3、在主窗口的 OnInitDialog()中添加属性 //设置窗口属性
1 SetProp(m_hWnd,g_szPropName,g_hValue);
2丶第二种方法:
控制台下:
1 HANDLE Mutex; 2 3 Mutex = CreateMutex(NULL, TRUE, "me"); 4 5 if(GetLastError() == ERROR_ALREADY_EXISTS) 6 7 { 8 9 cout << "only one instance can run!" << endl; 10 11 return 1; 12 13 } 14 15 else 16 17 { 18 19 ReleaseMutex(Mutex); 20 21 }
MFC下:
1 BOOL CtestInfoApp::InitInstance() 2 3 { 4 5 HANDLE Mutex; 6 7 Mutex = CreateMutex(NULL, TRUE, "me"); 8 9 if(GetLastError() == ERROR_ALREADY_EXISTS) 10 11 { 12 13 AfxMessageBox("only one instance can run!"); 14 15 return 0; 16 17 } 18 19 else 20 21 { 22 23 ReleaseMutex(Mutex); 24 25 } 26 27 … 28 29 }