//窗口程序 - 动态创建窗口控件 //入门教程: doc://library-guide/std/win/ui/create-winform.html import win.ui; /*DSG{{*/ var winform = win.form(text="动态创建控件演示";right=759;bottom=469) winform.add( button={cls="button";text="button";left=381;top=347;right=740;bottom=454;z=1} ) /*}}*/ /************ 在设计器生成的代码中使用 winform.add() 函数添加控件。 winform.add()的参数是一个表,键为控件名,值为创建控件的参数, 典型的例子: winform.add({ button={cls="button";text="button";left=129;top=155;right=229;bottom=262;z=1} button2={cls="button";text="button";left=229;top=155;right=329;bottom=262;z=1} button3={cls="button";text="button";left=329;top=155;right=488;bottom=262;z=1} }) 上面的代码创建 winform.button, winform.button2, winform.button3, 这三个控件。 如果之前存在同名的控件,则会被替换掉,原来的控件会被关闭。 但是winform.add()也可以不指定控件名,而直接使用普通数组添加控件,例如: winform.add({ {cls="button";text="button";left=129;top=155;right=229;bottom=262;z=1} {cls="button";text="button";left=229;top=155;right=329;bottom=262;z=1} {cls="button";text="button";left=329;top=155;right=488;bottom=262;z=1} }) 当然,也可以写成数值索引的格式: winform.add({ [1]= {cls="button";text="button";left=129;top=155;right=229;bottom=262;z=1} [2]= {cls="button";text="button";left=229;top=155;right=329;bottom=262;z=1} [3]= {cls="button";text="button";left=329;top=155;right=488;bottom=262;z=1} }) 不指定控件名字是创建匿名的控件( 在窗口设计器中不能这样写 )。 winform对象里并不会创建 winform[1] winform[2] winform[3] 这样的引用。 但是winform仍然会记录这些匿名控件的句柄,并对其进行管理。 winform.add()的返回值也是一个表,这个表包含创建成功的控件, 以控件名字为键,控件对象为值,如果是匿名控件,则键为创建控件时指定的数值索引键,值仍然是控件对象。 例如我们创建一个匿名控件,并获取返回的对象是这样写: var ctrls = winform.add({ {cls="button";text="button";left=129;top=155;right=229;bottom=262;z=1} }) var btn = ctrls[1]; 注意下面这样写是错误的 var ctrls = winform.add( {cls="button";text="button";left=129;top=155;right=229;bottom=262;z=1} ) 即使只创建一个控件,参数也应当是一个数组 */ /* 所有窗口对象都有 addCtrl()函数( 包含窗体和控件 )。 这个函数实际上是调用 winfrom.add(),他们的作用和用法是完全相同的。 但是,当你使用一个控件的 addCtrl() 函数添加控件时,这时候控件会被设置为实际的父窗口, 例如指定固定边距,margin前缀的边距参数都是以实际的父窗口为参考坐标。 创建控件的大多数参数都是用于设计器,并且是被精简过的非常短,一般我们不需要去了解这种字段。 这里大致的说一下关键的几个控件创建参数: cls 指定控件的设计时类名,每个cls都对应 win.ui.ctrl命名空间下的控件库名字 className 这是控件的运行时类名,className 是Windows窗口类名,通常跟cls中指定的名字是不一样的. left 左坐标 设计时坐标,窗体会记录此字段到 _defClientRect 属性,控件会记录到 _defRect 属性。 top 上坐标 设计时坐标,窗体会记录此字段到 _defClientRect 属性,控件会记录到 _defRect 属性。 right 右坐标 设计时坐标,窗体会记录此字段到 _defClientRect 属性,控件会记录到 _defRect 属性。 bottom 下坐标 设计时坐标,窗体会记录此字段到 _defClientRect 属性,控件会记录到 _defRect 属性。 aardio会记录设计时坐标,作为运行时自动缩放控件的依据。 dl 左侧是否固定与父窗口的左边距,如果是一个小数,计算父窗口宽度的百分比得出当前边距 dt 上侧是否固定与父窗口的上边距,如果是一个小数,计算父窗口高度的百分比得出当前边距 dr 右侧是否固定与父窗口的右边距,如果是一个小数,计算父窗口宽度的百分比得出当前边距 db 底侧是否固定与父窗口的底边距,如果是一个小数,计算父窗口高度的百分比得出当前边距 注意在未指定固定边距属性时,控件默认跟随窗体缩放自动调整位置(边距不会保持不变)。 -------------------------------------------------------------------------- 以上属性由aardio窗体设计器生成的代码中使用,以下属性在窗体设计器之外使用。 -------------------------------------------------------------------------- anchors 属性获取或设置固定边距,值为表对象, 可选包含 left,top,right,bottom 字段,参数必须是数值,可用值与控件初始化属性 dl,dt,dr,db 相同。 例如 winfom.edit.anchors = {left=1;top=1;right=1;bottom=1} 等价于在控件初始化属性中将 dl,dt,dr,db 都设为 1。 width 控件的设计时宽度,会被转换为 _defClientRect 或 _defRect 然后清除 height 控件的设计时高度,会被转换为 _defClientRect 或 _defRect 然后清除 marginLeft 控件的设计时固定左边距,值为像素单位的数值,设为小数表示计算父窗口宽度的百分比得出当前边距 marginRight 控件的设计时固定右边距,值为像素单位的数值,设为小数表示计算计算父窗口宽度的百分比得出当前边距 marginTop 控件的设计时固定顶边距,值为像素单位的数值,设为小数表示计算父窗口高度的百分比得出当前边距 marginBottom 控件的设计时固定底边距,值为像素单位的数值,设为小数表示计算父窗口高度的百分比得出当前边距 所有关于控件位置的参数都是可选的, 如果未明确指定控件某个边的位置,则固定该边距为 0, 也就是说如果不指定任何位置参数,则控件铺满父窗口的客户区。 aardio 的窗体设计器(/*DSG{{*/ /*}}*/ 标签包围的代码)无法识别 width,height,marginLeft,marginRight,marginTop,marginBottom 这些属性。 ************/ var ctrls = winform.button.addCtrl({ {cls="button";text="r";font=LOGFONT(name='Marlett';charset=2/*_SYMBOL_CHARSET*/);width=25;height=25;marginTop=0.5/*垂直居中*/;marginRight=25 } }) /* 普通控件WM_COMMAND消息是发给父窗口, 而只有win.form才能处理此消息并自动触发控件自身的oncommand函数, 如果父窗口不是winform,就需要用下面的函数转发WM_COMMAND消息给父窗体处理,这样控件的 oncommand事件才能触发。 对于plus控件这样不依赖WM_COMMAND, 而是使用 win.ui.tracker完全自己处理事件的控件,不需要调用这句代码。 */ winform.button.translateCommand(); //匿名控件也可以响应事件 ctrls[1].oncommand = function(id,event){ owner.parent.close(); } /* import win.ui.tracker; var event = win.ui.tracker(ctrls[1]); event.onMouseClick = function(wParam,lParam){ owner.parent.close(); } */ winform.add( edit={cls="edit";text="edit";height=199;marginLeft=0;marginRight=0.5;top=0;edge=1;multiline=1;z=2}; edit2={cls="edit";text="edit2";height=199;marginLeft=0.5;marginRight=0;marginTop=0;edge=1;multiline=1;z=3} ) winform.show() win.loopMessage();