ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

nim_duilib界面库快速上手(Windows系统,VS 2022)

nim_duilib界面库快速上手(Windows系统,VS 2022) nim_duilib界面库快速上手Windows系统VS 2022此示例将引导你快速部署一个基于 nim_duilib 的基本应用此示例与examples中的basic项目相似如果你更喜欢查看代码可以打开examples.sln工程参考示例代码而无需多花费时间。获取项目代码并编译获取项目代码gitclone https://github.com/rhett-lee/nim_duilib获取skia代码的编译方法和修改的代码nim_duilib使用skia作为绘制引擎所以先要编译skiagitclone https://github.com/rhett-lee/skia_compile编译skia源码按照skia_compile项目文档Windows下编译skia.md中的方法编译出skia相关的lib文件注意事项skia源码应该与nim_duilib源码位于相同的目录下。注意事项skia源码编译的时候应使用LLVM编译程序运行比较流畅如果使用VS编译运行速度很慢界面比较卡。检查方法编译成功以后在skia/out的子目录下有生成skia.lib等lib文件。在工作目录内几个项目的源码目录的基本结构如下编译nim_duilib进入nim_duilib目录使用 Visual Studio 2022版本的 IDE 打开examples.sln选择编译选项为Debug|x64或者Release|x64按下 F7 即可编译所有示例程序编译完成的示例程序位于bin目录中。创建基础工程使用 Visual Studio 打开项目目录中examples.sln解决方案新建一个 Windows 桌面应用来一步一步完成第一个基于 duilib 界面库的程序。在examples.sln解决方案中新建一个 Windows 桌面程序VS2022程序类型为Windows Desktop Application。假定程序名为MyDuilibApp源码放在examples子目录中。将生成的代码清理一下只保留关键的 wWinMain 函数#includeMainThread.hintAPIENTRYwWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPWSTR lpCmdLine,_In_intnCmdShow){UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);//正常退出程序return0;}配置项目属性使用nim_duilib提供的通用配置msvc\PropertySheets\BinCommonSettings.props1用文本编辑器打开刚刚创建的工程文件examples\MyDuilibApp\MyDuilibApp.vcxproj2找到Import Project$(VCTargetsPath)\Microsoft.Cpp.Default.props /这一行的位置在这行的后面插入一行添加一下内容Import Project..\..\msvc\PropertySheets\BinCommonSettings.props /3保存该工程文件的修改如果已经在VS中打开需要重新加载。项目右键-添加-引用将 duilib、cximage、libpng、libwebp、zlib 作为引用项目这样就不需要手动引入静态库文件了。添加成功后可以看到引用成功的项目引入线程库在创建的项目中增加自定义的线程类MainThread主线程和一个工作线程创建两个文件MainThread.h和MainThread.cpp并添加到VS工程中两个文件的内容分别如下MainThread.h#ifndefEXAMPLES_MAIN_THREAD_H_#defineEXAMPLES_MAIN_THREAD_H_// duilib#includeduilib/duilib.h/** 主线程 */classMainThread:publicui::FrameworkThread{public:MainThread();virtual~MainThread()override;private:/** 运行前初始化在进入消息循环前调用 */virtualvoidOnInit()override;/** 退出时清理在退出消息循环后调用 */virtualvoidOnCleanup()override;};#endif// EXAMPLES_MAIN_THREAD_H_MainThread.cpp#includeMainThread.h#includeMainForm.hMainThread::MainThread():FrameworkThread(_T(MainThread),ui::kThreadUI){}MainThread::~MainThread(){}voidMainThread::OnInit(){//初始化全局资源, 使用本地文件夹作为资源ui::FilePath resourcePathui::FilePathUtil::GetCurrentModuleDirectory();resourcePath_T(resources\\);ui::GlobalManager::Instance().Startup(ui::LocalFilesResParam(resourcePath));//在下面加入启动窗口代码////创建一个默认带有阴影的居中窗口MainForm*windownewMainForm();window-CreateWnd(nullptr,ui::WindowCreateParam(_T(MyDuilibApp),true));window-PostQuitMsgWhenClosed(true);window-ShowWindow(ui::kSW_SHOW_NORMAL);}voidMainThread::OnCleanup(){ui::GlobalManager::Instance().Shutdown();}在 wWinMain 实例化主线程对象并调用执行主线程循环添加后 wWinMain 函数修改如下#includeMainThread.hintAPIENTRYwWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPWSTR lpCmdLine,_In_intnCmdShow){UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);//创建主线程MainThread thread;//执行主线程消息循环thread.RunMessageLoop();//正常退出程序return0;}创建一个简单窗口创建一个窗口类MainForm继承ui::WindowImplBase类并覆写GetSkinFolderGetSkinFile等方法。//MainForm.h#ifndefEXAMPLES_MAIN_FORM_H_#defineEXAMPLES_MAIN_FORM_H_// duilib#includeduilib/duilib.h/** 应用程序的主窗口实现 */classMainForm:publicui::WindowImplBase{typedefui::WindowImplBase BaseClass;public:MainForm();virtual~MainForm()override;/** 创建窗口时被调用由子类实现用以获取窗口皮肤目录 * return 子类需实现并返回窗口皮肤目录 */virtualDStringGetSkinFolder()override;/** 创建窗口时被调用由子类实现用以获取窗口皮肤 XML 描述文件 * return 子类需实现并返回窗口皮肤 XML 描述文件 * 返回的内容可以是XML文件内容以字符为开始的字符串 * 或者是文件路径不是以字符开始的字符串文件要在GetSkinFolder()路径中能够找到 */virtualDStringGetSkinFile()override;/** 当窗口创建完成以后调用此函数供子类中做一些初始化的工作 */virtualvoidOnInitWindow()override;};#endif//EXAMPLES_MAIN_FORM_H_//MainForm.cpp#includeMainForm.hMainForm::MainForm(){}MainForm::~MainForm(){}DStringMainForm::GetSkinFolder(){return_T(my_duilib_app);}DStringMainForm::GetSkinFile(){return_T(MyDuilibForm.xml);}voidMainForm::OnInitWindow(){BaseClass::OnInitWindow();//窗口初始化完成可以进行本Form的初始化}创建窗口描述 XML 文件在我们创建的窗口类中指定了窗口描述文件目录是my_duilib_app指定窗口的描述文件为MyDuilibForm.xml。接下来在bin\resources\themes\default目录下创建my_duilib_app文件夹并新建一个MyDuilibForm.xml文件写下如下内容。注意事项XML文件的编码格式是UTF-8。?xml version1.0 encodingUTF-8?Windowsize800,600mininfo80,60caption0,0,0,36use_system_captionfalsesnap_layout_menutruesys_menutruesys_menu_rect0,0,36,36shadow_typedefaultshadow_attachedtruelayered_windowtruealpha255sizebox4,4,4,4icon../public/caption/logo.icoVBoxbkcolorbk_wnd_darkcolorvisibletrue!-- 标题栏区域 --HBoxnamewindow_caption_barwidthstretchheight36bkcolorbk_wnd_lightcolorControl/Buttonclassbtn_wnd_fullscreen_11height32width40namefullscreenbtnmargin0,2,0,2tooltip_text全屏按ESC键可退出全屏/Buttonclassbtn_wnd_min_11height32width40nameminbtnmargin0,2,0,2tooltip_text最小化/Boxheightstretchwidth40margin0,2,0,2Buttonclassbtn_wnd_max_11height32widthstretchnamemaxbtntooltip_text最大化/Buttonclassbtn_wnd_restore_11height32widthstretchnamerestorebtnvisiblefalsetooltip_text还原//BoxButtonclassbtn_wnd_close_11heightstretchwidth40nameclosebtnmargin0,0,0,2tooltip_text关闭//HBox!-- 工作区域除了标题栏外的内容都放在这个大的Box区域 --BoxVBoxmargin0,0,0,0valigncenterhaligncenterLabelnametooltiptext这是一个简单的nim_duilib窗口带有标题栏和常规按钮。height100%width100%text_alignhcenter,vcenter//VBox/Box/VBox/Window显示窗口在主线程的 MainThread::Init 方法中创建窗口并居中显示创建窗口前先引入窗口的头文件修改后的代码如下首先在文件中包含头文件#include MainForm.hvoidMainThread::OnInit(){//初始化全局资源, 使用本地文件夹作为资源ui::FilePath resourcePathui::FilePathUtil::GetCurrentModuleDirectory();resourcePath_T(resources\\);ui::GlobalManager::Instance().Startup(ui::LocalFilesResParam(resourcePath));//在下面加入启动窗口代码////创建一个默认带有阴影的居中窗口MainForm*windownewMainForm();window-CreateWnd(nullptr,ui::WindowCreateParam(_T(MyDuilibApp),true));window-PostQuitMsgWhenClosed(true);window-ShowWindow(ui::kSW_SHOW_NORMAL);}这样一个简单的带有最小化、最大化、还原和关闭按钮、全屏按钮具有阴影效果和一行文字提示的窗口就创建出来了你可以编译运行以下代码看一看窗口效果。在程序中使用libCEF可以参考相关的文档CEF.md关于Visual Studio的工程配置项目中关于Visual Studio的工程配置是使用属性文件保存在以下目录nim_duilib\msvc\PropertySheets如何设置项目中使用的源代码文件编码为UTF-8格式在项目根目录创建一个格式配置文件文件名为.editorconfig文件内容如下# Visual Studio generated .editorconfig file with C settings. root true [*.{c,c,cc,cpp,cppm,cxx,h,h,hh,hpp,hxx,inl,ipp,ixx,tlh,tli}] # Visual C Formatting settings end_of_line crlf # 行尾格式可选值为 lfUnix 风格、crMac 风格或 crlfWindows 风格 charset utf-8 # 文件编码字符集为 UTF-8可选值为 utf-8、utf-8-bom、latin1 等 trim_trailing_whitespace true # 删除文件末尾空格 insert_final_newline true # 末尾插入新行 indent_style space # 以空格代替 tab indent_size 4 # 代替 tab 的空格数量 tab_width 4 # 制表符的宽度该方法适用于Visual Studio 2022。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进