Duilib的界面布局使用xml文件进行描述,在Duilib v1.1版本的xml布局文件中我们可以使用以下这些标签(后续版本标签有扩充):



这些标签总的来讲可以分为三类:

  1. 窗口类,该类别中只有一个Window标签,它表示一个Window窗口,是每个xml布局文件的根节点,也是必不可少的元素。
  2. 容器类,和该类别相关的标签有ChildLayout、Container、VerticalLayout、HorizontalLayout、TileLayout、TabLayout。该类标签主要用于控制按钮、编辑框等这些控件在窗口中如何摆放。例如VerticalLayout容器下的控件默认情况下都会按照先后顺序竖直摆放,而HorizontalLayout容器下的控件则水平摆放,需要注意的是容易中可以嵌套其他容器。
  3. 控件类,剩下的标签都属于控件类,例如Button标签表示窗口中的一个按钮、Edit标签用来表示编辑框等等。

一个最简单的xml布局文件需要哪些元素呢?实际上只需要一个Window标签和一个容器类标签就够了,容器类标签可以是ChildLayout、Container、VerticalLayout、HorizontalLayout、TileLayout、TabLayout中的任意一种,例如下面一个最简单的布局文件:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<Window size="432,320">
<TabLayout name="MainLayout"> </TabLayout>
</Window>

界面运行效果:



可以看到一个黑乎乎的窗口,客户区中什么都没有。

下面笔者向大家介绍一下HorizontalLayout和VerticalLayout容器在布局中的使用,使用这两种容器基本能完成大部分软件的界面效果。

1.HorizontalLayout,HorizontalLayout容器下的所有元素都会按照先后顺序水平排列,例如我们可以向该容器中添加几个按钮:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<Window size="432,320">
<HorizontalLayout name="MainLayout">
<Button text="Btn01" width="100" height="30" bkcolor="#FFFF0000" borderround="2,2"/>
<Button text="Btn02" width="100" height="30" bkcolor="#FFFF0000" borderround="2,2"/>
<Button text="Btn03" width="100" height="30" bkcolor="#FFFF0000" borderround="2,2"/>
<Button text="Btn04" width="100" height="30" bkcolor="#FFFF0000" borderround="2,2"/>
</HorizontalLayout>
</Window>

2.VerticalLayout容器则和HorizontalLayout相反,在VerticalLayout容器中的窗口元素都会按照顺序竖直排列,把上面布局内容进行修改:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<Window size="432,320">
<VerticalLayout name="MainLayout">
<Button text="Btn01" width="100" height="30" bkcolor="#FFFF0000" borderround="2,2"/>
<Button text="Btn02" width="100" height="30" bkcolor="#FFFF0000" borderround="2,2"/>
<Button text="Btn03" width="100" height="30" bkcolor="#FFFF0000" borderround="2,2"/>
<Button text="Btn04" width="100" height="30" bkcolor="#FFFF0000" borderround="2,2"/>
</VerticalLayout>
</Window>

3.容器中可以再嵌套容器,我们可以在一个容器中嵌套任何其他容器,例如一个VerticalLayout中可以嵌套多个HorizontalLayout或VerticalLayout等等。

有了这些特性我们就可以完成大部分软件界面的布局,下面我们来完成一个简单的案例,效果如下:

这个界面很简单,我们先来分析一下它的布局:

上图很直观的反应了整个界面的布局情况,我们只需要在3.HorizontalLayout中添加一个Text控件,在4.HorizontalLayout中添加两个按钮控件并指定按钮的背景图片即可。

xml布局内容如下:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<Window size="432,320" sizebox="4,4,6,6" caption="0,0,0,30">
<Font name="宋体" size="12" />
<Font name="宋体" size="26" />
<VerticalLayout name="MainLayout" bkimage="bg.png">
<HorizontalLayout height="30">
<HorizontalLayout>
<Text text="QQ旋风" padding="30,12,0,0" textcolor="#FFFF0000" height="30" align="center" font="0" ></Text>
</HorizontalLayout>
<HorizontalLayout width="80" >
<Button name="MinBtn" width="28" height="17" padding="0,2,0,0" normalimage="file='max_min.png' source='0,0,28,17' dest='0,0,28,17' " hotimage="file='max_min_h.png' source='0,0,28,17' dest='0,0,28,17" ></Button>
<Button name="CloseBtn" width="28" height="17" padding="0,2,0,0" normalimage="file='max_min.png' source='28,0,56,17' dest='0,0,28,17' " hotimage="file='max_min_h.png' source='28,0,56,17' dest='0,0,28,17'" ></Button>
</HorizontalLayout>
</HorizontalLayout>
<HorizontalLayout >
</HorizontalLayout>
</VerticalLayout>
</Window>

