当前位置:网站首页>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);
}
边栏推荐
- 【Hot100】739. 每日温度
- A 27-year-old without a diploma, wants to work hard on self-study programming, and has the opportunity to become a programmer?
- 成功解决AttributeError: Can only use .cat accessor with a ‘category‘ dtype
- Day 245/300 JS forEach 多层嵌套后数据无法更新到对象中
- AttributeError: Can‘t get attribute ‘SPPF‘ on <module ‘models. common‘ from ‘/home/yolov5/models/comm
- 基于购买行为数据对超市顾客进行市场细分(RFM模型)
- Day 248/300 关于毕业生如何找工作的思考
- [English] Grammar remodeling: the core framework of English Learning -- English rabbit learning notes (1)
- 电子书-CHM-上线CS
- Attributeerror: can 't get attribute' sppf 'on < module' models. Common 'from' / home / yolov5 / Models / comm
猜你喜欢

Reflex WMS medium level series 3: display shipped replaceable groups

Huawei equipment configuration ospf-bgp linkage

BUU的MISC(不定时更新)

利用快捷方式-LNK-上线CS

Bitcoinwin (BCW): 借贷平台Celsius隐瞒亏损3.5万枚ETH 或资不抵债

万丈高楼平地起,每个API皆根基

Apache dolphin scheduler source code analysis (super detailed)

Reflex WMS中阶系列3:显示已发货可换组

After sharing the clone remote project, NPM install reports an error - CB () never called! This is an error with npm itself.

Changes in the number of words in English papers translated into Chinese
随机推荐
CS passed (cdn+ certificate) PowerShell online detailed version
将ue4程序嵌入qt界面显示
Wish Dragon Boat Festival is happy
Simple use of MySQL database: add, delete, modify and query
mysql的基础命令
ROS2安装及基础知识介绍
Day 246/300 SSH connection prompt "remote host identification has changed!"
My seven years with NLP
Latex文字加颜色的三种办法
万丈高楼平地起,每个API皆根基
MySQL high frequency interview 20 questions, necessary (important)
钓鱼&文件名反转&office远程模板
[advanced software testing step 1] basic knowledge of automated testing
Traffic encryption of red blue confrontation (OpenSSL encrypted transmission, MSF traffic encryption, CS modifying profile for traffic encryption)
Automated test environment configuration
How to reconstruct the class explosion caused by m*n strategies?
Day 245/300 JS foreach data cannot be updated to the object after multi-layer nesting
Day 239/300 注册密码长度为8~14个字母数字以及标点符号至少包含2种校验
A method to measure the similarity of time series: from Euclidean distance to DTW and its variants
[ 英語 ] 語法重塑 之 動詞分類 —— 英語兔學習筆記(2)