当前位置:网站首页>将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);
}
边栏推荐
- Market segmentation of supermarket customers based on purchase behavior data (RFM model)
- Attributeerror successfully resolved: can only use cat accessor with a ‘category‘ dtype
- Fledgling Xiao Li's 103rd blog CC2530 resource introduction
- Facebook AI & Oxford proposed a video transformer with "track attention" to perform SOTA in video action recognition tasks
- 翻译生物医学说明书,英译中怎样效果佳
- How to translate biomedical instructions in English
- Leetcode daily question (971. flip binary tree to match preorder traversal)
- 云上有AI,让地球科学研究更省力
- 自动化测试环境配置
- Reflex WMS medium level series 3: display shipped replaceable groups
猜你喜欢
AttributeError: Can‘t get attribute ‘SPPF‘ on <module ‘models.common‘ from ‘/home/yolov5/models/comm
Cobalt strike feature modification
[ 英语 ] 语法重塑 之 动词分类 —— 英语兔学习笔记(2)
SQL Server manager studio(SSMS)安装教程
女生学软件测试难不难 入门门槛低,学起来还是比较简单的
【刷题】怎么样才能正确的迎接面试?
Modify the list page on the basis of jeecg boot code generation (combined with customized components)
26岁从财务转行软件测试,4年沉淀我已经是25k的测开工程师...
Cobalt Strike特征修改
翻译影视剧字幕,这些特点务必要了解
随机推荐
A 27-year-old without a diploma, wants to work hard on self-study programming, and has the opportunity to become a programmer?
Chinese English comparison: you can do this Best of luck
生物医学本地化翻译服务
Fedora/rehl installation semanage
Monotonic stack
【刷题】怎么样才能正确的迎接面试?
删除外部表源数据
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
Attributeerror: can 't get attribute' sppf 'on < module' models. Common 'from' / home / yolov5 / Models / comm
翻译生物医学说明书,英译中怎样效果佳
Day 246/300 ssh连接提示“REMOTE HOST IDENTIFICATION HAS CHANGED! ”
一文读懂简单查询代价估算
万丈高楼平地起,每个API皆根基
论文翻译英译中,怎样做翻译效果好?
机器学习植物叶片识别
Reflex WMS medium level series 3: display shipped replaceable groups
Advanced MySQL: Basics (1-4 Lectures)
基于PyTorch和Fast RCNN快速实现目标识别
Machine learning plant leaf recognition
SAP SD发货流程中托盘的管理