方法二转载:https://blog.csdn.net/winstonyi/article/details/108737600
qt在桌面应用程序中,会存在一个问题,官方示例中也无提及,桌面快捷方式,唤醒已经最小化的窗口,因为大部分情况下,不可能让窗口一直保持在前台,最小化后,在需要时有必须让其快速显示,windows托盘图标在某些情况下,受图标缓冲影响,就是不显示!最直接和可靠的渠道就是,桌面快捷方式和开始菜单的快捷方式,也比较符合大部分普通用户习惯!
方法一:
起初遇到该问题,我们测试,直接双击桌面快捷方式,默认是相当于“双开”,也就说打开同样的程序的第二个,对于有端口号等应用程序,明显会出错,因为都被一个占了,和同事试了各种方法,最多只能用QSharedMemory忽略再次打开这个动作,保证无法重复打开,无法唤醒已经最小化到托盘的窗口。
后来无意间,在现场商量到了一个实现方式,是通过udp消息唤醒窗口。每次打开程序,默认给指定端口,发出特定消息,已经运行的应用程序收到该消息后,主动showwindow,实现了,打开桌面快捷方式,唤醒已经最小化的窗口;
方法二:
博主Chervin(https://blog.csdn.net/winstonyi/article/details/108737600),在2020年9月开源了,新的方法,采用QSharedMemory方式,加上Window API函数操作程序,保证已打开程序不重复打开,并激活程序窗口到最前面。
仔细看其原理,应该是合理的解决方案。
可能qt的大多人对windows api并不熟悉,下为实现方法,可自行参考,
// Windouw API 依赖头文件
#include <windows.h>
#include <winbase.h>
// Qt 依赖头文件
#include <QSystemSemaphore>
#include <QSharedMemory>
int main(int argc, char *argv[])
{
// ......
//.....其他代码
/** 程序是否已经打开检测和激活并置于最前端控制 */
//@ 1.首先判断程序是否已经打开
QSystemSemaphore semaphore("BTSemap", 1);
semaphore.acquire();
QSharedMemory shareMemory("BTKey");//建立共享内存对象,BTKey为改程序设置的共享内存key值,用户根据自己需要设定
bool isRunning =false;
if (shareMemory.attach())//判断软件是否已经打开
{
isRunning = true;//已经打开
}
else
{
shareMemory.create(1);//软件未打开,则创建共享内存
isRunning = false;
}
semaphore.release();
//@ 2.软件已经打开,则将软件激活,并置于桌面最前面
if (isRunning)
{
//@ 将软件激活,显示在最前端
QString wTitle = QString("TestProgram");//Qt创建的主MainWindow的 标题
HWND handle = FindWindow(nullptr,wTitle.toLocal8Bit().toStdString().c_str());//基于windows Api 获取程序窗口的句柄
if (handle == nullptr)//判断是否为空
{
return -1;
}
ShowWindow(handle, SW_RESTORE);//激活窗口,参数:SW_RESTORE,以程序之前的大小显示,可以根据需要设置其他标识,如SW_MAXIMIZE
SetForegroundWindow(handle);//激活窗口在桌面最前面
return 1;
}
//@ 3.若程序未打开,则正常执行程序,如以下屏蔽的代码,正常启动主界面程序
//TMainWindow w;
//w.show();
//int ret = a.exec();
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/96517.html