当前位置:网站首页>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 :
1. Open the program to get the handle Set the style
function :
- Get window handle :
HWND FindWindow(L"class name",L"window title")
Data can be obtained through “ Handle Genie ” Software access - Set window style :
SetWindowLong(HWND, GWL_STYLE, LONG dwNewLong)
- Get window style :
GetWindowLong(HWND, GWL_STYLE)
- 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 :
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 :
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 .
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 :
- Set the window display :
ShowWindow(HWND, int nCmdShow)
Set upnCmdShow
: Display inactive asSW_SHOWNOACTIVATE
, Hide asSW_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);
}
边栏推荐
猜你喜欢
Financial German translation, a professional translation company in Beijing
基于购买行为数据对超市顾客进行市场细分(RFM模型)
At the age of 26, I changed my career from finance to software testing. After four years of precipitation, I have been a 25K Test Development Engineer
My creation anniversary
[brush questions] how can we correctly meet the interview?
Wish Dragon Boat Festival is happy
[unity] how to export FBX in untiy
Changes in the number of words in English papers translated into Chinese
ROS学习_基础
接口自动化测试框架:Pytest+Allure+Excel
随机推荐
Reflex WMS中阶系列3:显示已发货可换组
Blue Bridge Cup zero Foundation National Championship - day 20
ML之shap:基于adult人口普查收入二分类预测数据集(预测年收入是否超过50k)利用Shap值对XGBoost模型实现可解释性案例之详细攻略
What are the characteristics of trademark translation and how to translate it?
Redis Foundation
Introduction and underlying analysis of regular expressions
SQL Server Manager studio (SSMS) installation tutorial
L'Ia dans les nuages rend la recherche géoscientifique plus facile
成功解决TypeError: data type ‘category‘ not understood
It is necessary to understand these characteristics in translating subtitles of film and television dramas
(practice C language every day) reverse linked list II
ROS2安装及基础知识介绍
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
Apache DolphinScheduler源码分析(超详细)
librosa音频处理教程
因高额网络费用,Arbitrum 奥德赛活动暂停,Nitro 发行迫在眉睫
How much is it to translate Chinese into English for one minute?
Monotonic stack
Day 239/300 注册密码长度为8~14个字母数字以及标点符号至少包含2种校验
Day 248/300 关于毕业生如何找工作的思考