除此之外我们需要去掉系统原有的标题栏,对WM_NCPAINT、WM_NCCALCSIZE、WM_NCACTIVATE三个系统消息进行屏蔽即可,在消息处理switch case语句中,增加下面代码

case WM_NCPAINT:
case WM_NCCALCSIZE:
case WM_NCACTIVATE:
return 0;

加载界面代码和上节基本相同,完整内容如下:

#include <Windows.h>
#include "../DuiLib/StdAfx.h"
using namespace DuiLib; class CMyWnd : public CWindowWnd,public INotifyUI
{
public:
CMyWnd(){}
LPCTSTR GetWindowClassName() const
{
return L"MyWnd";
}
UINT GetClassStyle() const{
return UI_CLASSSTYLE_FRAME|CS_DBLCLKS;
}
void Notify(TNotifyUI& msg)
{
if(msg.sType == L"click")
{
if(msg.pSender->GetName() == L"CloseBtn")
{
::PostQuitMessage(0); }else if(msg.pSender->GetName() == L"MinBtn")
{
::SendMessage(m_hWnd,WM_SYSCOMMAND, SC_MINIMIZE, 0);
}
}
}
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CREATE:
{
m_PaintMgr.Init(m_hWnd);
//从xml中加载界面
CDialogBuilder builder;
m_pRoot = builder.Create(L"tutorial4.xml",(UINT)0,NULL,&m_PaintMgr);
m_PaintMgr.AttachDialog(m_pRoot);
m_PaintMgr.AddNotifier(this);
}
break;
case WM_NCPAINT:
case WM_NCCALCSIZE:
case WM_NCACTIVATE:
return 0;
break;
case WM_DESTROY:
::PostQuitMessage(0);
break;
case WM_KEYDOWN:
{
int nVirtKey = (int) wParam;
if(VK_ESCAPE == nVirtKey)
{
::PostQuitMessage(0);
}
}
break;
}
LRESULT lRes=0;
if(m_PaintMgr.MessageHandler(uMsg,wParam,lParam,lRes)) return lRes;
return CWindowWnd::HandleMessage(uMsg,wParam,lParam);
}
~CMyWnd(){
delete m_pRoot;
}
private:
CPaintManagerUI m_PaintMgr;
CControlUI* m_pRoot;
};
INT WinMain(HINSTANCE hInst,HINSTANCE hPreInst,LPSTR lpCmdLine,INT Show)
{
CPaintManagerUI::SetInstance(hInst);
CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetResourcePath());
//创建主窗口
CMyWnd* pFrame = new CMyWnd();
pFrame->Create(NULL,L"Tutorial4",UI_WNDSTYLE_FRAME,WS_EX_WINDOWEDGE);
pFrame->CenterWindow();
pFrame->ShowWindow(true);
CPaintManagerUI::MessageLoop(); return 0;
}

其他容器和控件的使用将在后面的博文中介绍。

博文源码:https://github.com/rongbo-j/duilib-tutorial

