在网上找了很久的单实例运行解决方法,一般都是一样的思路,我们先看看代码:
HANDLE m_hMutex = ::CreateMutex(NULL, TRUE, "MyApp");
if (GetLastError() == ERROR_ALREADY_EXISTS) //程序已经运行
{
AfxMessageBox(“该程序已运行”);
return FALSE;
}else{ //程序还未运行
//创建主窗口
return FALSE;
}
上面的代码是为程序建立一把锁,如果该锁存在就表示已有实例在运行,但我们更多的是希望如果已有实例存在则显示已存在的实例而不是提示我们,前段时间做一个软件刚好需要单实例运行(现在很多软件也是单实例运行的),已存在则显示。
我们把上面的代码修改如下:
HANDLE m_hMutex = ::CreateMutex(NULL, TRUE, "MyApp");
if (GetLastError() == ERROR_ALREADY_EXISTS) //程序已经运行
{
HWND oldHWnd = NULL;
//查找已经运行的程序
oldHWnd = ::FindWindow(NULL, "MyApp");
//如果存在已运行的实例
if (oldHWnd)
{
//激活显示找到的已运行的程序
::ShowWindow(oldHWnd,SW_SHOWNORMAL);
//将已运行的程序设置为当前窗口
::SetForegroundWindow(oldHWnd);
}
CloseHandle(m_hMutex);
m_hMutex = NULL;
return FALSE;
}else{ //程序还未运行
//创建主窗口
return FALSE;
}
以上代码便可实现上面要求的效果。这里关键的函数是Win API函数:查找窗口函数FindWindow,MSDN解析如下:
CWnd::FindWindow
static CWnd* PASCAL FindWindow( LPCTSTR lpszClassName, LPCTSTR lpszWindowName );
Return Value
Identifies the window that has the specified class name and window name. It is NULL if no such window is found.
The CWnd* may be temporary and should not be stored for later use.
Parameters
lpszClassName
Points to a null-terminated string that specifies the window’s class name (a WNDCLASS structure). If lpClassName is NULL, all class names match.
lpszWindowName
Points to a null-terminated string that specifies the window name (the window’s title). If lpWindowName is NULL, all window names match.
Remarks
Returns the top-level CWnd whose window class is given by lpszClassName and whose window name, or title, is given by lpszWindowName. This function does not search child windows.
貌似在网上也看到其他解决办法,不过现在记不起来了。