使用互斥对象让应用程序只有一个可以运行,如何让已经运行的应用程序获得焦点?

时间:2021-09-18 21:33:54
BOOL CMYApp::InitInstance()
{
        //在此处加入检测,让应用程序只有一个可以运行
//创建互斥对象
hMutex=CreateMutex(NULL,TRUE,"one_times");
if(hMutex)
{
if(ERROR_ALREADY_EXISTS==GetLastError())
{
     AfxMessageBox(_T("程序已经运行"));
      //如何让运行的程序获得激活 ??
     return FALSE;
}
}
}

10 个解决方案

#1


BringWindowToTop

#2


EnumWindows发现原来的实例句柄
SetForegroundWindow激活

#3


整个过程我重新描述一下:
在第一次运行应用程序时,依据one_times创建的互斥量不会产生ERROR_ALREADY_EXISTS的,因此应用程序正常执行,不会弹出对话框,也不会return.
在第一个应用程序没有退出时,当用户重新再次运行这个应用程序的时候,依据one_times创建的互斥量将产生ERROR_ALREADY_EXISTS的,再次运行的应用程序会弹出对话框,将return.

我希望在第二个应用程序退出之前,让第一个应用程序,获得焦点并显示在屏幕上,采用什么方法可以实现?

#4



while(::IsWindow(hWndPrev))
{
//判断窗口是否有我们预先设置的标记,如有,则是我们寻找的窗口,并将它激活。
if(::GetProp(hWndPrev,"Devang")) 
{
//如果主窗口已最小化,则恢复其大小。
if (::IsIconic(hWndPrev)) 
::ShowWindow(hWndPrev,SW_RESTORE);

//将应用程序的主窗口激活。
::SetForegroundWindow(hWndPrev);
return FALSE; //退出实例。
}
//继续寻找下一个窗口。
hWndPrev = ::GetWindow(hWndPrev,GW_HWNDNEXT); 
}

#5


楼上少了一行



//获取桌面窗口的一个子窗口。
HWND hWndPrev=::GetWindow(::GetDesktopWindow(),GW_CHILD); 

while(::IsWindow(hWndPrev))
{
//判断窗口是否有我们预先设置的标记,如有,则是我们寻找的窗口,并将它激活。
if(::GetProp(hWndPrev,"Devang")) 
{
//如果主窗口已最小化,则恢复其大小。
if (::IsIconic(hWndPrev)) 
::ShowWindow(hWndPrev,SW_RESTORE);

//将应用程序的主窗口激活。
::SetForegroundWindow(hWndPrev);
return FALSE; //退出实例。
}
//继续寻找下一个窗口。
hWndPrev = ::GetWindow(hWndPrev,GW_HWNDNEXT); 
}

#6


请问(::GetProp(hWndPrev,"Devang")中的预先设置的标记 "Devang",指的什么,如何预先设置该标记 

#7


你不是已经实现了吗???




//创建命名信标对象。
HANDLE hSem=CreateSemaphore(NULL,1,1,"Devang");
if(hSem) //信标对象创建成功。
{
//信标对象已经存在,则程序已有一个实例在运行。
if(ERROR_ALREADY_EXISTS==GetLastError())

CloseHandle(hSem); //关闭信号量句柄。 

//获取桌面窗口的一个子窗口。
HWND hWndPrev=::GetWindow(::GetDesktopWindow(),GW_CHILD); 

while(::IsWindow(hWndPrev))
{
//判断窗口是否有我们预先设置的标记,如有,则是我们寻找的窗口,并将它激活。
if(::GetProp(hWndPrev,"Devang")) 
{
//如果主窗口已最小化,则恢复其大小。
if (::IsIconic(hWndPrev)) 
::ShowWindow(hWndPrev,SW_RESTORE);

//将应用程序的主窗口激活。
::SetForegroundWindow(hWndPrev);
return FALSE; //退出实例。
}
//继续寻找下一个窗口。
hWndPrev = ::GetWindow(hWndPrev,GW_HWNDNEXT); 
}

AfxMessageBox("已有一个实例在运行,但找不到它的主窗口!");
}
}
else
{
AfxMessageBox("创建信标对象失败,程序退出!");
return FALSE;
}



#8


SetForegroundWindow

#9


我采用的互斥对象,调试发现

 //判断窗口是否有我们预先设置的标记,如有,则是我们寻找的窗口,并将它激活。
                if(::GetProp(hWndPrev,"one_times")) 
                {
                    //如果主窗口已最小化,则恢复其大小。
                    if (::IsIconic(hWndPrev)) 
                        ::ShowWindow(hWndPrev,SW_RESTORE);
                    
                    //将应用程序的主窗口激活。
                    ::SetForegroundWindow(hWndPrev);
                    return FALSE; //退出实例。
                }

无法进入该if语句,因此
                 //将应用程序的主窗口激活。
                    ::SetForegroundWindow(hWndPrev);
                    return FALSE; //退出实例。
程序语句没有执行,是不是这个预先设置的标记,采用我的方式不正确?

#10


多谢以上各位的帮助.
尤其感谢Devang 的帮助与提醒.

在程序中增加下面代码后,问题解决了. 多谢各位了

