外部进程嵌入到Qt进程界面

https://www.cnblogs.com/findumars/p/8001326.html

https://blog.youkuaiyun.com/weixin_43956958/article/details/124948569

https://blog.youkuaiyun.com/qq_38040674/article/details/83546357?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-1-83546357-blog-111567062.235%5Ev35%5Epc_relevant_increate_t0_download_v2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-1-83546357-blog-111567062.235%5Ev35%5Epc_relevant_increate_t0_download_v2&utm_relevant_index=2

一、主要思路

运行exe—>FindWindow获得窗口句柄—>QWindow::fromWinId获得QWindow—>createWindowContainer为QWindow对象创建容器即窗口—>设置窗口属性并显示

  1. FindWindow获得外部应用窗口句柄
HWND WINAPI FindWindow(
  _In_opt_ LPCTSTR lpClassName,// pointer to class name
  _In_opt_ LPCTSTR lpWindowName // pointer to window name
);

FindWindow的两个参数填入一个即可查找到窗口句柄。

②如何获取外部应用的类名或者窗口名:
使用VS中的Spy++工具(在VS菜单栏“工具”中可以找到)。运行外部应用程序,打开Spy++,可以看到所有窗口的信息。
右键菜单中的“属性”项,可以查看窗口属性,其中“常规”- 窗口标题 即为窗口名,“类”- 类名 即为所要的类名。

#include<Windows.h>  

Sleep(5000);//在代码之前增加延时
WId wid = (WId)FindWindow(NULL, L"honestech TVR - Screen");
//如果函数成功,则返回值是具有指定类名和窗口名的窗口句柄。如果函数失败,则返回值为NULL。
  1. 获取QWindow。QWindow::fromWinId用来创建一个win32窗口的代理。
QWindow*m_window;
m_window= QWindow::fromWinId(wid);
  1. 获取代理QWidget。QWidget::createWindowContainer用来把窗口封装为一个QWidget控件。
m_widget = QWidget::createWindowContainer(m_window, this); //第二个参数是作为window的父类,也可以用layout

二、源码

step1:Qt打开外部exe。创建进程:CreateProcess是Windows下用于创建进程的API函数
step2:启动外部exe,找到该exe窗口的句柄。FindWindow()
step3:将打开的外部程序嵌入到Qt的UI界面中

补充:设置窗口属性

https://www.cnblogs.com/shuoguoleilei/p/12766432.html

https://blog.youkuaiyun.com/xuebing1995/article/details/96478891?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-1-96478891-blog-77772635.235%5Ev36%5Epc_relevant_default_base3&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-1-96478891-blog-77772635.235%5Ev36%5Epc_relevant_default_base3&utm_relevant_index=1

#include "stdafx.h"  
#include "winId.h"  
  
winId::winId(QWidget *parent)  
    : QWidget(parent),ui(new Ui::winIdClass)  
{  
    ui->setupUi(this);  
    
    //创建进程  
    QString cmd = "C:/Windows/system32/calc.exe";  
    STARTUPINFO si = { sizeof(si) };   //一些必备参数设置
    PROCESS_INFORMATION pi;  
    si.dwFlags = STARTF_USESHOWWINDOW;  
    si.wShowWindow = true;   //必备参数设置结束
  
    bool bRet = CreateProcess(  
        NULL,  
        (LPWSTR)cmd.toStdWString().c_str(),  
        NULL,  
        NULL,  
        FALSE,  
        CREATE_NEW_CONSOLE,  
        NULL,  
        NULL, &si, &pi);  
  
    Sleep(5000);  
  
    WId wid = (WId)FindWindow(L"CalcFrame", L"计算器");  
    //WId wid = (WId)FindWindow(L"Rgui Workspace",NULL);  
    QWindow *m_window = nullptr; 
    m_window = QWindow::fromWinId(wid);  
    m_window->setFlags(m_window->flags() | Qt::CustomizeWindowHint | Qt::WindowTitleHint); //  
  
    QWidget* m_widget = nullptr; 
    m_widget = QWidget::createWindowContainer(m_window, this);  
    m_widget->setMinimumSize(400, 300);  //必须设置大小,否则可能因为嵌入后窗口太小看不到效果
}  
  
winId::~winId()  
{  
    delete ui;  
}  

或者参考:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QProcess>
#include <QDir>
#include "windows.h"
#include "stdio.h"
#include <QDebug>
#include <QMainWindow>
#include <QWindow>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    //启动
    QDir::setCurrent("C:\\windows\\system32");
    QProcess *pro = new QProcess(this);
    pro->start("notepad.exe");
    ui->setupUi(this);
}

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

void MainWindow::integrate()
{
    QString Name = "无标题 - 记事本";
    QString Name2 = "MainWindow";
    WId hwnd = (WId)FindWindow(L"Notepad",(LPCTSTR)Name.unicode());
    WId m_hWnd = (WId)FindWindow(L"Qt5QWindowIcon",(LPCTSTR)Name2.unicode());
    qDebug()<<hwnd;
    qDebug()<<m_hWnd;
    //嵌入
    if (hwnd > 0)
    {
        QWindow *m_window;
        m_window = QWindow::fromWinId(WId(hwnd));
        QWidget *m_widget;
        m_widget = QWidget::createWindowContainer(m_window,this);
        setCentralWidget(m_widget);
    }
}

void MainWindow::on_pushButton_clicked()
{
    integrate();
}

另一种方法:

#include <windows.h>
#include <QProcess>
#include <QWindow>

QString cmd = "D:/XXX.exe";
myProcess = new QProcess(this);
myProcess->start(cmd);
Sleep(3000);

 HWND hwnd = NULL;
        while (1) {
            hwnd = FindWindow(L"CalcFrame", L"计算器");
            if(hwnd){
                break;
            }
        }
 ::SetParent(hwnd,(HWND)winId());//参数一:子类句柄,参数二:父类句柄。(HWND)对象名->winId()
 WId wid = (WId)hwnd;
 m_window = QWindow::fromWinId(wid);

 m_window->setGeometry(80,50,1000,700);

三、句柄

https://blog.youkuaiyun.com/zhangchuan7758/article/details/121967154

https://blog.youkuaiyun.com/weixin_43956958/article/details/124948569

Windows 环境中有很多对象,诸如窗口、画笔、位图、光标、设备环境、程序实例等,可以通过API函数以不同的形式对这些对象进行操作。为此,必须以某种方法对这些对象进行标识,并把它们以参数的形式传递给函数。Windows用一个32位的整数对各种对象进行标识,这就是“句柄”(Handle)。也就是说句柄是一个对象的标识符。
句柄----用来标识指定一个窗体的,一个窗体有一个唯一的标识,引用句柄就可以引用窗体”。

在windows编程中类型名前面加H的基本是句柄。 常用的句柄:
HBITMAP 保存位图信息的内存域的句柄
HBRUSH 画刷句柄
HCTR 子窗口控件句柄
HCURSOR 鼠标光标句柄
HDC 设备描述表句柄
HDLG 对话框句柄
HFONT 字体句柄
HICON 图标句柄
HINSTANCE 应用程序实例句柄
HMENU 菜单句柄
HMODULE 模块句柄
HPALETTE 颜色调色板句柄
HPEN 笔的句柄
HWND 窗口句柄

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值