将子进程(exe)界面嵌入到主进程(另一exe)界面中——Qt

前言

近期项目中,要将子进程界面嵌入到主进程中,双方都是自己开发的,之前有过研究,曾经写过一篇文章

将外部exe嵌入到界面中(Windows)——Qt_startf_useshowwindow-CSDN博客,如今发现不好用,界面是嵌入了,但是并没有按照要求的大小展示,通过了几种方法(布局、绝对位置)仍然行不通。

如何将一个进程(子进程)界面嵌入另一个进程界面

  • 方式一:在主进程中启动子进程,获取子进程的窗口句柄。
  • 方式二:如果子进程也是自己开发的,在启动子进程时,可以将主进程的容纳子进程界面的窗体句柄作为运行参数传入子进程,通过进程通讯的方式,进行控制。
    QStringList argl = a.arguments();
    qDebug() << argl;
    if (argl.size() <2)
    {       
        return 0;
    }

	WId wid = WId(argl.at(1).toInt());
	QWindow* window = QWindow::fromWinId(wid);

	SubProcessWidget w;
	w.setProperty("_q_embedded_native_parent_handle", QVariant(wid));//设置属性,这句是必须的
	w.winId();//必须调用一次,生成winId
	w.windowHandle()->setParent(window);//设置父窗口

如何控制大小位置

通过Windows API重置大小

之前都是通过Qt的方式对界面大小进行控制,失败了,后面查资料,发现有通过Windows API的方法(SetWindowPos)设置子进程界面的大小和位置的,所以就试了试,结果差强人意:可放大和还原,但是拖动主进程界面边框无法缩放,原因不清。

    qint64 pid = processStart();
    WId wid = getProcessWid(pid);

    if(wid!=0)
    {
        m_wnd =(HWND)wid;
        SetParent(m_wnd,(HWND)ui->widget->winId());
        SetWindowPos(m_wnd, 0,  0, 0 ,ui->widget->width(), 
                    ui->widget->height(), SWP_NOZORDER);
    }
qint64 Widget::processStart()
{
    pro =new QProcess(this);
    pro->setProgram("programName");
    connect(pro,&QProcess::errorOccurred,this,&Widget::onErrorOccurred);
    connect(pro,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(onFinished(int,QProcess::ExitStatus)));
    connect(pro,&QProcess::started,this,&Widget::onStarted);
    connect(pro,&QProcess::stateChanged,this,&Widget::onStateChanged);
    pro->setCreateProcessArgumentsModifier([](QProcess::CreateProcessArguments *args)
                                               {
                                                   args->startupInfo->wShowWindow = SW_HIDE;
                                                   args->startupInfo->dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
                                               }
                                               );
    pro->start();
    pro->waitForStarted();
    return pro->processId();

}

WId Widget::getProcessWid(qint64 pid)
{

    WId winId = NULL;
    while (true) {
        winId=(WId)FindWindowW(L"Qt5152dQWindowIcon",L"Form");
        if (winId != NULL)
        {
            break;
        }
    }
    return winId;
}

void Widget::resizeEvent(QResizeEvent *e)
{
    QWidget::resizeEvent(e);
    SetWindowPos(m_wnd, 0,  0, 0 ,ui->widget->width(), ui->widget->height(), SWP_NOZORDER);
}

子进程内部控制

由于子进程也是我开发的,所以可以通过TCP或者其他方式进行通讯,告诉子进程的大小和位置,在子进程中进行设置(setGeometry)。

结束语

纸上得来终觉浅,绝知此事要躬行。

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值