vc++禁止重复运行实例并显示(激活)原来窗口

来源:赵克立博客 分类: C/C++ 标签:C/C++发布时间:2014-07-11 13:07:00最后更新:2017-10-28 10:39:10浏览:2441
版权声明:
本文为博主原创文章,转载请声明原文链接...谢谢。o_0。
更新时间:
2017-10-28 10:39:10
温馨提示:
学无止境,技术类文章有它的时效性,请留意文章更新时间,如发现内容有误请留言指出,防止别人"踩坑",我会及时更新文章

第一种方法  

最简单的方法,查找对应的主窗口类,如果存在就显示原来的,退出现在的窗口

HWND hwnd = ::FindWindow(_T("SendHttpRequestWnd"), NULL);
if (hwnd != NULL) {
    
    //如果主窗口已最小化,则恢复其大小。 
    if (::IsIconic(hwnd))
        ::ShowWindow(hwnd, SW_RESTORE);
    //窗口是否显示
    if(!::IsWindowVisible(hwnd))
        ::ShowWindow(hwnd, SW_SHOWNORMAL);
    //将应用程序的主窗口激活。 
    ::SetForegroundWindow(hwnd);
    return 0;
}

注:如果你有很严格的要求的话此方法也不太适用,因为可能找到多个一样类名的窗口;

第二种方法 

使用互斥对象判断程序是不是重复运行,程序运行时加上下面代码就可以限制程序重复运行

//创建一个名字为norepeat的互斥对象,名字可以自己取,越长越好,再次运行如果已经创建过就会有错误信息
HANDLE m_hMutex=::CreateMutex(NULL,true,"norepeat");
if(m_hMutex){
    if(ERROR_ALREADY_EXISTS==GetLastError()) 
    {
        ::MessageBox(NULL,"程序已经运行",NULL,0);
        //SendMessage(WM_SYSCOMMAND,SC_MINIMIZE,0);
        m_hMutex=NULL;
        return false;
    }
}

需要把原来的窗口激活,使用第一个方法的查找窗口类可以实现,另外也可以使用一个信标对象标记运行的程序

首先在窗口WM_CREATE创建的时候设置一个信标对象,如下:

//设置程序运行标记
::SetProp(m_hWnd,"重复运行标记",(HANDLE)1);

   然后要记着要窗口WM_DESTORY销毁的时候把信标对象移除掉,如下:

//移除标记
::RemoveProp(m_hWnd,"重复运行标记");

   最后在程序入口处添加下面代码遍历桌面窗口进行拦截就ok啦 

//获取桌面窗口的一个子窗口。 
HWND hWndPrev = ::GetWindow(::GetDesktopWindow(), GW_CHILD);
while (::IsWindow(hWndPrev))
{
    //判断窗口是否有我们预先设置的标记,如有,则是我们寻找的窗口,并将它激活。 
    if (::GetProp(hWndPrev, "SendHttpRequest"))
    {
        //如果主窗口已最小化,则恢复其大小。 
        if (::IsIconic(hWndPrev))
            ::ShowWindow(hWndPrev, SW_RESTORE);
        //窗口是否显示
        if (!::IsWindowVisible(hWndPrev))
            ::ShowWindow(hWndPrev, SW_SHOWNORMAL);
        //将应用程序的主窗口激活。 
        ::SetForegroundWindow(hWndPrev);
        return FALSE; //退出实例。
    }
    //继续寻找下一个窗口。 
    hWndPrev = ::GetWindow(hWndPrev, GW_HWNDNEXT);
}


后记:一般情况下用第一个方法就可以啦


微信号:kelicom QQ群:215861553 紧急求助须知
Win32/PHP/JS/Android/Python