DDuilib入门【一】

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zyjying520/article/details/50184759

一、前言


      在学习DDuilib之前最好先了解下原duilib,这样能快速掌握DDuilib, 其次需要抛开Delphi拖控件来设计界面的思想,因为duilib是一个基于逻辑与界面分离式的,所以不管是先写UI部分还是逻辑代码部分都可以,但按照我们一般的设计习惯,先将UI设计好再去编写相关代码。


二、xml UI构建入门


       跟据duilib界面设计的描述文件(.xml),我们首先建立一个标准的utf-8格式的xml文件,


<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<Window size="379,551" sizebox="4,4,4,4" caption="0,0,0,32" roundcorner="3,3">
	<VerticalLayout bkcolor="#FFF0F0F0" bkcolor2="#FFAAAAA0">
	</VerticalLayout>
</Window>
        根节点须为Window, 其中已经定义了4个属性:

        size:窗口的大小:

        sizebox:右下角可调 整窗口大小区域: 

        caption:标题栏的范围:

        roundcorner:窗口的圆矩角大小。

此外每一个标准的窗口都必须还有一个除Window的根root,这里我们选一个VerticalLayout作为整个窗口 的根root,铺满整个窗口,如果不定义控件的大小将默认会进行自动调整(博主自己理解,实践了下的),bkcolor与bkcolor2混合作为一个渐变色。接下来我们给窗口增加一个标题栏,此时xml文件为:

        

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<Window size="379,551" sizebox="4,4,4,4" caption="0,0,0,32" roundcorner="3,3">
	<VerticalLayout bkcolor="#FFF0F0F0" bkcolor2="#FFAAAAA0">
		<HorizontalLayout height="32" bkcolor="#FFE6E6DC" bkcolor2="#FFAAAAA0">
		</HorizontalLayout>
	</VerticalLayout>
</Window>

    

可看到此时增加了一个HorizontalLayout横向布局,并设置其高度为32(宽度自动),并设置了bkcolor和bkcolor2, 看下预览图了解下具体:

       

接下来我们继续完善这个窗口,为其添加几个系统按钮:此时xml文件变为如下:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<Window size="379,551" sizebox="4,4,4,4" caption="0,0,0,32" roundcorner="3,3">
	<VerticalLayout bkcolor="#FFF0F0F0" bkcolor2="#FFAAAAA0">
		<HorizontalLayout height="32" bkcolor="#FFE6E6DC" bkcolor2="#FFAAAAA0">
			<VerticalLayout height="32">
			</VerticalLayout>
			<VerticalLayout width="140" height="32">
				<Button name="minbtn" tooltip="最小化" float="true" pos="47,3,0,0" width="30" height="27" normalimage="file='sysbtn_min_normal.png'" hotimage="file='sysbtn_min_hover.png'" pushedimage="file='sysbtn_min_down.png'" />
				<Button name="maxbtn" tooltip="最大化" float="true" pos="77,3,0,0" width="30" height="27" normalimage="file='sysbtn_max_normal.png'" hotimage="file='sysbtn_max_hover.png'" pushedimage="file='sysbtn_max_down.png'" />
				<Button name="restorebtn" tooltip="恢复" visible="false" float="true" pos="77,3,0,0" width="30" height="27" normalimage="file='sysbtn_restore_normal.png'" hotimage="file='sysbtn_restore_hover.png'" pushedimage="file='sysbtn_restore_down.png'" />
				<Button name="closebtn" tooltip="关闭" float="true" pos="107,3,0,0" width="30" height="27" normalimage="file='sysbtn_close_normal.png'" hotimage="file='sysbtn_close_hover.png'" pushedimage="file='sysbtn_close_down.png'" />
			</VerticalLayout>
		</HorizontalLayout>
	</VerticalLayout>
</Window>


可以看到我们增加了两个VerticalLayout布局,为什么要添加2个呢?其实第一个是用来占位用的,可以看到我们并没有设置宽度,只设置了其高度,第二个布局设置了宽和高,固位了大小。第二个VerticalLayout中我们添加了4个button控件,有一个默认不可视, 每个button中有不少的属性,其含义为:

       name :唯一的一个名称,与delphi中控件name含是一样的,每一个布中只允许存在一个:

       tooltip:工具提示与delphi件的hint是一样的效果:

       float:当为true是使用绝对定位:

       pos:一个矩形大小Left, Top, Right, Bottom对应:

       width、height:与delphi控件的width、height等同: 

       normalimage:按钮在没有任何操作情况下显示的图片,这里定义为file='sysbtn_min_normal.png',

            其实也可以写为sysbtn_min_normal.png。博主也还在学习duilib中,所以有很多时候也不一定清楚。

       hotimage: 鼠标移动到按钮上显示的图片:

       pushedimage:鼠标按下时显示的图片:

