ccrun(老妖)提供的
一、通过创建互斥量来判断:
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
HANDLE hMutex = CreateMutex(NULL, TRUE, "MyAppMutex");
if(NULL == hMutex)
{
MessageBox(NULL, "创建Mutex失败!",
Application->Title.c_str(), MB_OK | MB_SYSTEMMODAL);
return 0;
}
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
::MessageBox(NULL, "已经运行了一个实例!",
Application->Title.c_str(), MB_OK | MB_SYSTEMMODAL);
ReleaseMutex(hnd);
return 0;
}
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
return 0;
}
二、用系统原子
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
const char *Atom = "SingleApp";
try
{
if (GlobalFindAtom(Atom) != 0) // 在系统原子表中找原子
{
::MessageBox(NULL, "已经运行了一个实例!",
Application->Title.c_str(), MB_OK | MB_SYSTEMMODAL);
return 0;
}
GlobalAddAtom(Atom); // 增加原子
Application->Initialize();
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
GlobalDeleteAtom(GlobalFindAtom(Atom)); // 删除原子
return 0;
}
三、通过FindWindow函数来判断:
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
HWND hForm = FindWindow("TForm1", "Form1");
if(NULL != hForm)
{
::MessageBox(NULL, "已经运行了一个实例!",
Application->Title.c_str(), MB_OK | MB_SYSTEMMODAL);
return 0;
}
Application->Initialize();
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
return 0;
}
四、通过内存映射来还原窗口:
PHANDLE lpMainWin;
HANDLE hMap;
bool bExist;
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
hMap = CreateFileMapping(
(HANDLE)0xFFFFFFFF, // 要映射的文件名,使用0xFFFFFFFF是说明不使用真实文件,而是在页面文件上创建内存
NULL, // 安全属性
PAGE_READWRITE, // 访问权限,读写都要
0, // 最大内存的高位
4, // 最大内存的低位,最大内存有4字节就够了,只需要放一个窗体的句柄
"MyProjectFlag" // 映射名字,这个应该是本程序独有的,和其他程序不冲突,由调用者传进来
);
bExist = GetLastError() == ERROR_ALREADY_EXISTS;
// 创建一个文件映射的访问
lpMainWin = (PHANDLE)MapViewOfFile(
hMap, // 文件映射的句柄
FILE_MAP_ALL_ACCESS, // 访问权限,读写都要,这个要和文件映射的权限兼容
0, // 偏移量的高位
0, // 偏移量的低位
4 // 要映射的字节数
);
if(lpMainWin == NULL)
bExist = false;
if(bExist)
{
if(!IsWindowVisible(*lpMainWin))
// 如果最小化状态就将窗体恢复
PostMessage(*lpMainWin, WM_SYSCOMMAND, SC_RESTORE, 0);
// 窗体置前
SetForegroundWindow(*lpMainWin);
BringWindowToTop(*lpMainWin);
UnmapViewOfFile(lpMainWin);
return 0;
}
try
{
Application->Initialize();
Application->CreateForm(__classid(TForm1), &Form1);
*lpMainWin = Application->MainForm->Handle;
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
// 关闭映射的访问
UnmapViewOfFile(lpMainWin);
return 0;
}