当前位置:网站首页>将ue4程序嵌入qt界面显示
将ue4程序嵌入qt界面显示
2022-07-06 06:43:00 【Leslie X徐】
windows窗口编程
需求:将ue4程序嵌入qt界面显示
思路:通过使用 windowsAPI 对ue4窗口进行设置跟随qt界面以及活动窗口时的位置层序设置
结果:
1.打开程序获取句柄 设置样式
函数:
- 获取窗口句柄:
HWND FindWindow(L"class name",L"window title")
数据可通过“句柄精灵”软件获取 - 设置窗口样式:
SetWindowLong(HWND, GWL_STYLE, LONG dwNewLong)
- 获取窗口样式:
GetWindowLong(HWND, GWL_STYLE)
- 窗口样式宏
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;
}
}
});
}
2.等待显示 移动位置
此处不使用 createWindowContainer,对ue4有鼠标键盘交互问题
函数:
- 移动窗口:
BOOL MoveWindow(
[in] HWND hWnd,
[in] int X,
[in] int Y,
[in] int nWidth,
[in] int nHeight,
[in] BOOL bRepaint
);
等待到窗口出现才能获取句柄
connect(this,&Unreal4::sigUe4Complete,this,&Unreal4::slotUe4Complete);
void Unreal4::slotUe4Complete()
{
//createWindowContainer方式不好
// _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.定时器定时显示窗口到最上层
函数:
BOOL SetWindowPos(
[in] HWND hWnd,
[in, optional] HWND hWndInsertAfter,
[in] int X,
[in] int Y,
[in] int cx,
[in] int cy,
[in] UINT uFlags
);
将hWnd
移动到hWndInsertAfter
下层,并设置位置和大小,显示方式。
HWND GetWindow(
[in] HWND hWnd,
[in] UINT uCmd
);
要获取已知窗口上层的窗口句柄可用 GetWindow( (HWND)this->winId() ,GW_HWNDPREV )
当主要窗口和ue程序为活动窗口时,将hWndInsertAfter
设置为HWND_TOPMOST
,uFlags
设置为SWP_NOACTIVATE
只显示不激活
当主要窗口不为活动窗口时,将hWndInsertAfter
设置为 GetWindow( (HWND)this->winId() ,GW_HWNDPREV )
,uFlags
设置为SWP_NOACTIVATE
只显示不激活
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.重写QWidget事件
函数:
- 设置窗口显示:
ShowWindow(HWND, int nCmdShow)
设置nCmdShow
:显示不激活为SW_SHOWNOACTIVATE
,隐藏为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.源码
pro文件中加入:LIBS += -luser32
头文件:
#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 将UE4界面嵌入QT界面
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
源文件:
#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);
}
边栏推荐
- [English] Verb Classification of grammatical reconstruction -- English rabbit learning notes (2)
- The registration password of day 239/300 is 8~14 alphanumeric and punctuation, and at least 2 checks are included
- Cobalt Strike特征修改
- Attributeerror: can 't get attribute' sppf 'on < module' models. Common 'from' / home / yolov5 / Models / comm
- Bitcoinwin (BCW): the lending platform Celsius conceals losses of 35000 eth or insolvency
- What are the characteristics of trademark translation and how to translate it?
- Market segmentation of supermarket customers based on purchase behavior data (RFM model)
- 机器人类专业不同层次院校课程差异性简述-ROS1/ROS2-
- Introduction and underlying analysis of regular expressions
- Chapter 7 - thread pool of shared model
猜你喜欢
基于购买行为数据对超市顾客进行市场细分(RFM模型)
Basic commands of MySQL
SAP SD发货流程中托盘的管理
Apache dolphin scheduler source code analysis (super detailed)
AI on the cloud makes earth science research easier
Fedora/rehl installation semanage
女生学软件测试难不难 入门门槛低,学起来还是比较简单的
How effective is the Chinese-English translation of international economic and trade contracts
Attributeerror: can 't get attribute' sppf 'on < module' models. Common 'from' / home / yolov5 / Models / comm
Cobalt strike feature modification
随机推荐
Tms320c665x + Xilinx artix7 DSP + FPGA high speed core board
MySQL5.72.msi安装失败
How to do a good job in financial literature translation?
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
翻译影视剧字幕,这些特点务必要了解
My seven years with NLP
Difference between backtracking and recursion
UNIPRO Gantt chart "first experience": multi scene exploration behind attention to details
Data security -- 13 -- data security lifecycle management
Chapter 7 - thread pool of shared model
Apache dolphin scheduler source code analysis (super detailed)
(practice C language every day) reverse linked list II
Bitcoinwin (BCW): 借贷平台Celsius隐瞒亏损3.5万枚ETH 或资不抵债
端午节快乐Wish Dragon Boat Festival is happy
SQL Server Manager studio (SSMS) installation tutorial
ROS2安装及基础知识介绍
Phishing & filename inversion & Office remote template
成功解决TypeError: data type ‘category‘ not understood
Attributeerror successfully resolved: can only use cat accessor with a ‘category‘ dtype
[ 英语 ] 语法重塑 之 英语学习的核心框架 —— 英语兔学习笔记(1)