c++ duiLib 显示一个简单的窗口
参照官方的指导文档,显示一个最简单windows窗口。入口源文件先加上这几句代码:
// 必须放在所有头文件包含之前. 预处理指令,编译优化,排除windows头文件(windows.h)中较少使用的组件
#define WIN32_LEAN_AND_MEAN
// 必须放在所有头文件包含之前. 兼容性控制宏. 禁用微软对不安全函数(如scanf、strcpy等)的编译警告
#define _CRT_SECURE_NO_DEPRECATE#include <duilib/UIlib.h>
#include <windows.h>
#include <objbase.h>using namespace DuiLib;
然后下面是窗口实例和消息响应:
// 窗口实例及消息响应部分
class CFrameWindowWnd : public CWindowWnd, public INotifyUI
{
public:CFrameWindowWnd() {};// 窗口唯一标识符LPCTSTR GetWindowClassName() const { return _T("UIMainFrame"); };// 定义窗口类样式。 UI_CLASSSTYLE_FRAME:窗口大小改变时触发重绘,通常用于带标题栏、边框的标准窗体。// CS_DBLCLKS:Windows 标准样式,启用窗口对鼠标双击消息的响应能力UINT GetClassStyle() const { return UI_CLASSSTYLE_FRAME | CS_DBLCLKS; };// 处理窗口生命周期终结void OnFinalMessage(HWND /*hWnd*/) { delete this; };// 核心功能:控件事件分发、消息传递枢纽void Notify(TNotifyUI& msg){if (msg.sType == _T("click")) {if (msg.pSender->GetName() == _T("I服了You")) { // 即点击的根控件root,代码见下面Close(); // 关闭窗口}}}LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam){if (uMsg == WM_CREATE) { // 成功创建窗口后, 系统会立即发送 WM_CREATE 消息, 标志着窗口句柄已有效但尚未显示m_pm.Init(m_hWnd); // 绑定窗口句柄,初始化绘图环境CControlUI* root = new CButtonUI;root->SetName(_T("I服了You"));root->SetBkColor(0xFFcccccc);m_pm.AttachDialog(root); // 关联控件树根节点,启动界面渲染. 根控件与绘图管理器关联. 这里根控件为rootm_pm.AddNotifier(this); // 注册事件监听器,接收控件通知(如 Notify 消息)return 0;}else if (uMsg == WM_DESTROY) { // 窗口销毁::PostQuitMessage(0); // 0表示正常退出}LRESULT lRes = 0;// 将 Windows 消息(uMsg)交由 CPaintManagerUI 处理(即交给对应控件处理),若返回 true 表示消息已被消费,直接返回处理结果if (m_pm.MessageHandler(uMsg, wParam, lParam, lRes)) return lRes;return CWindowWnd::HandleMessage(uMsg, wParam, lParam); // 基类默认处理消息的流程}public:CPaintManagerUI m_pm; // 承担界面绘制、消息处理和控件管理的核心职责
};
再下面是程序入口:
// 程序入口及Duilib初始化部分
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int nCmdShow)
{CPaintManagerUI::SetInstance(hInstance);CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());CFrameWindowWnd* pFrame = new CFrameWindowWnd();if (pFrame == NULL) return 0;pFrame->Create(NULL, _T("别人笑我太疯癫,我笑他人看不穿"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);pFrame->ShowWindow(true);CPaintManagerUI::MessageLoop();return 0;
}
运行结果:
ok . 点击页面窗口消失。 如果不想显示系统标题栏,需加上WM_NCACTIVATE、WM_NCCALCSIZE、WM_NCPAINT 这几个消息处理,窗口实例和消息响应这部分改为如下代码:
// 窗口实例及消息相应部分
class CFrameWindowWnd : public CWindowWnd, public INotifyUI
{
public:CFrameWindowWnd() {};// 窗口唯一标识符LPCTSTR GetWindowClassName() const { return _T("UIMainFrame"); };// 定义窗口类样式。 UI_CLASSSTYLE_FRAME:窗口大小改变时触发重绘,通常用于带标题栏、边框的标准窗体。// CS_DBLCLKS:Windows 标准样式,启用窗口对鼠标双击消息的响应能力UINT GetClassStyle() const { return UI_CLASSSTYLE_FRAME | CS_DBLCLKS; };// 处理窗口生命周期终结void OnFinalMessage(HWND /*hWnd*/) { delete this; };// 核心功能:控件事件分发、消息传递枢纽void Notify(TNotifyUI& msg){if (msg.sType == _T("click")) {if (msg.pSender->GetName() == _T("I服了You")) { // 即点击的根控件root,代码见下面Close(); // 关闭窗口}}}LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam){if (uMsg == WM_CREATE) { // 成功创建窗口后, 系统会立即发送 WM_CREATE 消息, 标志着窗口句柄已有效但尚未显示m_pm.Init(m_hWnd); // 绑定窗口句柄,初始化绘图环境CControlUI* root = new CButtonUI;root->SetName(_T("I服了You"));root->SetBkColor(0xFFcccccc);m_pm.AttachDialog(root); // 关联控件树根节点,启动界面渲染. 根控件与绘图管理器关联. 这里根控件为rootm_pm.AddNotifier(this); // 注册事件监听器,接收控件通知(如 Notify 消息)return 0;}else if (uMsg == WM_DESTROY) { // 窗口销毁::PostQuitMessage(0); // 0表示正常退出}// 不想使用系统的标题栏和边框这些非客户区绘制,加上下面这俩分支(WM_NCACTIVATE、WM_NCCALCSIZE、WM_NCPAINT 消息)的处理else if (uMsg == WM_NCACTIVATE) { // 窗口获得焦点或失去焦点时收到该消息if (!::IsIconic(m_hWnd)) {// TRUE: 允许系统将非客户区绘制为失活状态(灰色标题栏)// FALSE: 阻止系统默认的激活状态绘制,可能用于实现自定义标题栏样式return (wParam == 0) ? TRUE : FALSE;}}else if (uMsg == WM_NCCALCSIZE) { // 当窗口大小或位置发生变化时,系统会发送该消息return 0; // 返回0屏蔽系统默认的标题栏计算. 这使得开发者可以用客户区完全模拟自定义标题栏,实现更灵活的界面设计}else if (uMsg == WM_NCPAINT) { // 用于非客户区绘制的消息,在duilib中主要用于屏蔽系统默认标题栏以实现自定义界面return 0;}LRESULT lRes = 0;// 将 Windows 消息(uMsg)交由 CPaintManagerUI 处理(即交给对应控件处理),若返回 true 表示消息已被消费,直接返回处理结果if (m_pm.MessageHandler(uMsg, wParam, lParam, lRes)) return lRes;return CWindowWnd::HandleMessage(uMsg, wParam, lParam); // 基类默认处理消息的流程}public:CPaintManagerUI m_pm; // 承担界面绘制、消息处理和控件管理的核心职责
};
运行结果:
ok. 后续再看下用自定义xml布局写页面。