其实属性远不止这些,还有很多就不一一举例了,具体可以看duilib源码中的的文档。根据上面的定义我们预览下,可以看到以下效果:

       

        此时看到运行的效果已经发现三个按钮位置被排在了右边。


三、代码编写


       接下来我们开始编写逻辑处理的代码,博主封装了一个C++的WindowImplBase类作为窗口的主要类,命名为TDuiWindowImplBase。

        

  TAppsWindow = class(TDuiWindowImplBase)
  protected
    procedure DoNotify(var Msg: TNotifyUI); override;
    procedure DoHandleMessage(var Msg: TMessage; var bHandled: BOOL); override;
    procedure DoInitWindow; override;
  public
    constructor Create;
    destructor Destroy; override;
  end;

       

看到上面我们继了这个类,一般情况下我们继续这个类就可以,如果需要消息响应还需要覆盖DoNotify方法,在其中接收来自duilib的消息。

       DoNotify: 接收消息用:

       DoHandleMessage:里面可以拦截windows的消息,可自行决定怎么处理该消息:

       DoInitWindow:整个UI已经在内存中构建完成后的一个回调,可以在这里面初始化一些信息:

     

constructor TAppsWindow.Create;
begin
  inherited Create('MainWindow.xml', 'skin\Apps');
  CreateWindow(0, 'Apps', UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);
end;


destructor TAppsWindow.Destroy;
begin
  inherited;
end;


function TAppsWindow.DoCreateControl(pstrStr: string): CControlUI;
begin
  Result := nil;
end;


procedure TAppsWindow.DoHandleMessage(var Msg: TMessage; var bHandled: BOOL);
begin
  inherited;
end;


procedure TAppsWindow.DoInitWindow;
begin
  inherited;
end;


procedure TAppsWindow.DoNotify(var Msg: TNotifyUI);
var
  LType, LCtlName: string;
begin
  inherited;
  LType := Msg.sType;
  LCtlName := Msg.pSender.Name;
  // 新版本中可不写 关闭,最小化,恢复,最大化的功能了
  // 只需在建立布局文件时将相应控件名默认为closebtn,restorebtn, minbtn,maxbtn即可
  if LType.Equals(DUI_MSGTYPE_CLICK) then
  begin
    if LCtlName.Equals(kclosebtn) then
      DuiApplication.Terminate
    else if LCtlName.Equals(krestorebtn) then
      Restore
    else if LCtlName.Equals(kmaxbtn) then
      Maximize
    else if LCtlName.Equals(kminbtn) then
      Minimize;
  end;
end;

       

在构造函数中我们继承了父类的Create方法,指定了资源文件和目录,默认是UILIB_FILE, 加载文件资源: 然后我们使用CreateWindow创建了一个窗口,指定了父窗口句柄为0,标题为"Apps",以及设置了样式为 UI_WNDSTYLE_FRAME,扩展样式为 WS_EX_WINDOWEDGE,这样一来我们整个UI部分已经构建完成,接下来就是为相应的控件添加响应事件。我们在重载的DoNotify中接收来自CPaintManagerUI传递过来的消息信息。在TNotifyUI中sType指定了当前的消息类型,我们这里只需要响应click所以他的消息即为 click,同时成员 中的pSender保存着当前的控件,与Delphi中常见的Sender是一样的道理,我们跟据xml文件中button定义的name来判断是哪一个控件调用此事件。最后我们在delphi工程文件的程序入口处添加以下代码来初始程序:

  

program Apps;

uses
  DuiWindowImplBase,
  uMain in 'uMain.pas';

{$R *.res}

begin
  DuiApplication.Initialize;
  AppsWindow := TAppsWindow.Create;
  AppsWindow.Show;
  DuiApplication.Run;
  AppsWindow.Free;
end.

       

至此我们一个简单的demo就做完了,看下是不是觉得很方便,而且界面也挺炫的。

      

展开阅读全文

没有更多推荐了,返回首页