在框架类的OnCreate()函数中设置查找标记。 
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 


   //设置查找标记。 
   ::SetProp(m_hWnd,"Devang"",(HANDLE)1); 

   return 0; 


在程序退出是删除设置的标记,在框架类中响应WM_DESTROY消息,进行处理。 
void CMainFrame::OnDestroy() 

CFrameWnd::OnDestroy(); 

// TODO: Add your message handler code here 
//删除所设置的标记。 
::RemoveProp(m_hWnd,"Devang""); 

#1


BringWindowToTop

#2


EnumWindows发现原来的实例句柄
SetForegroundWindow激活

#3


整个过程我重新描述一下:
在第一次运行应用程序时,依据one_times创建的互斥量不会产生ERROR_ALREADY_EXISTS的,因此应用程序正常执行,不会弹出对话框,也不会return.
在第一个应用程序没有退出时,当用户重新再次运行这个应用程序的时候,依据one_times创建的互斥量将产生ERROR_ALREADY_EXISTS的,再次运行的应用程序会弹出对话框,将return.

我希望在第二个应用程序退出之前,让第一个应用程序,获得焦点并显示在屏幕上,采用什么方法可以实现?

#4



while(::IsWindow(hWndPrev))
{
//判断窗口是否有我们预先设置的标记,如有,则是我们寻找的窗口,并将它激活。
if(::GetProp(hWndPrev,"Devang")) 
{
//如果主窗口已最小化,则恢复其大小。
if (::IsIconic(hWndPrev)) 
::ShowWindow(hWndPrev,SW_RESTORE);

//将应用程序的主窗口激活。
::SetForegroundWindow(hWndPrev);
return FALSE; //退出实例。
}
//继续寻找下一个窗口。
hWndPrev = ::GetWindow(hWndPrev,GW_HWNDNEXT); 
}

#5


楼上少了一行



//获取桌面窗口的一个子窗口。
HWND hWndPrev=::GetWindow(::GetDesktopWindow(),GW_CHILD); 

while(::IsWindow(hWndPrev))
{
//判断窗口是否有我们预先设置的标记,如有,则是我们寻找的窗口,并将它激活。
if(::GetProp(hWndPrev,"Devang")) 
{
//如果主窗口已最小化,则恢复其大小。
if (::IsIconic(hWndPrev)) 
::ShowWindow(hWndPrev,SW_RESTORE);

//将应用程序的主窗口激活。
::SetForegroundWindow(hWndPrev);
return FALSE; //退出实例。
}
//继续寻找下一个窗口。
hWndPrev = ::GetWindow(hWndPrev,GW_HWNDNEXT); 
}

#6


请问(::GetProp(hWndPrev,"Devang")中的预先设置的标记 "Devang",指的什么,如何预先设置该标记 

#7


你不是已经实现了吗???




//创建命名信标对象。
HANDLE hSem=CreateSemaphore(NULL,1,1,"Devang");
if(hSem) //信标对象创建成功。
{
//信标对象已经存在,则程序已有一个实例在运行。
if(ERROR_ALREADY_EXISTS==GetLastError())

CloseHandle(hSem); //关闭信号量句柄。 

//获取桌面窗口的一个子窗口。
HWND hWndPrev=::GetWindow(::GetDesktopWindow(),GW_CHILD); 

while(::IsWindow(hWndPrev))
{
//判断窗口是否有我们预先设置的标记,如有,则是我们寻找的窗口,并将它激活。
if(::GetProp(hWndPrev,"Devang")) 
{
//如果主窗口已最小化,则恢复其大小。
if (::IsIconic(hWndPrev)) 
::ShowWindow(hWndPrev,SW_RESTORE);

//将应用程序的主窗口激活。
::SetForegroundWindow(hWndPrev);
return FALSE; //退出实例。
}
//继续寻找下一个窗口。
hWndPrev = ::GetWindow(hWndPrev,GW_HWNDNEXT); 
}

AfxMessageBox("已有一个实例在运行,但找不到它的主窗口!");
}
}
else
{
AfxMessageBox("创建信标对象失败,程序退出!");
return FALSE;
}



#8


SetForegroundWindow

#9


我采用的互斥对象,调试发现

 //判断窗口是否有我们预先设置的标记,如有,则是我们寻找的窗口,并将它激活。
                if(::GetProp(hWndPrev,"one_times")) 
                {
                    //如果主窗口已最小化,则恢复其大小。
                    if (::IsIconic(hWndPrev)) 
                        ::ShowWindow(hWndPrev,SW_RESTORE);
                    
                    //将应用程序的主窗口激活。
                    ::SetForegroundWindow(hWndPrev);
                    return FALSE; //退出实例。
                }

无法进入该if语句,因此
                 //将应用程序的主窗口激活。
                    ::SetForegroundWindow(hWndPrev);
                    return FALSE; //退出实例。
程序语句没有执行,是不是这个预先设置的标记,采用我的方式不正确?

#10


多谢以上各位的帮助.
尤其感谢Devang 的帮助与提醒.

在程序中增加下面代码后,问题解决了. 多谢各位了

在框架类的OnCreate()函数中设置查找标记。 
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 


   //设置查找标记。 
   ::SetProp(m_hWnd,"Devang"",(HANDLE)1); 

   return 0; 


在程序退出是删除设置的标记,在框架类中响应WM_DESTROY消息,进行处理。 
void CMainFrame::OnDestroy() 

CFrameWnd::OnDestroy(); 

// TODO: Add your message handler code here 
//删除所设置的标记。 
::RemoveProp(m_hWnd,"Devang"");