方法一:
首先定义一个共享数据段(在所有函数是外面):例如
#pragma data_seg("OnlyYou")//自己定义了一个共享数据段
long lInstanceCount=-1;
#pragma data_seg()
#pragma comment(linker,"/section:OnlyYou,rws")//意思:read write shared
然后在::InitInstance中,使用Win32函数InterlockedIncrement和InterlockedDecrement来控制记数。这两个函数要求使用长整型。它们还解决了多进程。线程情况下的对数局的互斥保护。
下面在程序初始化阶段,如CWinApp派生类的InitInstance成员函数开始处,添加以下代码判断:
BOOL bFirstInstance=(InterlockedIncrement(&lInstanceCount)==0);
if(!bFirstInstance)
{
AfxMessageBox("该程序已经执行!终止此次执行.",MB_OK|MB_ICONSTOP);
//InterlockedDecrement(&lInstanceCount);
return FALSE;
}
AfxMessageBox("这是首次运行该程序!",MB_OK|MB_ICONINFORMATION);
。。。。
在程序正常处理结束后,还要调用
InterlockedDecrement(&lInstanceCount);减少程序实例的记数。
对于一般程序在CWinApp派生类的ExitInstance成员函数中调用。对于对话框程序,在InitInstance函数中对话框返回后结束程序就将结束了,所以在InitInstance成员函数的最后调用。
方法二:利用互斥体
1)定义一个唯一的常量:
#define UNIQE_NAME "{F5EFF561-ECB3-11d1-A18D-DCB3C85EBD34}"
2) 在InitInstance ( )中创建互斥体
使用上面在应用程序类的InitInstance()函数的开始处定义的名字来创建一个互斥体,并保存该互斥体的句柄—在关闭互斥体时还要用到该句柄。如果应用程序的另一个实例已经存在,::CreatMutex ()函数就会给由其他实例创建的互斥体返回一个句柄,而不是再创建一个新的句柄。为了确定该句柄是否为应用程序已经运行的实例的互斥体的句柄,可以调用GetLastError()函数,如果是,则该函数将返回一个ERROR_ALREADY_EXISTS错误。可以通过退出InitInstance()函数返回一个FALSE值来终止应用程序的运行。以下代码说明了上述过程是如何完成的:
3) 关闭互斥体
使用Class Wizard 重载应用程序类的ExitInstance()函数,同时关闭该互斥体的句柄: