一 启动程序

QT在运行的时候,要启动qws服务,如果用前面两种方法,运行的时候,要新开启一个qws,否则不能运行;而用第三种方法,则不需要再开启qws,它和主进程共用一个qws。

一、通过调用系统函数 system

system()函数的作用是执行系统命令调用命令处理器来执行命令。。在使用system()函数时,需要在程序中包含process.h或者stdlib.h头文件。
示例:调用“e:\1.exe”程序。

system("e:\\1.exe");

阻塞进程,直到myApp程序结束

二、通过QProcess,阻塞调用QProcess::execute

QProcess::execute(“/opt/myApp”); //绝对路径和相对路径都可以,windows下要带exe后缀,系统应用如记事本notepad可直接输入打开

三、通过QProcess,非阻塞调用

QProcess *pro = new QProcess;  
pro->start("/opt/myApp");

有可能在终端上看不到打印出来的信息。所以要在终端显示信息时,可以考虑用阻塞模式。

二 获取窗口类名或窗口句柄

FindWindow句法

检索其类名和窗口名与指定字符串匹配的顶级窗口的句柄。此函数不搜索子窗口。此函数不执行区分大小写的搜索。
在pro文件里面添加:

win32{LIBS += -luser32}

源文件添加:
#include <Windows.h>

HWND FindWindow(LPCTSTR IpClassName,LPCTSTR IpWindowName);
  • IpClassName :指向一个指定了类名的空结束字符串,或一个标识类名字符串的成员的指针。假设该參数为一个成员,则它必须为前次调用theGlobafAddAtom函数产生的全局成员。该成员为16位,必须位于IpClassName的低 16位,高位必须为 0。
  • IpWindowName:指向一个指定了窗体名(窗体标题)的空结束字符串。假设该參数为空,则为全部窗体全匹配。

示例

HWND hWnd = ::FindWindow(L"CalcFrame", L"计算器");

返回值类型:HWND
如果函数成功,则返回值是具有指定类名和窗口名的窗口句柄。如果函数失败,则返回值为NULL。要获取扩展的错误信息,使用GetLastError。

三 嵌入到QT窗口

获取QWindow。QWindow::fromWinId用来创建一个win32窗口的代理。

QWindow*m_window;
m_window= QWindow::fromWinId((WId)hWnd);

获取代理QWidget。QWidget::createWindowContainer用来把窗口封装为一个QWidget控件。

m_widget = QWidget::createWindowContainer(m_window, this->ui->widget); //第二个参数是作为window的父类,也可以用layout

示例

#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();
}

createWindowContainer

QWidget *QWidget::createWindowContainer(QWindow *window, QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags())
创建一个QWidget窗口容器,该窗口容器使得基于QWidget的应用内嵌window窗口变为可能。

QWidget与HWND的互相转换

HWND转QWidget

QWidget *myWidget;
HWND hwnd;
myWidget=QWidget::find(hwnd);

QWidget转HWND

QWidget *myWidget;
HWND hwnd;
hwnd=( HWND )myWidget->winId();

相关概念

句柄(Handle)是一个是用来标识对象或者项目的标识符,可以用来描述窗体、文件等,值得注意的是句柄不能是常量 。
在程序设计中,句柄是一种特殊的智能指针,当一个应用程序要引用其他系统(如数据库、操作系统)所管理的内存块或对象时,就要使用句柄。
句柄是对象生成时系统指定的,属性是只读的,程序员不能修改句柄。

在windows编程中类型名前面加H的基本是句柄
常用句柄 :

  • HBITMAP 保存位图信息的内存域的句柄
  • HBRUSH 画刷句柄
  • HCTR 子窗口控件句柄
  • HCURSOR 鼠标光标句柄
  • HDC 设备描述表句柄
  • HDLG 对话框句柄
  • HFONT 字体句柄
  • HICON 图标句柄
  • HINSTANCE 应用程序实例句柄
  • HMENU 菜单句柄
  • HMODULE 模块句柄
  • HPALETTE 颜色调色板句柄
  • HPEN 笔的句柄
  • HWND 窗口句柄

WId 窗口句柄
在windows下每个窗口都有窗口句柄的概念,但是程序每次运行窗口句柄WId都会改变。

Hwnd 窗口句柄: 其中包含窗口的属性。是描述一个窗口的形状、位置、大小、是否显示、它的父窗口、兄弟窗口、等等的一组数据结构;