当前位置:网站首页>Embed UE4 program into QT interface display

Embed UE4 program into QT interface display

2022-07-06 06:50:00 Leslie x Xu

windows Window programming

demand : take ue4 Program embedding qt Interface display
Ideas : By using windowsAPI Yes ue4 Set the window to follow qt Interface and the position sequence setting when the window is active
result :
 Please add a picture description

1. Open the program to get the handle Set the style

function :

  1. Get window handle :HWND FindWindow(L"class name",L"window title") Data can be obtained through “ Handle Genie ” Software access
  2. Set window style SetWindowLong(HWND, GWL_STYLE, LONG dwNewLong)
  3. Get window style :GetWindowLong(HWND, GWL_STYLE)
  4. Window style macro
void Unreal4::on_pushButton_clicked()
{
    
    QString unreal4Path{
    "D:/lesliex/QTpro/QWidgetUnreal4/Windows/UEMetaFactory.exe"};
    QStringList arguments;
    arguments << "-WINDOWED";
    _process=new QProcess;
    _process->start(unreal4Path,arguments);

    QtConcurrent::run([this]{
    
        while(true){
    
            _hwnWindow=FindWindow(L"UnrealWindow",L"UEMetaFactory ");
            SetWindowLong(_hwnWindow, GWL_STYLE, GetWindowLong(_hwnWindow, GWL_STYLE) & (~WS_OVERLAPPEDWINDOW));// Use &~ Remove a certain style 
            if(_hwnWindow != NULL){
    
                qDebug()<<("get SeerSupports");
                emit sigUe4Complete();
                break;
            }
        }
    });
}

2. Wait for the display Mobile location

Don't use... Here createWindowContainer, Yes ue4 There is a problem with mouse keyboard interaction
function :

  1. Move the window
BOOL MoveWindow(
  [in] HWND hWnd,
  [in] int  X,
  [in] int  Y,
  [in] int  nWidth,
  [in] int  nHeight,
  [in] BOOL bRepaint
);

Wait until the window appears to get the handle

connect(this,&Unreal4::sigUe4Complete,this,&Unreal4::slotUe4Complete);
void Unreal4::slotUe4Complete()
{
    
//createWindowContainer Bad way 
    // _window=QWindow::fromWinId((WId)_hwnWindow);
    // _windowWidget = QWidget::createWindowContainer(_window);

    _windowWidget = ui->widget_2;
    MoveWindow(_hwnWindow,mapToGlobal(_windowWidget->pos()).x(),mapToGlobal(_windowWidget->pos()).y(),_windowWidget->width(),_windowWidget->height(),false);
}

3. The timer regularly displays the window to the top

function :

  1. Set the window position
BOOL SetWindowPos(
  [in]           HWND hWnd,
  [in, optional] HWND hWndInsertAfter,
  [in]           int  X,
  [in]           int  Y,
  [in]           int  cx,
  [in]           int  cy,
  [in]           UINT uFlags
);

take hWnd Move to hWndInsertAfter The lower , And set the position and size , Display mode .

  1. Get the window
HWND GetWindow(
  [in] HWND hWnd,
  [in] UINT uCmd
);

To get the window handle on the upper layer of a known window, you can GetWindow( (HWND)this->winId() ,GW_HWNDPREV )

When the main window and ue When the program is an active window , take hWndInsertAfter Set to HWND_TOPMOST,uFlags Set to SWP_NOACTIVATE Only inactive
When the main window is not the active window , take hWndInsertAfter Set to GetWindow( (HWND)this->winId() ,GW_HWNDPREV ),uFlags Set to SWP_NOACTIVATE Only inactive

Unreal4::Unreal4(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Unreal4)
{
    
    ui->setupUi(this);

    _timer = new QTimer(this);
    _timer->start(10);
    connect(_timer,&QTimer::timeout,this,&Unreal4::timerShowUe4);

}

void Unreal4::timerShowUe4()
{
    
    if(_windowWidget){
    
        if(GetForegroundWindow()==_hwnWindow||this->isActiveWindow()){
    
            qDebug()<<"isActive";
            SetWindowPos(_hwnWindow, HWND_TOPMOST, mapToGlobal(_windowWidget->pos()).x(),mapToGlobal(_windowWidget->pos()).y(),\
                         _windowWidget->width(),_windowWidget->height(),SWP_NOACTIVATE);
        }
        else{
    
            qDebug()<<"NotActive";
            SetWindowPos(_hwnWindow, GetWindow((HWND)this->winId(),GW_HWNDPREV), mapToGlobal(_windowWidget->pos()).x(),mapToGlobal(_windowWidget->pos()).y(),\
                         _windowWidget->width(),_windowWidget->height(),SWP_NOACTIVATE);
        }
    }
}

4. rewrite QWidget event

function :

  1. Set the window display ShowWindow(HWND, int nCmdShow)
    Set up nCmdShow: Display inactive as SW_SHOWNOACTIVATE, Hide as SW_HIDE
void Unreal4::showEvent(QShowEvent *event)
{
    
    if(_process) ShowWindow(_hwnWindow,SW_SHOWNOACTIVATE);
}


void Unreal4::resizeEvent(QResizeEvent *event)
{
    
    if(_windowWidget)
        MoveWindow(_hwnWindow,mapToGlobal(_windowWidget->pos()).x(),mapToGlobal(_windowWidget->pos()).y(),_windowWidget->width(),_windowWidget->height(),false);
}


void Unreal4::hideEvent(QHideEvent *event)
{
    
    if(_process) ShowWindow(_hwnWindow,SW_HIDE);
}

5. Source code

pro Add... To the document :
LIBS += -luser32

The header file :

