禁止mfc开发的软件多开

作者:小知 发布时间:2017-07-24 分类:MFC

     技术所限,难免错误,如有不对之处,敬请留言指正!

    本篇文章使用的工程源码test.rar点击可下载,可用vc++6.0或者vs2008打开。

    本篇文章所用到的禁止多开的代码禁止多开.rar点击即可下载,解压即可打开。




    mfc开发的软件有时候需要禁止多开,即软件只能运行一个实例,当有一个实例在运行时,再点击exe运行就不会有任何反应,禁止多开的步骤如下:

1:使用vc++6.0新建一个基于对话框的mfc工程。然后生成release版本的exe。

QQ截图20170724142513.png

QQ截图20170724142523.png

QQ截图20170724142623.png

QQ截图20170724142841.png

    这时候到工程所在的文件夹找到release文件夹,双击打开test.exe发现打开一个,再点击又打开一个,即可以打开多个实例。

QQ截图20170724142902.png

2:找到mfc工程主程序的cpp,我这里是test.cpp,找到InitInstance()函数,并在函数开头添加下列代码:

// 用应用程序名创建信号量
HANDLE hSem = CreateSemaphore(NULL, 1, 1, m_pszExeName);
// 信号量已存在?
// 信号量存在,则程序已有一个实例运行
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
// 关闭信号量句柄
CloseHandle(hSem);
// 寻找先前实例的主窗口
HWND hWndPrevious = ::GetWindow(::GetDesktopWindow(), GW_CHILD);
while (::IsWindow(hWndPrevious))
{
// 检查窗口是否有预设的标记
// 有,则是我们寻找的主窗
if (::GetProp(hWndPrevious, m_pszExeName))
{
// 主窗口已最小化,则恢复其大小
if (::IsIconic(hWndPrevious))
::ShowWindow(hWndPrevious, SW_RESTORE);
// 将主窗激活
::SetForegroundWindow(hWndPrevious);
// 将主窗的对话框激活
::SetForegroundWindow(::GetLastActivePopup(hWndPrevious));
// 退出本实例
return FALSE;
}
// 继续寻找下一个窗口
hWndPrevious = ::GetWindow(hWndPrevious, GW_HWNDNEXT);
}
// 前一实例已存在,但找不到其主窗
// 可能出错了
// 退出本实例
return FALSE;
}


QQ截图20170724143738.png

    再次选择菜单栏的组建下拉菜单中的批组建,全部重建生成release版本的exe

QQ截图20170724143955.png

    这时发现已经达到了禁止多开的效果

QQ截图20170724144037.png

    延伸与拓展:

    如果要实现这样的效果,比如说第一次打开软件然后最小化了,再次点击release版本的exe,虽然没有能够多开,但是运行中的软件的状态改变了,从最小化激活了,变成了不是最小化的状态,把窗体呈现了出来,这个怎么实现呢?这里就涉及到状态的标记。步骤如下:

    首先把软件按照上面的步骤设置成禁止多开,接下来在类向导里面为窗体添加两个函数OnCreate和OnDestroy。

QQ截图20170724144857.png

QQ截图20170724144909.png

   在OnCreate函数相应位置里面加上::SetProp(m_hWnd, AfxGetApp()->m_pszExeName, (HANDLE)1);在OnDestroy函数相应位置里面加上::RemoveProp(m_hWnd, AfxGetApp()->m_pszExeName);

QQ截图20170724145542.png

    再次批组建全部重建,第一次打开软件,将其最小化,再次点击test.exe发现软件从最小化变成呈现界面的状态。

QQ截图20170724145818.png

QQ截图20170724145836.png

    所以如果一个工程文件生成的exe里面有很多窗体,比如说里面有10个窗体,窗体与窗体之间分别是非模态的关系,假如可以一次性把10个窗体全部展现出来,假设第10个窗体最小化了,其他9个窗体呈现在界面上,这时候如果对第10个窗体所在的类加了OnCreate函数和OnDestroy函数,并且添加了状态标记的代码,这时候如果点击exe文件,第10个窗体会由最小化展现在界面上,但是整个软件还是禁止多开的状态,如果第10个窗体没有添加状态标记的代码,那么点击exe文件,这个窗体还是最小化的状态,不会有任何反应。

    实际操作中,根据自己需要来设计多开的形式,据我所知,卡巴斯基是采用延伸与拓展里面的这种禁止多开的方式。

    第一次打开卡巴斯基,然后将其最小化,这时候在点击快捷方式,卡巴斯基会从最小化状态还原到界面上。

QQ截图20170724151049.png

QQ截图20170724151205.png

QQ截图20170724151329.png

本篇完。



呃 本文暂时没人评论 来添加一个吧

发表评论

必填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。