qt嵌入程序,并监控是否关闭。

85 篇文章 1 订阅

qt嵌入程序需要使用到QWindow::fromWinId(mWid)和QWidget::createWindowContainer(Window,this, Qt::Widget );

qt阻塞启动三方程序ShellExecuteEx(&shExecinfo);和WaitForSingleObject(shExecinfo.hProcess, INFINITE);

代码示例:
.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QtWidgets>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::Widget *ui;
    QWidget* mWidget;
    int mWid = 0;
    QVBoxLayout* mLay;
};

class UThread : public QObject
{
    Q_OBJECT

public:
    UThread(QWidget *parent = nullptr);
    ~UThread();

public slots:
    void run();

signals:
    void signalWid(int wid);
    void signalCloseWid(bool flag);
};

#endif // WIDGET_H

.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>
#include "windows.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    mLay = new QVBoxLayout;
    mLay->addWidget(ui->pushButton_2);
    mLay->addWidget(ui->pushButton);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_2_clicked()
{
    QString cmd = QString("cmd /c taskkill /F /IM notepad++.exe /T");
    WinExec(cmd.toUtf8().data(),SW_HIDE);
    QList<QWidget *>wList = this->findChildren<QWidget *>("exewidget");
    foreach (QWidget* w, wList) {
        mLay->removeWidget(w);
        delete w;
    }
}

void Widget::on_pushButton_clicked()
{
    if (mWid > 0)
        return;
    UThread *load = new UThread;
    QThread* thread = new QThread();
    load->moveToThread(thread);
    connect(thread,SIGNAL(started()),load,SLOT(run()));
    connect(load,&UThread::signalCloseWid,this,[=](bool ok){
        qDebug()<<"-------------------"<<ok;
        mWid = 0;
    });
    connect(load,&UThread::signalWid,this,[=](int wid){
        mWid = wid;
        if( 0 == mWid){
            QMessageBox::information(0,"title","启动失败");
            return;
        }

        QWindow *Window = QWindow::fromWinId(mWid);
        Window->setFlags(Window->flags() | Qt::CustomizeWindowHint | Qt::WindowTitleHint);

        mWidget  = QWidget::createWindowContainer(Window,this, Qt::Widget );
        mWidget->setObjectName("exewidget");
        qDebug() << __FUNCTION__ << __LINE__ << "  ===--==> " << int(mWid);

        mLay->addWidget(mWidget);
        this->setLayout(mLay);
    });

    thread->start();
    //    QString runExec = "C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Notepad++";
    //    std::wstring operate = L"open";
    //    std::wstring path = L"C:/ProgramData/Microsoft/Windows/Start Menu/Programs";
    //    std::wstring lpParameters = L"";
    //    ShellExecute(NULL,operate.c_str(),runExec.toStdWString().c_str(),lpParameters.c_str(),path.c_str(),SW_HIDE);

    //    WId wid = 0;
    //    for(int i = 0 ;i < 7;++i){
    //        wid = (WId)FindWindow(L"Notepad++",NULL);
    //        qDebug() << __FUNCTION__ << __LINE__ << wid;
    //        if(wid != 0){
    //            break;
    //        }
    //        ::Sleep(3000);
    //    }

}



UThread::UThread(QWidget *parent)
{

}

UThread::~UThread()
{

}

void UThread::run()
{
    std::wstring operate = L"open";
    std::wstring path = L"C:/ProgramData/Microsoft/Windows/Start Menu/Programs";
    std::wstring lpParameters = L"";

    SHELLEXECUTEINFO shExecinfo = {0};//创建执行文件对象
    shExecinfo.cbSize = sizeof(SHELLEXECUTEINFO);//结构大小
    shExecinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
    shExecinfo.hwnd = NULL;//父窗口句柄
    shExecinfo.lpVerb = operate.c_str();//权限
    shExecinfo.lpFile = L"C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Notepad++";//执行文件
    shExecinfo.lpParameters = lpParameters.c_str();//参数
    shExecinfo.lpDirectory = path.c_str();//路径
    shExecinfo.nShow = SW_SHOWNORMAL;//显示方式
    shExecinfo.hInstApp = NULL;
    int ret = (int)ShellExecuteEx(&shExecinfo);
    if (ret == 0)//执行失败
    {}
    else//执行成功
    {}

    WId wid = 0;
    for(int i = 0 ;i < 7;++i){
        wid = (WId)FindWindow(NULL,L"Notepad++");
        qDebug() << __FUNCTION__ << __LINE__ << wid;
        if(wid != 0){
            break;
        }
        ::Sleep(3000);
    }

    emit signalWid((int)wid);

    try {
        DWORD wret = WaitForSingleObject(shExecinfo.hProcess, INFINITE);//阻塞,直到ShellExecuteEx()执行的程序关闭
        if (wret == WAIT_OBJECT_0)
        {
            qDebug()<<"正常关闭";
            emit signalCloseWid(true);
        }
        else if (wret == WAIT_TIMEOUT)
        {
            qDebug()<<"超时";
        }
        else if (wret == WAIT_FAILED)
        {
            qDebug()<<"异常关闭";
            emit signalCloseWid(false);
        }
    } catch (...) {
        qDebug()<<"异常关闭1";

    }

}



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东方忘忧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值