在MFC程序中激活以前的实例,并退出本实例
2011-03-19 10:01
253 查看
本文地址: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 ;
}
要求如下:
只启动一个实例
如果已经启动,则激活以前的实例
实现方法:
程序启动时,首先尝试打开一个命名的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 ;
}
相关文章推荐
- MFC退出程序时进程未终止
- c# 程序只能运行一次(多次运行只能打开同一个程序) 并激活第一个实例,使其获得焦点,并在最前端显示.
- C# 实现程序只启动一次(多次运行激活第一个实例,使其获得焦点,并在最前端显示)
- mfc程序莫名退出了
- VC 实现程序只运行一个实例,并激活已运行的程序
- Android实例-退出程序
- C# 实现程序只启动一次(多次运行激活第一个实例,使其获得焦点,并在最前端显示)
- MFC窗口程序三个退出程序消息:WM_CLOSE、WM_DESTROY、WM_QUIT
- MFC程序带参数运行实例
- vc 防止程序重复运行(即只运行一个实例)并激活已运行进程和枚举进程及窗口
- 深入浅出MFC代码实例1--控制台程序中使用MFC类库
- [Android实例] android2.2退出程序的例子
- vc2010使用CMFCEditBrowseCtrl控件导致程序退出崩溃解决
- MFC程序只运行一个实例
- MFC回车键和Esc键默认退出程序的问题
- MFC防止enter和ESC键使程序退出方法
- 程序只运行一个实例,并激活前一个实例
- MFC 激活已在运行实例
- C# 实现程序只启动一次(多次运行激活第一个实例,使其获得焦点,并在最前端显示)
- MFC对话框退出程序所调用的函数