Duilib支持xml界面布局,使得界面设计与逻辑处理相分离,本节介绍如何从xml文件中加载界面元素。
我们需要以下几个步骤:
- 创建并初始化CPaintManagerUI对象。
- 创建CDialogBuilder对象,调用CDialogBuilder对象的Create函数加载xml文件,该函数返回界面元素根节点。
- 调用CPaintManagerUI的AttachDialog將界面元素根节点附加到CPaintManagerUI对象中。
- 编写xml界面布局文件。
案例代码如下:
//代码清单tutorial3.cpp@H_502_18@
#include@H_502_18@ <@H_502_18@Windows.@H_502_18@h>@H_502_18@
#include@H_502_18@ "../DuiLib/StdAfx.h"@H_502_18@
using namespace DuiLib;
class CMyWnd : public@H_502_18@ CWindowWnd,public@H_502_18@ INotifyUI
{
public@H_502_18@:
CMyWnd(){}
LPCTSTR GetWindowClassName() const
{
return@H_502_18@ L"MyWnd"@H_502_18@;
}
UINT GetClassStyle() const{
return@H_502_18@ UI_CLASSSTYLE_FRAME|@H_502_18@CS_DBLCLKS;
}
void@H_502_18@ Notify(TNotifyUI&@H_502_18@ msg)
{
if@H_502_18@(msg.@H_502_18@sType ==@H_502_18@ L"click"@H_502_18@)
{
if@H_502_18@(msg.@H_502_18@pSender->@H_502_18@GetName() ==@H_502_18@ L"CloseBtn"@H_502_18@)
{
if@H_502_18@(IDOK ==@H_502_18@ ::MessageBox@H_502_18@(m_hWnd,L"退出程序?"@H_502_18@,L"提示信息"@H_502_18@,MB_OKCANCEL))
{
::PostQuitMessage@H_502_18@(0@H_502_18@);
}
}
}
}
LRESULT HandleMessage(UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
case@H_502_18@ WM_KEYDOWN:
{
int nVirtKey =@H_502_18@ (int) wParam;
if@H_502_18@(VK_ESCAPE ==@H_502_18@ nVirtKey)
{
::PostQuitMessage@H_502_18@(0@H_502_18@);
}
}
break;
case@H_502_18@ WM_CREATE:
{
m_PaintMgr.@H_502_18@Init(m_hWnd);
//从xml中加载界面@H_502_18@
CDialogBuilder builder;
m_pRoot =@H_502_18@ builder.@H_502_18@Create(L"tutorial3.xml"@H_502_18@,(UINT)0@H_502_18@,NULL@H_502_18@,&@H_502_18@m_PaintMgr);
m_PaintMgr.@H_502_18@AttachDialog(m_pRoot);
m_PaintMgr.@H_502_18@AddNotifier(this);
}
break;
case@H_502_18@ WM_DESTROY:
::PostQuitMessage@H_502_18@(0@H_502_18@);
break;
}
LRESULT lRes=@H_502_18@0@H_502_18@;
if@H_502_18@(m_PaintMgr.@H_502_18@MessageHandler(uMsg,wParam,lParam,lRes)) return@H_502_18@ lRes;
return@H_502_18@ CWindowWnd::HandleMessage@H_502_18@(uMsg,lParam);
}
~CMyWnd(){
delete m_pRoot;
}
private@H_502_18@:
CPaintManagerUI m_PaintMgr;
CControlUI*@H_502_18@ m_pRoot;
};
INT WinMain(HINSTANCE hInst,HINSTANCE hPreInst,LPSTR lpCmdLine,INT Show)
{
CPaintManagerUI::SetInstance@H_502_18@(hInst);
CPaintManagerUI::SetResourcePath@H_502_18@(CPaintManagerUI::GetResourcePath@H_502_18@());
//创建主窗口@H_502_18@
CMyWnd*@H_502_18@ pFrame =@H_502_18@ new@H_502_18@ CMyWnd();
pFrame->@H_502_18@Create(NULL@H_502_18@,L"Tutorial3"@H_502_18@,UI_WNDSTYLE_FRAME,WS_EX_WINDOWEDGE);
pFrame->@H_502_18@CenterWindow();
pFrame->@H_502_18@ShowWindow(true@H_502_18@);
CPaintManagerUI::MessageLoop@H_502_18@();
delete pFrame;
return@H_502_18@ 0@H_502_18@;
}
和上节相比我们在窗口消息WM_CREATE中创建了CDialogBuilder对象builder,调用Create方法加载界面布局文件tutorial3.xml。
CDialogBuilder builder;
m_pRoot = builder.Create@H_502_18@(L"tutorial3.xml"@H_502_18@,NULL@H_502_18@,&m_PaintMgr);@H_502_18@
m_PaintMgr.AttachDialog(m_pRoot);
接下来的工作就是编写界面布局文件tutorial3.xml,内容如下:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>@H_502_18@
<Window@H_502_18@ sizeBox@H_502_18@="4,4,6,6"@H_502_18@ size@H_502_18@="800,600"@H_502_18@ >@H_502_18@
<VerticalLayout@H_502_18@ name@H_502_18@="MainLayout"@H_502_18@ >@H_502_18@
<HorizontalLayout@H_502_18@ name@H_502_18@="Content"@H_502_18@ bkcolor@H_502_18@="#FFFF0000"@H_502_18@>@H_502_18@
<Button@H_502_18@ float@H_502_18@="true"@H_502_18@ name@H_502_18@="CloseBtn"@H_502_18@ text@H_502_18@="关闭按钮"@H_502_18@ bkcolor@H_502_18@="#FF0000FF"@H_502_18@ width@H_502_18@="150"@H_502_18@ height@H_502_18@="50"@H_502_18@ pos@H_502_18@="200,300,0"@H_502_18@ >@H_502_18@
</Button@H_502_18@>@H_502_18@
</HorizontalLayout@H_502_18@>@H_502_18@
</VerticalLayout@H_502_18@>@H_502_18@
</Window@H_502_18@>@H_502_18@
在界面布局文件中,我们同样定义一个名称为CloseBtn按钮。需要注意的一点是Duilib的界面布局xml文件必须是utf-8编码,大家尽量不要使用Windows自带的记事本编辑,可以使用UltraEdit和EditPlus將文件另存为utf-8编码格式。
编译运行同样可以看到窗口中有一个按钮:
博文源码:https://github.com/rongbo-j/duilib-tutorial (参考tutorial3工程)