aardio 中最强大的控件是 plus 控件,但最重要的控件是 custom 控件。不会用 plus 控件可能只是界面没那么好看,而不会用 custom 控件,你在 aardio 中将寸步难行。
aardio 开发环境「界面控件」工具箱里最后一个控件就是自定义控件( custom 控件)。
步骤如下:
在 aardio 工程里找到其他新建的窗体代码文件。
右键点击该文件,复制文件路径,例如 /.res/frmChild1.aardio
拖一个 custom 控件到风窗口上,
点击该控件,在控件属性窗口修改控件类名为 /.res/frmChild1.aardio
示例:
import win.ui;
/*DSG{{*/
var winform = win.form(text="加载子窗口文件";)
winform.add(
custom={cls="~\example\Windows\Custom\.res\frmChild1.aardio";left=19;top=15;right=740;bottom=455;db=1;dl=1;dr=1;dt=1;z=1}
)
/*}}*/
winform.show();
win.loopMessage();
我们可以使用 winform.custom.loadForm( path ) 加载窗口。aardio 会自动将窗口加载为 winform.custom 的子窗口。
每次调用 winform.custom.loadForm( path )都会加载窗体代码并返回新的子窗体对象。 winform.custom 会成为容器管理所有加载的子窗口数组。
规则如下:
示例代码:
import win.ui;
/*DSG{{*/
var winform = win.form(text="用 custom 控件加载一个或多个子窗体")
winform.add(
button1={cls="button";text="切换窗口 frmChild1";left=366;top=418;right=525;bottom=459;db=1;dr=1;z=2};
button2={cls="button";text="切换窗口 frmChild2";left=534;top=418;right=693;bottom=459;db=1;dr=1;z=3};
custom={cls="custom";text="自定义控件";left=21;top=14;right=741;bottom=380;db=1;dl=1;dr=1;dt=1;z=1}
)
/*}}*/
var frmChild1 = winform.custom.loadForm("~/example/Windows/Custom/.res/frmChild1.aardio")
winform.button1.oncommand = function(id,event){
frmChild1.show();
}
var frmChild2 = winform.custom.loadForm("~/example/Windows/Custom/.res/frmChild2.aardio")
winform.button2.oncommand = function(id,event){
frmChild2.show();
}
winform.show();
win.loopMessage();
custom 控件与其他控件的主要区别是:控件的类名可以修改为任意 win.ui.ctrl 名字空间下的类名。
所有控件类都位于 win.ui.ctrl 名字空间,例如 plus 控件的类名为 "plus",那么 win.ui 就会将 "plus" 自动转换为完整类名 "win.ui.ctrl.plus" , 然后调用 "win.ui.ctrl.plus" 创建控件。
如果是基础控件只要在 开发环境「界面控件」工具箱直接拖到界面上就可以了,这些基础控件不需要写 import 语句,aardio 在开发时会导放所有基础控件,在发布时会按需发布程序实际使用的基础控件。
但是自定义控件首先要用 import 语句导入,不然 win.ui 在 win.ui.ctrl 名字空间找不到对应的控件类就无法创建控件。
实现自定义控件类有三种方式。
由系统创建窗口,如果系统存在相同类名的控件就可以直接创建。否则可以在控件的构造函数中修改类名,下面我们看一下 win.ui.ctrl.hotkey 的部分有关代码:
namespace win.ui.ctrl;
class hotkey{
ctor(parent,tParam){
if(tParam){
//修改创建控件的实际类名
tParam.cls = "msctls_hotkey32";
};
}
@_metaProperty;
}
上面的代码指示使用系统类名 "msctls_hotkey32" 创建控件。控件创建成功以后,控件的 cls 属性会被还原为设计时类名 "hotkey",而运行时类名 "msctls_hotkey32" 将会被保存到控件的 className 属性中。
最后 aardio 会将控件的 hwnd 属性设置为窗口句柄。这是最重要的一步,所有对窗口的操作在控件内部都要通过句柄操作。
由控件类自己创建窗口,这时候 aardio 就不管控件到底是怎么创建窗口了,唯一的要求就是在控件构造函数运行以后,控件的 hwnd 属性必须指向创建成功的子窗口的句柄。
所以 win.ui 对控件的要求就是:要么你给一个有效的运行时类名我来负责创建控件窗口,要么你自己创建窗口把句柄值告诉我。
由控件自己创建窗口的控件,最典型的代表控件就是 custom 控件。
如果我们修改了 custom 控件的类名,那么实际创建的控件实际跟 custom 控件无关。但如果我们没有修改 custom 控件的类名,那么就会创建执行 win.ui.ctrl.custom 构造函数创建一个真正的 custom 控件。
我们看一下 custom 控件的主要代码(只看与本文有关的部分):
namespace win.ui.ctrl;
class custom {
ctor(parent,tParam){
this = ..win._form(border="none";exmode="none";mode="child";parent=parent;
left=tParam.left;top=tParam.top;right=tParam.right;bottom=tParam.bottom;tParam=tParam);
}
}
原来 custom 控件自己啥都没干,默认只是调用 win.form 创建了一个子窗口,并且把自己直接赋值为这个创建的子窗口。当然这个子窗口符合条件,winform 的 hwnd 属性那肯定是有效的窗口句柄。
其实产这个最简单原始的空白 custom 控件也不是真的那么简单。custom 控件扩展了一些功能。例如在高级选项卡里,我们可以使用这样的 custom 控件作为多标签页的子窗体容器,用来管理并切换选项卡的内容区域。
请参考:aardio 范例:自定义控件类
无句柄的贴图控件
如果在自定义控件类里指定控件的 onlyDirectDrawBackground 属性为 true,那么控件就不需要创建窗口,hwnd 属性也不会有一个窗口句柄值。
典型的无句柄贴图控件就是 bk, bkplus 控件。
请参考: 窗口背景贴图
下面是一个空白的自定义控件类:
namespace win.ui.ctrl;
class myCtrl{
ctor( parent,tParam ){
};
}
说明:
有了上面的知识,下面我们一起创建一个自定义控件。
/lib/win/ui/ctrl/myCtrl.aardio
。然后我们在 myCtrl.aardio 中添加以下代码实现控件类:
namespace win.ui.ctrl;
class myCtrl{
ctor( parent,tParam ){
this = ..win._form(border="none";exmode="none";mode="child";parent=parent;right=750;bottom=387;tParam=tParam)
this.add(
plus={cls="plus";left=-5;top=2;right=751;bottom=393;db=1;dl=1;dr=1;dt=1;repeat="scale";z=1}
)
};
}
上面的子窗体创建参数里:
parent=parent;
指定了父窗口。mode="child";
指定了创建的是一个子窗口。然后我们如下调用自定义控件:
//用于支持在图像属性中直接指定网络图像
import inet.http;
//导入界面库
import win.ui;
/*DSG{{*/
var winform = win.form(text="自定义控件类";right=757;bottom=467)
winform.add(
myCtrl2={cls="myCtrl";text="自定义控件";left=3;top=-1;right=467;bottom=316;db=1;dl=1;dr=1;dt=1;z=1};
plus={cls="plus";left=168;top=280;right=465;bottom=353;notify=1;z=2}
)
/*}}*/
//显示窗口
winform.show();
//这时候 winform.myCtrl2 就是 win.ui.ctrl.myCtrl 的实例对象.
winform.myCtrl2.plus.background = "http://download.aardio.com/v10.files/demo/images/custom.gif";
win.loopMessage();
在 aardio 中我们还可以对任何一个窗口、或窗口上的子窗件进行扩展,这种用法在 aardio 中被大量使用,例如让窗口嵌入浏览器控件,以增加显示网页的功能。
这样的库非常多,例如 web.form,web.view,web.sysView,web.layout,web.sciter,chrome.app ……
示例:
//扩展控件
import win.ui;
/*DSG{{*/
var winform = win.form(text="加载扩展控件";right=759;bottom=469)
winform.add(
button={cls="button";text="全屏";left=523;top=415;right=630;bottom=460;db=1;dr=1;z=2};
custom={cls="custom";text="自定义控件";left=17;top=26;right=732;bottom=380;db=1;dl=1;dr=1;dt=1;z=1}
)
/*}}*/
import web.form;
var wb = web.form( winform.custom )
//导出允许网页调用的 aardio 函数
wb.external={
close = function(){ winform.close()}
}
wb.html = /**
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<style type="text/css">
html,body{ margin:50; }
</style>
</head>
<body>这是一个网页 <button id="fullscreen" onclick="external.close()">关闭</button>
**/
//全屏
winform.button.oncommand = function(id,event){
winform.custom.fullscreen()
}
winform.show();
win.loopMessage();