#ifndef UNREAL4_H
#define UNREAL4_H

#include "mwidget.h"
#include <QProcess>
#include "windows.h"
#include <QTimer>

QT_BEGIN_NAMESPACE
namespace Ui {
     class Unreal4; }
QT_END_NAMESPACE

/// \brief The Unreal4 class
/// \details  take UE4 Interface embedding QT Interface 

class Unreal4 : public QWidget
{
    
    Q_OBJECT

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

    void closeUe4();


private slots:
    void slotUe4Complete();
    void on_pushButton_clicked();
    void on_pushButton_2_clicked();
    void on_pushButton_3_clicked();
    void on_pushButton_4_clicked();

signals:
    void sigUe4Complete();
private:
    Ui::Unreal4 *ui;
    QProcess *_process{
    Q_NULLPTR};
    HWND _hwnWindow{
    Q_NULLPTR};
    QWidget *_windowWidget{
    Q_NULLPTR};
    QWindow * _window{
    Q_NULLPTR};
    QTimer* _timer{
    Q_NULLPTR};

    // QWidget interface
protected:
    void timerShowUe4();
    void showEvent(QShowEvent *event) override;
    void resizeEvent(QResizeEvent *event) override;
    void hideEvent(QHideEvent *event) override;
};
#endif // UNREAL4_H

Source file :

#include "Unreal4.h"
#include "ui_Unreal4.h"

#include <QWindow>
#include <QDebug>
#include <QPalette>

#include <QtConcurrent>
#include <QMouseEvent>
#include <QPainter>

Unreal4::Unreal4(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Unreal4)
{
    
    ui->setupUi(this);

    connect(this,&Unreal4::sigUe4Complete,this,&Unreal4::slotUe4Complete);
    _timer = new QTimer(this);
    _timer->start(10);
    connect(_timer,&QTimer::timeout,this,&Unreal4::timerShowUe4);

}


Unreal4::~Unreal4()
{
    
    closeUe4();
    delete ui;
}

void Unreal4::closeUe4()
{
    
    if(!_process) return;
    if(_process->state()==QProcess::Running){
    
       _process->kill();
       QString exe = "UEMetaFactory-Win64-Shipping.exe";
       _process->execute("taskkill",QStringList()<<"-im"<<exe<<"-f");
       _process->waitForFinished(5000);
       delete _process; _process = Q_NULLPTR;
       ui->verticalLayout->removeWidget(_windowWidget); delete _windowWidget;
    }
}

void Unreal4::slotUe4Complete()
{
    
    _windowWidget = ui->widget_2;
    MoveWindow(_hwnWindow,mapToGlobal(_windowWidget->pos()).x(),mapToGlobal(_windowWidget->pos()).y(),_windowWidget->width(),_windowWidget->height(),false);
}

void Unreal4::on_pushButton_clicked()
{
    
    QString unreal4Path{
    "D:/lesliex/QTpro/QWidgetUnreal4/Windows/UEMetaFactory.exe"};
    QStringList arguments;
    arguments << "-WINDOWED";
    _process=new QProcess;
    _process->start(unreal4Path,arguments);

    QtConcurrent::run([this]{
    
        while(true){
    
            _hwnWindow=FindWindow(L"UnrealWindow",L"UEMetaFactory ");
            SetWindowLong(_hwnWindow, GWL_STYLE, GetWindowLong(_hwnWindow, GWL_STYLE) & (~WS_OVERLAPPEDWINDOW));
            if(_hwnWindow != NULL){
    
                qDebug()<<("get SeerSupports");
                emit sigUe4Complete();
                break;
            }
        }
    });
}

//==================================show ue4===============================
void Unreal4::timerShowUe4()
{
    
    if(_windowWidget){
    
        if(GetForegroundWindow()==_hwnWindow||this->isActiveWindow()){
    
            qDebug()<<"isActive";
            SetWindowPos(_hwnWindow, HWND_TOPMOST, mapToGlobal(_windowWidget->pos()).x(),mapToGlobal(_windowWidget->pos()).y(),\
                         _windowWidget->width(),_windowWidget->height(),SWP_NOACTIVATE);
        }
        else{
    
            qDebug()<<"NotActive";
            SetWindowPos(_hwnWindow, GetWindow((HWND)this->winId(),GW_HWNDPREV), mapToGlobal(_windowWidget->pos()).x(),mapToGlobal(_windowWidget->pos()).y(),\
                         _windowWidget->width(),_windowWidget->height(),SWP_NOACTIVATE);
        }
    }
}

void Unreal4::showEvent(QShowEvent *event)
{
    
    if(_process) ShowWindow(_hwnWindow,SW_SHOWNOACTIVATE);
}


void Unreal4::resizeEvent(QResizeEvent *event)
{
    
    if(_windowWidget)
        MoveWindow(_hwnWindow,mapToGlobal(_windowWidget->pos()).x(),mapToGlobal(_windowWidget->pos()).y(),_windowWidget->width(),_windowWidget->height(),false);
}


void Unreal4::hideEvent(QHideEvent *event)
{
    
    if(_process) ShowWindow(_hwnWindow,SW_HIDE);
}

//=====================button==========================
void Unreal4::on_pushButton_3_clicked()
{
    
    _timer->start(10);
    if(_process) ShowWindow(_hwnWindow,SW_SHOWNOACTIVATE);
}

void Unreal4::on_pushButton_2_clicked()
{
    
    this->close();
}

void Unreal4::on_pushButton_4_clicked()
{
    
    _timer->stop();
    if(_process) ShowWindow(_hwnWindow,SW_HIDE);
}


原网站

版权声明
本文为[Leslie x Xu]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/187/202207060642582714.html