aardio 文档

aardio 范例:跨线程操作窗口控件

//跨线程操作窗口控件
import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=560;bottom=413;parent=...)
winform.add(
edit={cls="edit";left=25;top=30;right=535;bottom=139;dl=1;dr=1;dt=1;edge=1;multiline=1;z=1};
treeview={cls="treeview";left=25;top=165;right=535;bottom=390;asel=false;bgcolor=16777215;db=1;dl=1;dr=1;dt=1;edge=1;z=2}
)
/*}}*/

var hItem = winform.treeview.insertItem( { 
    text = "children数组指定子节点"; 
    children = { 
        { text = "子节点"  };
        { text = "子节点2" };
    }
} ) 

thread.invoke( 
    function(winform,hItem){
        winform.show();
        winform.text = 'aabc测试123'
        winform.edit.text = '------------------------------------\n'

        /*
        上面这么帅的功能其实是用 
        thread.callWnd ,thread.setWnd, thread.getWnd实现的,
        也可以直接调用这几个函数,例如:
        */
        thread.setWnd(winform.hwnd,"text","原来也就是个语法糖呀")

        /*
        切记控件传入多线程时,在线程中的对象只是一个影子代理,
        所有对控件成员函数的调用都会转发到界面线程内执行。

        如果跨线程调用控件的成员函数时,返回值是一个函数对象,
        那么该函数会复制到当前线程,函数必须遵守线程函数的规则,能独立执行不依赖其他线程的局部变量闭包。
        一个典型的例子就是函数名字为each前缀的一系列创建迭代器的函数,
        这些函数违反了aardio跨线程交互的规则(函数依赖的上层局部变量在界面线程,却试图在工作线程中调用他)。

        aardio目前自动提供一个解决方案,
        当跨线程调用控件的成员函数,并且函数名为each前缀时,aardio负责把each函数复制到当前线程。
        这样调用each函数创建的闭包存在于当前线程,则工作正常。在编写控件的each函数时应遵守线程函数的规则(不使用外部的局部变量闭包)

        这个解决方案类似于在线程中执行这样的操作:
        winform.listview[["each"]] = winform.listview.each
        使用直接下标[[]]跳过了元表中的运算符重载(避免函数被再次传回界面线程).

        这些操作由aardio自动完成,了解以上原理有助于更好的运用该特性
        */

        for hSubItem in winform.treeview.each(hItem) {
            winform.edit.print(winform.treeview.getItemText(hSubItem));
        }
    }, winform,hItem
)

win.loopMessage();
return winform;

Markdown 格式