本文地址:http://www.starsdust.info/blog/
要求如下:
只启动一个实例
如果已经启动,则激活以前的实例
实现方法:
程序启动时,首先尝试打开一个命名的CEvent对象,如果打开失败,说明本程序是第一次启动,启动一个等待线程,监视CEvent对象状态。如果打开成功,说明本程序已经在运行。此时,设置这个CEvent对象为有信号状态,监视线程检测到信号,激活自己。
实现代码:
比如新建项目 Demo
在CDemoApp类中,增加如下代码
static void DoggerThread(CDemoApp* pApp);// 线程
HANDLE m_hThread;
BOOL b_running;
在CDemoApp.h中,全局声明 HANDLE hEvent = NULL;
在InitInstance函数开始处,
TCHAR module_name[MAX_PATH];
memset(module_name,'/0',MAX_PATH);
::GetModuleFileName(NULL,module_name,MAX_PATH);
CString str;
str.Format(_T("__Hamkoo_%s"),module_name);
str.Replace(_T("//"),_T("_"));
//CEvent m_event(TRUE,FALSE,(LPCTSTR)str,NULL);
hEvent = OpenEvent(EVENT_ALL_ACCESS,FALSE,str);
if (hEvent == NULL)
{
hEvent = CreateEvent(NULL,FALSE,FALSE,str);
if (hEvent == NULL)
{
return FALSE;
}
else // 创建成功
{
//::SetEvent();
// 启动监视线程
this->b_running = TRUE;
m_hThread = ::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)DoggerThread,this,NULL,NULL);
}
}
else
{
// 设置事件状态
::SetEvent(hEvent);
// 结束本程序
return FALSE;
}
在return FALSE前,增加
this->b_running = FALSE;
::SetEvent(hEvent);// 退出线程
CloseHandle(m_hThread);
CloseHandle(hEvent);
在Demo.cpp最后,添加线程函数
void CDemoApp::DoggerThread(CDemoApp* pApp)
{
if(!pApp) return;
while ( pApp->b_running )
{
// 等待
DWORD rtn = ::WaitForSingleObject(hEvent,INFINITE);
if (!pApp->b_running) break;
if (rtn == WAIT_OBJECT_0)
{
::LockSetForegroundWindow(LSFW_UNLOCK);
::SetForegroundWindow(pApp->m_pMainWnd->GetSafeHwnd());
keybd_event( VK_MENU,0,0,0 );
keybd_event( VK_TAB,0,0,0 );
//Sleep(10);
keybd_event( VK_TAB,0,KEYEVENTF_KEYUP,0);
keybd_event( VK_MENU,0,KEYEVENTF_KEYUP,0);
::SetForegroundWindow(pApp->m_pMainWnd->GetSafeHwnd());
}
}
return ;
}