UE4之Slate:App默认窗口的创建流程
UE4版本:4.24.3源码编译
Windows10 + VS2019开发环境
在先前分享的基础上,现在来梳理下App启动时默认窗口的创建流程,以及相关的类、对象之间的抽象层级:
1、窗口创建流程
Q:App启动过程中,窗口是何时创建的?
Win32 API中创建窗口使用CreateWindowXX系列函数,VS中全局搜索一下CreateWindow,如下图是想要找的地方
全局搜索时不要勾选【Match whole world】

图1:全局搜索CreateWindow系列函数的调用
图一中源码路径:Source/Runtime/ApplicationCore/Private/Windows/WindowsWindow.cpp是需要找的调用;
在项目工程属性中:Debugging->Command Arguments中,添加-game参数:
VS中运行后,以Game模式启动,而非启动编辑器界面;
可以排除Editor相关的函数调用,模拟最终游戏的启动和运行流程;
VS中断点调试,拿到的调用堆栈如下图:
图2:窗口创建时的调用堆栈
从图2中可以看到,CreateWindowEx函数的调用过程中涉及到了下面几个类:
- FEngineLoop
- FPreLoadScreenManager
- UGameEngine
- FSlateApplication
- FWindowsApplication
- FWindowsWindow
定位到UGameEngine::CreateGameWindows()函数定义处,该函数创建的对象类型其实是SWindow;
// SNew宏创建一个SWindow实例(SWindow是SWidget派生类,参看前面的SImage用法)
TSharedRef<SWindow> Window = SNew(SWindow)
该SWindow实例被添加到FSlateApplication类中,被保存在SlateWindows这个数组中:定位到FSlateApplication::AddWindow()函数处可以查看
FSlateApplication::Get().AddWindow( Window, bShowImmediately );
FSlateApplication::AddWindow(...)函数内部,除了保存SWindow实例外,还会调用FSlateApplication::MakeWindow(...)创建一个FGenericWindow对象;
稍微追一下代码,会发现:
- 该FGenericWindow对象的实际类型是FWindowsWindow;
- FSlateApplication::MakeWindow(...)函数中出现的那个PlatformApplication实例,其类型为FWindowsApplication
关于PlatformApplication这个实例,参考FSlateApplication::Create(...)函数;
回到UGameEngine::CreateGameWindow()函数定义处:
SWindow实例会调用ShowWindow()函数,函数内部会调用到FWindowsWindow实例的Show()方法:该方法内部针对先前CreateWindowEx(...)函数创建的Win32窗口句柄做显示动作;
这部分分析过程中,会涉及到下面这些新出现的类:
- FGenericWindow
- FGenericApplication
- FGenericAcpplicationMisc
- FWindowsPlatformApplicationMisc
- FPlatformApplicationMisc 该类是一个typedef,指向具体平台的FXXXPlatformApplicationMisc类
- FSlateApplicationBase
以上整个UGameEngine::CreateGameWindow(...)函数调用的过程,就是窗口创建的过程;
2、类、对象的分析
类FSlateApplication继承自FSlateApplicationBase类;单例形式,管理并驱动整个Slate SWidget的渲染和事件派发等重要任务;
SWindow类抽象并封装平台Window对象;
FGenericApplication、FGenericWindow类是多平台对应类的基类,具体平台的逻辑操作在派生类中执行,实现各平台Api的封装;
3、总结、扩展
这次主要是追一下UE4引擎源码中,在Windows平台下,最基础的窗口是如何创建的;
对于其中涉及到的一些类和彼此之间的抽象关系做一个粗粒度的感性认识;
对于游戏引擎,各图形单元的渲染使用DirectX、OpenGL、Metal等底层硬件加速Api,并不依赖平台自身开发框架提供的Native控件;
窗口创建后,一般都会需要一个Content上下文初始化的工作,这块涉及到具体游戏引擎的渲染模块,以后有机会在来分享;
起始的窗口大小:
在项目工程属性中:Debugging->Command Arguments中,添加ResX=1280 ResY=720参数
ResX=1280 ResY=720参数设定窗口的启动大小:相关的代码可以参考:
static void UGameEngine::ConditionallyOverrideSettings(...);
static void UGameEngine::DetermineGameWindowResolution(...);
另外:上面全局搜索CreateWindo函数调用时,搜索结果中有出现一个WindowsPlatformSplash.cpp文件;
当中也有调用到CreateWindowEx(...)函数
这里其实就是引擎、或者VS中直接带-game参数启动时那个黑色的类似一个Loading界面的窗口
对应的图片资源在引擎Engine\Content\Splash目录下,有兴趣可以翻一下WindowsPlatformSplash.cpp源码
UE4之Slate:App默认窗口的创建流程的更多相关文章
- UE4之Slate: App启动与最外层Runtime结构
UE4版本:4.24.3源码编译: Windows10 + VS开发环境 Slate为一套自定义UI框架,其绘制直接依赖的是OpenGL.DirectX这样的硬件加速AIP;可以理解为一个单独的2D图 ...
- Cinder-2 窗口的创建过程
通过TinderBox生成的代码很简单,整个代码如下: #include "cinder/app/AppNative.h" #include "cinder/gl/gl. ...
- 一个先进的App框架:使用Ionic创建一个简单的APP
原文 http://www.w3cplus.com/mobile/building-simple-app-using-ionic-advanced-html5-mobile-app-framewor ...
- day99:MoFang:Flask-JSONRPC提供RPC接口&在APP进行窗口页面操作(窗口-帧-帧组)
目录 1.服务端基于Flask-JSONRPC提供RPC接口 1.Flask-JSONRPC简介 2.安装Flask-JSONRPC模块 3.快速实现一个测试的RPC接口 4.移动端访问测试接口 2. ...
- UE4之Slate: SImage
概述 距离上次记录<UE4之Slate:纯C++工程配置>后已经好长时间了: 这个随笔来记录并分享一下SImage控件的使用,以在屏幕上显示一张图片: 目标 通过SImage控件的展示,学 ...
- uCGUI窗口的创建过程分析
一.相关结构体和变量 窗口管理结构体 /* 窗口管理结构体 共30个字节 */ struct WM_Obj { GUI_RECT Rect; //窗口尺寸(x0,y0,x1,y1) 8个字节 GUI_ ...
- win32 api Windows窗口的创建
windows窗口的创建有以下几个步骤: 1.创建注册窗口类 2.创建窗口句柄 3.显示更新窗口 4.消息循环 1.创建注册窗口类 所谓创建窗口类就是定义一个WNDCLASS类对象,并将该对象进行初始 ...
- vc++窗口的创建过程(MFC消息机制的经典文章)
一.什么是窗口类 在Windows中运行的程序,大多数都有一个或几个可以看得见的窗口,而在这些窗口被创建起来之前,操作系统怎么知道该怎样创建该窗口,以及用户操作该窗口的各种消息交给谁处理呢?所以VC ...
- Windows窗口的创建
Windows窗口创建的基本代码: #include <Windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); i ...
随机推荐
- Photoshop教程,视频MP4格式转换为GIF格式
转自百度问题 https://zhidao.baidu.com/question/1497485136643778259.html Adobe PhotoShop软件的最bai新du本是可以编辑视zh ...
- 嵌入式大佬给你分析stm32串口
stm32作为现在嵌入式物联网单片机行业中经常要用多的技术,相信大家都有所接触,今天这篇就给大家详细的分析下有关于stm32的出口,还不是很清楚的朋友要注意看看了哦,在最后还会为大家分享有些关于stm ...
- 字符串与模式匹配算法(四):BM算法
一.BM算法介绍 BM算法(Boyer-Moore算法)是罗伯特·波义尔(Robert Boyer)和杰·摩尔(J·Moore)在1977年共同提出的.与KMP算法不同的是,BM算法是模式串P由左向右 ...
- Relocations in generic ELF (EM: 40)
最近在搞机器上的wifi热点,需要移植一大堆东西,如hostapd\wpa_suppliant.dhcp等,这些玩意又依赖其他的一大堆库的移植,比如libnl,openssl等,今天在移植编译libn ...
- ST表 求 RMQ(区间最值)
RMQ即Range Minimum/Maximun Query,中文意思:查询一个区间的最小值/最大值 比如有这样一个数组:A{3 2 4 5 6 8 1 2 9 7},然后问你若干问题: 数组A下标 ...
- js this指向汇总
this指向 普通函数 window 定时器函数 window 事件函数 事件源 箭头函数 父function中的this,没有就是window 对象函数 对象本身 构造函数 实例化 ...
- vim 脚本,自动添加文件头部信息
相信很多人编写脚本的时候都会在脚本头部写一些信息,记录文件生成时候,生成人姓名等 建议在自己的家目录下的 .vimrc 文件 下添加以下内容 [ autocmd BufNewFile *.sh exe ...
- 重新整理 .net core 实践篇——— filter[四十四]
前言 简单介绍一下filter 正文 filter 的种类,微软文档中写道: 每种筛选器类型都在筛选器管道中的不同阶段执行: 授权筛选器最先运行,用于确定是否已针对请求为用户授权. 如果请求未获授权, ...
- 攻防世界 Misc 新手练习区 坚持60s Writeup
攻防世界 Misc 新手练习区 坚持60s Writeup 题目介绍 题目考点 java反编译 jd-gui 的使用 Writeup 下载附件并打开 kali执行命令 java -jar 9dc125 ...
- vue中axios的post和get请求示例
POST请求 methods: { isclick() { if (this.account == "" || this.pwd == "") { this.$ ...