DirectUI界面编程(四)界面布局详解的更多相关文章

  1. Android学习之基础知识六—Android四种布局详解

    一.Android基本布局 布局是一种可以放置多个控件的容器,它可以按照一定规律调整内部控件的位置,而且布局内部除了可以放置控件外,还可以放置布局,实现多层布局嵌套.布局和控件.布局和布局之间的关系如 ...

  2. Android 布局学习之——Layout(布局)详解二(常见布局和布局参数)

    [Android布局学习系列]   1.Android 布局学习之——Layout(布局)详解一   2.Android 布局学习之——Layout(布局)详解二(常见布局和布局参数)   3.And ...

  3. Android布局详解之一:FrameLayout

      原创文章,如有转载,请注明出处:http://blog.csdn.net/yihui823/article/details/6702273 FrameLayout是最简单的布局了.所有放在布局里的 ...

  4. Scala进阶之路-面向对象编程之类的成员详解

    Scala进阶之路-面向对象编程之类的成员详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Scala中的object对象及apply方法 1>.scala 单例对象 ...

  5. 【转载】图说C++对象模型:对象内存布局详解

    原文: 图说C++对象模型:对象内存布局详解 正文 回到顶部 0.前言 文章较长,而且内容相对来说比较枯燥,希望对C++对象的内存布局.虚表指针.虚基类指针等有深入了解的朋友可以慢慢看.本文的结论都在 ...

  6. Grid 网格布局详解

    Grid网格布局详解: Grid布局与Flex布局有着一定的相似性,Grid布局是将容器划分成行和列,产生单元格,可以看做是二维布局. 基本概念: 采用网格布局的区域,称为"容器" ...

  7. ElasticSearch第四步-查询详解

    ElasticSearch系列学习 ElasticSearch第一步-环境配置 ElasticSearch第二步-CRUD之Sense ElasticSearch第三步-中文分词 ElasticSea ...

  8. Android开发重点难点1:RelativeLayout(相对布局)详解

    前言 啦啦啦~博主又推出了一个新的系列啦~ 之前的Android开发系列主要以完成实验的过程为主,经常会综合许多知识来写,所以难免会有知识点的交杂,给人一种混乱的感觉. 所以博主推出“重点难点”系列, ...

  9. 【翻译】Anatomy of a Program in Memory—剖析内存中的一个程序(进程的虚拟存储器映像布局详解)

    [翻译]Anatomy of a Program in Memory—剖析内存中的一个程序(进程的虚拟存储器映像布局详解) . . .

  10. 网络编程socket基本API详解(转)

    网络编程socket基本API详解   socket socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信. socket ...

随机推荐

  1. 给 iOS 开发者的 RxSwift(一)

    RxSwift 或许我们都听说过,但或许只知道 RxSwift 这个单词,长篇大论关于 RxSwift 的介绍往往使读者迷失在各种概念当中,却不知如何让它大展伸手.或许我们可以换一种姿势,一些应用场景 ...

  2. linux中errno使用(转)

    当linux中的C api函数发生异常时,一般会将errno变量(需include errno.h)赋一个整数值,不同的值表示不同的含义,可以通过查看该值推测出错的原因,在实际编程中用这一招解决了不少 ...

  3. 将JavaBean对象/List或Set或Map对象转成JSON方式

    一.通过Struts2插件包(即使用Struts框架)自动生成JSON文本 二.使用第三方工具,将JavaBean对象/List或Set或Map对象转成JSON  准备导入第三方jar包: >c ...

  4. Python爬虫2------爬虫屏蔽手段之代理服务器实战

      1.代理服务器: 一个处于客户端与互联网中间的服务器,如果使用代理服务器,当我们浏览信息的时候,先向代理服务器发出请求,然后由代理服务器向互联网获取信息,再返回给我们. 2.代码: import ...

  5. Python爬虫1-----urllib模块

    1.加载urllib模块的request from urllib import request 2.相关函数: (1)urlopen函数:读取网页 webpage=request.urlopen(ur ...

  6. 洛谷P1914 小书童——密码

    题目背景 某蒟蒻迷上了"小书童",有一天登陆时忘记密码了(他没绑定邮箱or手机),于是便把问题抛给了神犇你. 题目描述 蒟蒻虽然忘记密码,但他还记得密码是由一串字母组成.且密码是由 ...

  7. 最短路&查分约束

    [HDU] 1548 A strange lift 根蒂根基最短路(或bfs)★ 2544 最短路 根蒂根基最短路★ 3790 最短路径题目 根蒂根基最短路★ 2066 一小我的观光 根蒂根基最短路( ...

  8. oracle导入expdp、导出impdp数据库用户

    仅限oracle服务器上执行:把172.16.251.136:1521/orcl的AMI4_2用户导入到192.168.2.30:1521/orclss中的AMI1用户:  关于导入导出更详细的见文章 ...

  9. 纯js编写验证信息提示正则匹配数字,字母,空值

    1.显示效果 2,html结构 <div class="border_bg"> <div id="upcCode" style="p ...

  10. leetCode(32):Power of Two

    Given an integer, write a function to determine if it is a power of two. 2的幂的二进制表示中,必定仅仅有一个"1&q ...