Qt打开外部进程并将外部进程画面嵌入到Qt界面(谷歌浏览器)

在这里插入图片描述Qt打开外部进程并将外部进程画面嵌入到Qt界面(谷歌浏览器),windows下通过查找注册表找到谷歌浏览器的位置,然后QT启动谷歌浏览器的进程,然后等待谷歌浏览器启动后,查找它的窗口,然后将这个窗口嵌入到QT界面

#include "QProcess"
#include <QSettings>
#include <QDebug>
#include <Windows.h>
#include <stdio.h>
#include <QWindow>
#include <QScrollArea>

void Wide2Bytes(char* pBytes,TCHAR* pWide)
{
    int nLen,i;
    nLen = WideCharToMultiByte(CP_ACP,0,pWide,-1,NULL,0,NULL,NULL);
    i = (int)wcslen(pWide)*sizeof(TCHAR);
    WideCharToMultiByte(CP_ACP,0,pWide,-1,pBytes,nLen,NULL,NULL);
}

WebForm::WebForm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::WebForm)
{
    ui->setupUi(this);
    ui->frame->hide();
    layout = new QHBoxLayout(ui->widget);
    layout->setContentsMargins(0,0,0,0);
    pRc = new QProcess(this);
}

WebForm::~WebForm()
{
    pRc->close();
    delete pRc;
    delete layout;
    delete ui;
}

void WebForm::resizeEvent(QResizeEvent *event)
{
//    ui->frame->setGeometry(this->frameGeometry().width()*0.1,this->frameGeometry().height()*0.1,
//                           this->frameGeometry().width()*0.8,this->frameGeometry().height()*0.8);
    ui->widget->setGeometry(this->frameGeometry().width()*0.1,this->frameGeometry().height()*0.1,
                           this->frameGeometry().width()*0.8,this->frameGeometry().height()*0.8);
}

QString WebForm::getSoftware()
{
    QString regStr = "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\";
    QSettings settings(regStr, QSettings::NativeFormat);
    QStringList regGroups = settings.childGroups();
    QString softwarePath;
    foreach (QString regItem , regGroups)
    {
        settings.beginGroup(regItem);
        QString displayName = settings.value("DisplayName").toString();
        QString uninstallString = settings.value("UninstallString").toString();
        if(!displayName.isEmpty())
        {
            qDebug() << "[" << __FUNCTION__ << __LINE__ << "] :" << displayName << uninstallString;
            qDebug() << displayName;
            qDebug() << uninstallString;
            if(displayName == "Google Chrome")
            {
                return uninstallString;
            }

        }
        settings.endGroup();
    }
    return "";


}

void WebForm::GetChromePath(QString& strPath)
{
    HKEY hKey;
    TCHAR SubKeyName[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe");
    TCHAR ValueData[1024];
    char Data[1024];
    DWORD Buffer=1024;
    if(RegOpenKeyEx(HKEY_CURRENT_USER, SubKeyName, 0, KEY_READ, &hKey)!= ERROR_SUCCESS)
    {
        qDebug()<<"Error: Regedit cannot be opened! ";
    }

    else
    {
        if(RegQueryValueEx(hKey, TEXT("Path"), 0, NULL, (LPBYTE)ValueData, &Buffer) == ERROR_SUCCESS)
        {
            Wide2Bytes(Data, ValueData);
            QString strPathTemp =QString::fromStdWString(ValueData);
            strPathTemp +="\\chrome.exe";
            strPathTemp = strPathTemp.replace(QRegExp("\\\\"),"/");
            strPath = strPathTemp;
            RegCloseKey(hKey);
        }
        else
            qDebug()<<"RegQueryValueEx failed![ValueData = %s]",ValueData;
    }
}

void WebForm::AttachWinThreadKeyMouseEvent(WId remoteHandle)
{
    DWORD curThreadId = GetCurrentThreadId();  //获取当前线程的ID
    DWORD remoteThreadId = GetWindowThreadProcessId((HWND)remoteHandle,NULL); //获取要加入到当前线程的外部线程ID
    if (curThreadId != remoteThreadId)
    {
        if (!AttachThreadInput(remoteThreadId, curThreadId, true))
        {
            qErrnoWarning("AttachThreadInput:Error");
        }
    }
}

void WebForm::openWeb(QString str)
{
   QString softwarePath;
   GetChromePath(softwarePath);
    qDebug() << "softwarePath:  " <<softwarePath;
    QStringList arguments;
    arguments<<"--chrome-frame"<<"-kiosk"<<str;
    //arguments<<"--chrome-frame"<<str;
    //pRc->startDetached(softwarePath ,arguments);//父进程kill,子进程不会
    pRc->start(softwarePath ,arguments); // 父进程kill,子进程也会被kill

    Sleep(3000);
    WId wid = (WId)FindWindow(L"Chrome_WidgetWin_1", NULL);
    AttachWinThreadKeyMouseEvent(wid);  // 可以对外部进程进行输入,但是鼠标切出去就不能输入了
    qDebug()<<"wid:"<<wid;

    QVBoxLayout *mainlayout = new QVBoxLayout(this);
    QWindow *window = QWindow::fromWinId(wid);
    window->setFlags(Qt::FramelessWindowHint);
    QWidget *widget = QWidget::createWindowContainer(window);
    qDebug()<<"this->width():"<<this->width()<<"  this->height():"<<this->height();
    widget->setMinimumSize(this->width(), this->height());
    widget->setFixedSize(this->width(), this->height());
    mainlayout->addWidget(widget);
    QWidget *pembedwidget = new QWidget;
    pembedwidget->setLayout(mainlayout);
    QScrollArea *pscroll = new QScrollArea;
    pscroll->setFixedSize(this->width(), this->height());
    pscroll->setWidget(pembedwidget);
    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(pscroll);
    pembedwidget->setFixedSize(this->width(), this->height());
    this->setLayout(layout);


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值