• 3985阅读
  • 6回复

[提问]避免程序重复运行,并激活先前运行的程序 [复制链接]

上一主题 下一主题
离线stlcours
 

只看楼主 倒序阅读 楼主  发表于: 2015-07-01
避免程序重复运行可以这样写:
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QSharedMemory shared_memory;
    shared_memory.setKey("myapp");
    if(shared_memory.attach())
    {
        // QMessageBox  提示用户,程序已经运行
        return 0;
    }

    if(!shared_memory.create(1)) {
        // QMessageBox  提示用户,程序已经运行
        return 0;
    }

    MainWidget main_widget;
    main_widget.showWidget();

    return app.exec();
}
那么请问如何激活先前运行的程序,并展示到所有窗口的最前面呢?
离线20091001753

只看该作者 1楼 发表于: 2015-07-02
大致思路是运用进程通讯机智。
在Win下这么实现:
若发现已有实例,就SendMessage,举例:
inline void SendProcessMessage(HWND wnd,uint wParam,QString message){// 发送进程通讯讯息
    COPYDATASTRUCT cds;
    cds.dwData=0;
    cds.cbData=message.length()+1;
    cds.lpData=message.toAscii().data();
    SendMessage(wnd,WM_COPYDATA,wParam,(LPARAM)&cds);
}

在窗口初始化中:
    // 只允许一个实例(此代码仅限WIN系统)
    HANDLE m_hMutex = CreateMutex(NULL, FALSE, L"MyProgram");
    if(m_hMutex)if(GetLastError() == ERROR_ALREADY_EXISTS){
        SendProcessMessage(FindWindow(L"QWidget",(WCHAR*)tr("窗口标题").utf16()),NULL,"ShowMyProgram");
        exit(0);
    }

然后接收消息并处理:

bool Widget::winEvent ( MSG * message, long * result ){//监控消息
    switch(message->message){
        case WM_COPYDATA:{
            COPYDATASTRUCT *cds = reinterpret_cast<COPYDATASTRUCT*>(message->lParam);
            QString messagestring(static_cast<char*>(cds->lpData));
            processMessage((HWND)message->wParam,messagestring);
        }break;
    }return QWidget::winEvent (message,result );
}

void Widget::processMessage(HWND wnd,QString message){//处理进程通讯讯息
    if(message=="ShowMyProgram"){
        show();//显示
        SetWindowPos( winId(), HWND_TOP,0,0,0,0, SWP_NOSIZE| SWP_NOMOVE);//置顶
        SetForegroundWindow(winId());//焦点
        return;
    }
}



(づ ̄ 3 ̄)づ
离线z55716368

只看该作者 2楼 发表于: 2015-07-02
每一个问题 都是一次进步
离线wangkun5905

只看该作者 3楼 发表于: 2015-07-04
好像有一个QSingleApplication第三方类完全可以满足你的要求
离线roywillow

只看该作者 4楼 发表于: 2015-07-04
Qt4时代有个SingleApplication的solution,我记得有两种实现方法,应该能满足你的要求
印象中是程序自己对sharedmemory定期查询之类的,发现有第二个实例运行就激活自己
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线stlcours

只看该作者 5楼 发表于: 2015-07-06
回 roywillow 的帖子
roywillow:Qt4时代有个SingleApplication的solution,我记得有两种实现方法,应该能满足你的要求
印象中是程序自己对sharedmemory定期查询之类的,发现有第二个实例运行就激活自己 (2015-07-04 18:16) 

问题是,定期查询用什么方法啊?用时钟效率很低,感觉有明显延迟。共享内存写数据我也知道,但是按照网上的方法没试验成功,于是就想上来偷个懒直接问问有没有现成的代码~
离线hidxl

只看该作者 6楼 发表于: 2015-10-12
brower 例子,就是单例程的,你可以参考下.并且可激活.
快速回复
限100 字节
 
上一个 下一个