快速入门教程¶
本指南将带您一步步创建第一个 SOUI5 应用程序。我们将通过一个简单的"Hello World"应用程序,帮助您快速了解 SOUI5 的基本概念和开发流程。
学习目标¶
完成本指南后,您将了解: - SOUI5 应用程序的基本结构 - 如何创建简单的用户界面 - 如何处理基本的用户交互 - SOUI5 的资源管理方式 - CMake 构建配置
前置要求¶
在开始之前,请确保您已经:
- 完成了 安装指南 中的环境配置
- 熟悉基本的 C++ 编程
- 了解 CMake 构建系统的基本用法
- 安装了支持 C++11 的编译器
项目概述¶
我们将基于 SOUI5 提供的 CMake 项目模板创建一个简单的应用程序,它包含:
- 主窗口界面
- 文本显示控件
- 按钮交互
- 资源管理系统
- CMake 构建配置
步骤 1:获取项目模板¶
SOUI5 提供了现成的 CMake 项目模板,位于 soui\wizard\CmakeApp
目录下。您可以直接复制这个目录作为项目起点。
# 复制模板到新项目目录
cp -r soui/wizard/CmakeApp HelloSOUI5
cd HelloSOUI5
项目模板结构如下:
HelloSOUI5/
├── CMakeLists.txt # CMake 构建文件
├── Soui5Wizard.cpp # 程序入口点
├── MainDlg.h # 主窗口类头文件
├── MainDlg.cpp # 主窗口类实现
├── stdafx.h # 预编译头文件
├── stdafx.cpp # 预编译头实现
├── resource.h # 资源头文件
├── Soui5Wizard.rc # 资源文件
├── license.txt # 许可文件
├── readme.txt # 说明文件
├── res/ # 资源目录
│ ├── resource.h # 资源ID定义
│ └── soui_res.rc2 # 资源定义文件
└── uires/ # UI资源目录
├── uires.idx # 资源索引文件
├── image/ # 图片资源
│ └── soui.ico # 应用图标
├── uidef/ # 系统初始化配置
│ └── init.xml # 初始化配置文件
├── values/ # 资源值定义
│ ├── color.xml # 颜色定义
│ ├── skin.xml # 皮肤定义
│ └── string.xml # 字符串定义
└── xml/ # XML 布局文件
└── dlg_main.xml # 主窗口布局
步骤 2:理解应用程序入口点¶
在 Soui5Wizard.cpp 中是应用程序的入口点,主要包含以下内容:
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int /*nCmdShow*/)
{
HRESULT hRes = OleInitialize(NULL);
SASSERT(SUCCEEDED(hRes));
int nRet = 0;
SApplication app(hInstance);
SAppCfg cfg;
SStringT srcDir = getResourceDir();
cfg.SetRender(Render_Skia).SetImgDecoder(ImgDecoder_Stb).SetAppDir(srcDir).SetLog(TRUE);
#ifdef _WIN32
cfg.SetSysResPeFile(SYS_NAMED_RESOURCE);
#else
cfg.SetSysResZipFile(srcDir+_T("data/soui-sys-resource.zip"));
#endif //_WIN32
#if !defined(_WIN32) || defined(_DEBUG)
cfg.SetAppResFile(srcDir+_T("data/uires"));
#else
cfg.SetAppResPeHandle(hInstance);
#endif
//cfg.EnableMultiLang(_T("translator:lang_cn"), TRUE);
//cfg.EnableScript(TRUE);
// regisger external widget and skinobj
if (!cfg.DoConfig(&app))
{
return -1;
}
#ifndef _WIN32
AddFontResource("fonts/simsun.ttc");
#endif //_WIN32
// 如果需要在代码中使用R::id::namedid这种方式来使用控件必须要这一行代码:2016年2月2日,R::id,R.name是由uiresbuilder
// 增加-h .\res\resource.h 这2个参数后生成的。
app.InitXmlNamedID((const LPCWSTR *)&R.name, (const int *)&R.id, sizeof(R.id) / sizeof(int));
{
// show main window
CMainDlg dlgMain;
dlgMain.Create(GetActiveWindow());
dlgMain.SendMessage(WM_INITDIALOG);
dlgMain.CenterWindow(dlgMain.m_hWnd);
dlgMain.ShowWindow(SW_SHOWNORMAL);
nRet = app.Run(dlgMain.m_hWnd);
}
OleUninitialize();
return nRet;
}
这段代码完成了以下工作: 1. 初始化 COM 库 2. 创建 [SApplication] 对象 3. 配置应用程序参数,包括渲染器、图像解码器、资源路径等 4. 初始化资源 ID 映射 5. 创建并显示主窗口 6. 运行消息循环
步骤 3:理解主窗口实现¶
主窗口类 [CMainDlg]定义在 [MainDlg.h] 和 [MainDlg.cpp] 中。
MainDlg.h¶
class CMainDlg : public SHostWnd
, public SDpiHandler<CMainDlg>
{
public:
CMainDlg();
~CMainDlg();
void OnClose();
void OnMaximize();
void OnRestore();
void OnMinimize();
void OnSize(UINT nType, CSize size);
BOOL OnInitDialog(HWND wndFocus, LPARAM lInitParam);
protected:
//soui消息
EVENT_MAP_BEGIN()
EVENT_NAME_COMMAND(L"btn_close", OnClose)
EVENT_NAME_COMMAND(L"btn_min", OnMinimize)
EVENT_NAME_COMMAND(L"btn_max", OnMaximize)
EVENT_NAME_COMMAND(L"btn_restore", OnRestore)
EVENT_MAP_END2(SHostWnd)
//HostWnd真实窗口消息处理
BEGIN_MSG_MAP_EX(CMainDlg)
CHAIN_MSG_MAP(SDpiHandler<CMainDlg>)
MSG_WM_INITDIALOG(OnInitDialog)
MSG_WM_CLOSE(OnClose)
MSG_WM_SIZE(OnSize)
CHAIN_MSG_MAP(SHostWnd)
REFLECT_NOTIFICATIONS_EX()
END_MSG_MAP()
};
MainDlg.cpp¶
CMainDlg::CMainDlg() : SHostWnd(_T("LAYOUT:XML_MAINWND"))
{
}
CMainDlg::~CMainDlg()
{
}
BOOL CMainDlg::OnInitDialog(HWND hWnd, LPARAM lParam)
{
return 0;
}
void CMainDlg::OnClose()
{
SNativeWnd::DestroyWindow();
}
void CMainDlg::OnMaximize()
{
SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE);
}
void CMainDlg::OnRestore()
{
SendMessage(WM_SYSCOMMAND, SC_RESTORE);
}
void CMainDlg::OnMinimize()
{
SendMessage(WM_SYSCOMMAND, SC_MINIMIZE);
}
void CMainDlg::OnSize(UINT nType, CSize size)
{
SetMsgHandled(FALSE);
SWindow *pBtnMax = FindChildByName(L"btn_max");
SWindow *pBtnRestore = FindChildByName(L"btn_restore");
if(!pBtnMax || !pBtnRestore) return;
if (nType == SIZE_MAXIMIZED)
{
pBtnRestore->SetVisible(TRUE);
pBtnMax->SetVisible(FALSE);
}
else if (nType == SIZE_RESTORED)
{
pBtnRestore->SetVisible(FALSE);
pBtnMax->SetVisible(TRUE);
}
}
主窗口类的关键点: 1. 继承自 [SHostWnd],这是 SOUI 的主窗口基类 2. 使用 SDpiHandler<CMainDlg>
支持 DPI 自适应 3. 构造函数中使用 _T("LAYOUT:XML_MAINWND")
指定窗口布局资源 4. 通过事件映射表处理控件事件 5. 通过消息映射表处理 Windows 消息
步骤 4:理解 UI 资源¶
主窗口布局 (uires/xml/dlg_main.xml)¶
<SOUI name="mainWindow" title="@string/title" bigIcon="ICON_LOGO:32" smallIcon="ICON_LOGO:16" margin="5,5,5,5" resizable="1" wndType="appMain"
appWnd="1"
translucent="1"
>
<root skin="_skin.sys.wnd.bkgnd" cache="1" width="600" height="400" layout="vbox" padding="5,5,5,5">
<caption size="-2,30" layout="hbox" interval="0" gravity="center">
<icon src="ICON_LOGO:16"/>
<text >@string/title</text>
<window size="0,0" weight="1"/>
<imgbtn name="btn_min" skin="_skin.sys.btn.minimize" animate="1" />
<window>
<imgbtn pos="0,0" name="btn_max" skin="_skin.sys.btn.maximize" animate="1" />
<imgbtn pos="0,0" name="btn_restore" skin="_skin.sys.btn.restore" show="0" animate="1" />
</window>
<imgbtn name="btn_close" skin="_skin.sys.btn.close" tip="close" animate="1"/>
</caption>
<window size="-2,0" weight="1">
<text pos="|0,|0" offset="-0.5,-0.5">这是一个由SOUI向导生成的APP框架</text>
</window>
</root>
</SOUI>
字符串资源 (uires/values/string.xml)¶
<?xml version="1.0" encoding="utf-8"?>
<string>
<title>SOUI5向导生成的APP</title>
</string>
资源索引 (uires/uires.idx)¶
<resource>
<UIDEF>
<file name="XML_INIT" path="uidef\init.xml"/>
</UIDEF>
<LAYOUT>
<file name="XML_MAINWND" path="xml\dlg_main.xml"/>
</LAYOUT>
<values>
<file name="string" path="values\string.xml"/>
<file name="color" path="values\color.xml"/>
<file name="skin" path="values\skin.xml"/>
</values>
<IMG>
</IMG>
<ICON>
<file name="ICON_LOGO" path="image\soui.ico"/>
</ICON>
</resource>
步骤 5:理解 CMake 构建配置¶
项目模板中的 [CMakeLists.txt]文件配置了完整的构建流程:
cmake_minimum_required(VERSION 3.16)
set(project_name "soui5_app")
project(${project_name})
关键配置包括: 1. 设置项目名称和最低 CMake 版本 2. 查找 SOUI 安装路径 3. 配置编译器和链接器选项 4. 处理资源文件生成 5. 创建可执行文件 6. 配置资源文件复制
步骤 6:构建和运行¶
构建项目¶
在项目根目录下执行以下命令:
# 创建构建目录
mkdir build
cd build
# 配置 CMake(Release 版本)
cmake .. -DCMAKE_BUILD_TYPE=Release
# 编译项目
cmake --build . --config Release
运行程序¶
构建完成后,可执行文件将在 build
目录下:
# 运行程序(Windows)
.\build\soui5_app.exe
程序说明¶
资源管理¶
uires.idx
:资源索引文件,定义所有资源的映射关系uidef/init.xml
:全局 UI 配置,包括字体、皮肤、样式等xml/dlg_main.xml
:主窗口布局定义values/string.xml
:字符串资源定义
控件布局¶
SOUI5 使用位置属性 pos
来定义控件布局: - size="-2,30"
:宽度为父窗口宽度减去 margins,高度为 30 像素 - pos="|0,|0" offset="-0.5,-0.5"
:居中定位 - weight="1"
:在布局中占据剩余空间
事件处理¶
使用事件映射表来处理用户交互:
EVENT_MAP_BEGIN()
EVENT_NAME_COMMAND(L"btn_close", OnClose)
EVENT_NAME_COMMAND(L"btn_min", OnMinimize)
EVENT_NAME_COMMAND(L"btn_max", OnMaximize)
EVENT_NAME_COMMAND(L"btn_restore", OnRestore)
EVENT_MAP_END2(SHostWnd)
验证功能¶
运行程序后,您应该看到: 1. 主窗口:显示"SOUI5向导生成的APP"的标题 2. 窗口控制按钮:最小化、最大化、关闭按钮 3. 提示文本:窗口中央显示"这是一个由SOUI向导生成的APP框架"
下一步学习¶
完成本指南后,建议继续学习:
总结¶
通过本指南,您已经: - 了解了 SOUI5 应用程序的基本结构 - 学会了使用项目模板快速创建应用程序 - 理解了 SOUI5 的资源管理系统 - 掌握了基本的界面布局和事件处理 - 学会了使用 CMake 构建 SOUI5 应用程序
这些基础知识将为您进一步学习 SOUI5 打下坚实的基础。