Pc软件开发,aardio学习笔记

aardio 是一种易用性极强的动态语言,aardio官网:https://aardio.com/

基础语法

1.命名空间

  • 使用 namespace 关键字定义名字空间。如果一个不存在的变量首次被赋值(var语句声明的局部变量除外),则会自动加入到当前名字空间。
  • 名字空间也可以省略语句块标记,表示名字空间作用域直至该代码文件结束。
  • 名字空间其实也是一个普通的table对象。访问非当前名字空间的成员变量,可以加上有效的名字空间前缀.访问顶层名字空间要使用..操作符
  • global为默认的全局名字空间,当aardio代码文件加载时,默认都运行在global名字空间。self表示当前名字空间。
  • import语句可以将外部名字空间导入当前名字空间
提示
局部变量申明用var语句定义,若不使用var,则此变量申明为当前名字空间成员变量。

2.import语句

  • import语句将一个外部名字空间导入到当前名字空间,import 语句首先会在当前名字空间下查找同名对象是否存在,查找时不会触发名字空间的元方法

aardio的库有三种:

  • 内核库(Kernel Libraries),内核库由aardio提供,例如string库,raw库等。
  • 标准库(Standard Libraries),标准库由 aardio开发环境 提供。位于aardio根目录下的lib目录下,库路径与名字空间路径完全一致。
  • 用户库(User Libraries),用户库是用户在aardio应用程序根目录下的lib目录下建立的库。库路径与名字空间路径完全一致。
    如果是程序入口是打开工程内的代码文件,根目录为工程目录,否则为启动aardio文件所在目录。

相关文档:https://bbs.aardio.com/doc/reference/libraries/import.html

3.类

类可以动态创建数据结构相同的table对象。每一个类拥有独立的名字空间,名字空间中的变量也就是类的公用静态成员。在类内部,可以使用this对象引用动态创建的对象。

//定义类
class cls{
   
    //构造函数
    ctor(name,...){
        this.name = name;
        this.args = {...}
    };
   
    //属性
    value = staticNum;
   
    //成员函数
    add = function(v){
        this.value = this.value + v;
        return this.value;
    }
}


//打开类的名字空间
namespace cls{
    staticVar = "类的静态变量值";
    staticNum = 2;
}
 
//调用类创建对象
var obj = cls();

//调用对象函数
var v = obj.add(5);
提示
当一个table对象调用成员函数时,默认会传递一个owner对象给函数。
而在类创建的对象成员函数里,owner对象与this对象是指向同一个对象。

this对象与owner对象的区别在于。
this是类内部指向当前创建对象的指针,this指针不会因为函数的table前缀改变而改变。而owner对象是会根据函数调用时函数名前缀的table对象而相应改变。

4.元表

  • 使用元表可以自定义对象的默认行为、操作符。
  • 一个table对象可以用另一个table对象(元表)来定义一些元方法(metamethods)。用来定义元方法的表称为元表(metatable)。元表(metatable)允许我们改变表(table)的行为。例如对两个表(table)进行相加时,它会检查两个表是否有一个表有元表(metatable),并且检查元表(metatable)是否有_add函数。如果找到则调用这个_add函数去计算结果。
tab = {	
	@{ //使用@操作符设置元表
		_get = function(k) begin
			io.print(k)
			return owner[[k]] //不调用元方法
		end;
	
		_float = true; //允许移除元表
	
	}
}

tab@ = {}; //也可以这样设置元表
tab@ = {}; //这句会出错,因为元表没有指定_float属性时不能被移除

f = tab@._get; //读取元表

相关文档:https://bbs.aardio.com/doc/reference/libraries/kernel/table/meta.html 

[[]] 是一个raw操作符,它与[]不同的是,它不会调用元方法,也就是不能重载。

5.消息循环

Windows是以消息驱动的操作系统,Windows 消息提供了应用程序与应用程序以及应用程序与Windows系统之间进行通讯的手段。 Windows 中有一个系统消息队列,对于每一个正在执行的Windows应用程序,系统为其建立一个“消息队列”,即应用程序消息队列,用来存放该程序可能创建的各种窗口的消息。

在aardio窗口程序中,调用win.loopMessage启动窗口消息循环,用来从程序的消息队列中检索窗口消息并把它们分发到相应的窗口函数中。“消息循环”,实际也就是是程序循环,win.loopMessage退出,则窗口程序终止。

当我们用鼠标、按键等在窗口上操作时,windows就会将相应的操作转换为消息并加入到消息队列中。而win.loopMessage就检索这些消息并将之分发给窗口函数(消息回调函数wndproc、以及事件函数oncommand)

在一个GUI线程(窗口线程)中只能启动一次win.loopMessage循环,重复调用win.loopMessage不会启动多个循环。默认win.loopMessage是不需要参数的。

当我们指定observer参数为一个函数时,则win.loopMessage将该函数注册成为消息观察者。每次从消息队列中取出消息时,win.loopMessage首先会通知所有的observer(消息观察者)。如果调用 win.loopMessage( observer,false ) ,则将消息观察者observer从观察队列中注销。

6.操作符

aardio操作符优先级与C系语言基本兼容,也有很多自己的操作符

  • ++, 字符串连接符
  • [[]],直接下标操作符,获取或设置对象成员,不会调用元方法。
  • #,取字符串长度、或table数组元素个数。
  • @,@操作符表示元表,table的元表可以是table自已。例: tab@ = tab;
  • $,包含操作符可以将外部文件链接到当前代码中。
  • ..,两个点表示调用顶层命名空间下的成员。
  • ...,使用三个连续的圆点表示任意个数、任意类型的参数 arg = { ... }
  • _,如果在一个成员变量的前面加上下划线,则声明该变量的值为只读,在赋值后不可修改
  • “”,"/",在 aardio 中文件路径如果以单个斜杆或反斜杆开始表示『应用程序根目录』。
  • “~”,"~/",如果文件以 "~" 右单个斜杠或反斜杠开始表示启动EXE 所在目录。

7.全局成员

  • _ARGV ,解析后的进程启动参数表
  • _CMDLINE命令行参数的原始文本
  • call(),调用函数,可自定义owner对象
  • error,抛出一个异常。
  • publish("__/*发布消息名*/"),在当前线程内发布消息
  • subscribe,订阅消息设置回调
  • tostring,对象转字符串

8.多线程开发

相关文档:https://bbs.aardio.com/forum.php?mod=viewthread&tid=13625

9.窗体消息

消息列表:https://bbs.aardio.com/forum.php?mod=viewthread&tid=7776&extra=page%3D1

// 定义窗口的wndproc事件回调
winform.wndproc = function(hwnd, message, wParam, lParam) {
    if(message == 5 /* _WM_SIZE */) {
        // 窗口大小发生变化
        var width = win.ui.loWord(lParam) // 获取新的宽度
        var height = win.ui.hiWord(lParam) // 获取新的高度
        console.log("窗口大小变化:宽度 = ", width, " 高度 = ", height)
        // 在这里可以添加处理窗口大小变化的代码
    }
}

语法

1.基础语法

循环语句:https://bbs.aardio.com/doc/reference/the%20language/statements/looping.html

//遍历元组
for(k,v in tab){  

}

//计数器i从1循环到10,每次递增2
for( i=1;10;2 ){ 
   
}

//while
while (true) { 

}

标准库

1.win

win 库主要提供 Windows 系统函数、本进程窗口操作函数。相关文档:https://bbs.aardio.com/doc/reference/libraries/std/win.html

  • win.form,窗口类,实例化生产一个窗口。
  • win.loopMessage,启动窗口消息循环。
  • win.msgbox,弹出消息提醒框。
  • win.msgboxTest,弹出一个询问框
  • win.find,查找指定的窗口句柄
  • win.closed,返回当前窗口是否关闭

win.form相关方法:

  • winform.setTimeout,延时执行定时器
  • winform.setInterval,指定一个函数,并定时执行
  • winform.show,显示窗口
  • winform.clearInterval、clearTimeout
  • win.delay(),在界面线程中延时并同时处理窗口消息
  • winform.wndproc,监听窗口消息,设置消息处理的回调函数
  • win.setTopmost(winform.hwnd, true),窗口置顶
窗口消息
是指Windows发出的一个通知,告诉应用程序某个事情发生了。例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。消息本身是作为一个记录传递给应用程序的,这个记录中包含了消息的类型以及其他信息。例如,对于单击鼠标所产生的消息来说,这个记录中包含了单击鼠标时的坐标。

2.process

process库提供进程管理函数 ,process是一个类,用于创建进程对象。相关文档:https://bbs.aardio.com/doc/reference/libraries/std/process/process.html

  • process( "exe执行2文件路径",启动参数, startInfo),创建进程对象
  • proc.free(),关闭用来控制当前进程的内核对象,并非关闭目标进程(停止运行)
  • prcs.write(cmd),写入数据
  • proc.terminate(),强制杀除当前进程,使之停止运行.
  • process.execute(),执行指定的exe程序
  • process.kill(),终止指定的进程

3.com

com(Component Object Model组件对象模型)是开发软件组件的一种方法。com组件实际上是一些小的二进制可执行程序,它们可以给应用程序,操作系统以及其他组件提供服务。

  • com.CreateObject,创建Com对象
  • com.GetObject,返回已运行的Com对象
  • com.ShowHelp,查找Com对象的帮助文档
  • com.DumpTypeInfo,输出Com对象的类型信息、成员属性、成员方法列表

4.io

系统内输入、输出相关的功能

  • io.open(),显示控制台窗口,默认打开控制台窗口以后,标准输入输出的目标是控制台窗口。。
  • io.close(),关闭控制台窗口。
  • io.getText(),读取控制台的用户输入。

文件路径和文件操作:

  • io.fullpath(),把相对路径转换为绝对路径,并且支持用""或"/"作为首字符表示aardio程序根目录.
  • io.exist(),判断指定路径文件是否存在,判断目录权限
  • io.splitpath(),获取指定路径的信息,返回一个Table(文件名、目录、扩展名)
  • io.createDir("/__"),创建目录
  • io.remove("__"),删除参数@1指定路径的文件,此函数仅用于删除文件,删除目录请改用 fsys.delete、fsys.deleteEx 或 fsys.remove 函数。
  • io.rename("__",""),重命名指定文件
  • io.open 打开文件,成功返回文件对象
  • io.popen,运行控制台程序,并且得到返回的内容
  • io._exedir,主程序所在目录,返回完整长路径,目录路径以反斜杠结尾
  • io._exefile,主程序文件名
  • io._exepath,主程序文件路径,返回完整长路径

5.debug

debug 属于内核库,但必须使用 import debug 导入才能使用

  • debug.callcount(),函数调用栈深度
  • debug.debug(),插入断点,执行到该位置时打开控制台进入调试环境,发布后程序忽略此函数不执行

6.preg

preg是Perl兼容正则表达式支持库

  • preg("w+","uis"),创建正则表达式对象
  • preg.exec,类js
  • preg.find,返回匹配字符串起始位置,结束位置,
  • preg.grep,类php
  • preg.match,类php

7.thread

多线程相关文档:https://bbs.aardio.com/forum.php?mod=viewthread&tid=13625

  • thread.create,创建线程,返回句柄、线程ID,线程函数有独立的全局变量环境,线程引用的库应当在线程函数内 import
  • thread.delay,延时指定时间执行线程,导入 win 库的界面线程内会执行 win.delay,否则执行 sleep 函数。
  • thread.invoke,创建线程,但是不创建句柄,调用完毕自动释放
  • thread.lock("临界区名称"),获取一个锁,没有拿到时,会一直阻塞等待
  • thread.unlock("临界区名称"),释放锁
  • thread.table,线程共享表
  • thread.set("标志键" )、thread.get("标志键"),进程的共享内存
  • thread.wait()、waitAll(),等待指定线程句柄的线程运行结束
  • thread.waitClose(),等待指定线程句柄的线程运行结束,并释放句柄

8.thread.command

线程创建虽然传递的是闭包,但是不能引用外部的变量,线程有着自己单独的作用域,可以将外部函数挂载到thread.command内,所以线程都可以进行调用。

  • thread.command(),创建线程命令订阅对象
  • thread.command.命令函数名(),如果命令函数名首字符为$以post模式异步调用命令,否则以send模式同步调用该命令

9.console

console库用打开控制台,以及和控制台交互的一些操作。

  • console.getText,输出文字并获取用户输入
  • console.log,输入指定的字符串
  • console.pause,暂停
  • console.dumpTable,输出table
  • console.dumpJson,输出Json

10.web.json

  • web.json.parse,解析json为table
  • web.json.stringify,table转json

11.sys

  • sys.getComputerName(),返回计算机名
  • sys.getStartTime(),返回系统启动时间
  • sys.getUserName(),返回当前登录用户名
  • sys.hibernate(),休眠
  • sys.lock(),锁定计算机
  • sys.logoff(),注销
  • sys.restart(),重启
  • sys.setComputerName("计算机名"),修改计算机名,重启后生效
  • sys.shutdown(),关机
  • sys.sleep(),睡眠

12.environment

  • environment.each(),获取当前应用环境变量的迭代器
  • environment.system(),获取系统环境变量操作对象
  • environment.user() ,获取用户环境变量操作对象

13.string

相关文档:https://bbs.aardio.com/doc/reference/libraries/kernel/string/file.html

  • getenv(),读取当前进程环境变量
  • setenv(),设置当前进程环境变量
  • slice(),字符串截取
  • split(),字符串分割
  • string.load,加载文件内容
  • string.save,写入指定内容到文件

12.fsys

文件系统、注册表、Hosts、文件与目录操作相关的模块。

  • fsys.copy,复制文件或目录
  • fsys.createDir,创建目录并返回创建成功的完整文件路径
  • fsys.delete,删除文件或目录,成功返回 true
  • fsys.getCurDir(),获取当前目录。
  • fsys.enum 遍历指定目录下的文件和目录

13.time

  • time(),获取当前时间。返回时间对象。
  • time.stamp(),取 Unix 时间戳。

14.fsys.dlg

系统文件对话框。

  • fsys.dlg.open,打开选择单文件对话框
  • fsys.dlg.openEx,打开选择多文件对话框
  • fsys.dlg.save,显示保存文件对话框框
  • fsys.dlg.saveOp,显示保存文件对话框框,覆盖已存在的文件时显示确认对话框(overwrite prompt)
  • fsys.dlg.openDir,打开选择目录对话框,支持xp
  • fsys.dlg.dir,打开选择目录对话框

15.win.dlg.message

封装了一些简单的消息提示框。

  • win.dlg.message(),创建一个消息提示框操作对象
  • winMsg.ask,显示询问框
  • winMsg.doModal,显示模态框

16.table

相关文档:https://bbs.aardio.com/doc/reference/libraries/kernel/table/table.html

  • table.append(arr, value):向数组 arr 的末尾添加一个元素 value。
  • table.clear(arr):清空数组 arr 中的所有元素。
  • table.concat(arr1, arr2, …):连接多个数组,返回一个新的数组。
  • table.copy(arr):复制数组 arr。
  • table.count(arr):返回数组 arr 中的元素数量。
  • table.each(arr, function):遍历数组 arr,对每个元素执行给定的函数。
  • table.filter(arr, function):过滤数组 arr,返回一个新的数组,包含满足给定函数条件的元素。
  • table.find(arr, value):在数组 arr 中查找元素 value,返回其索引。
  • table.insert(arr, index, value):在数组 arr 的指定索引 index 处插入元素 value。
  • table.map(arr, function):对数组 arr 中的每个元素应用给定的函数,并返回一个新的数组。
  • table.pop(arr):移除并返回数组 arr 的最后一个元素。
  • table.push(arr, value):向数组 arr 的末尾添加一个元素 value,并返回新的长度。
  • table.remove(arr, index):移除数组 arr 中指定索引 index 处的元素。
  • table.reverse(arr):颠倒数组 arr 的元素顺序。
  • table.sort(arr):对数组 arr 进行排序。
  • table.some(arr, function):检查数组 arr 中是否有元素满足给定的函数条件。
  • table.unpack(arr, start, count):从数组 arr 中解包元素,返回一个新的数组。

fsys.log

fsys.log用于快捷记录日志

  • fsys.log("日志文件路径")
  • ....

窗口控件

1.treeview

  • treeview.getSelection(),获取所有被选项

2.edit

  • editObject.appendText ,追加文本并移动光标到文本尾部
  • editObject.clear,清空所有内容
  • editObject.print,将多个参数转换为字符串,并使用制表符分隔各参数追加到文本尾部,并追加换行
  • editObject.text,编辑控件文本属性
  • editObject.vScroll(),滚动到底部

问题记录

1.CDP协议

/* 设置这俩,才能进行别的页面操作 */
wb.cdpWait("Network.enable"); //启用网络跟踪,网络事件现在将传递到客户端。
wb.cdpWait("Page.enable"); //允许操作
wb.cdpWait("Page.setBypassCSP", { enabled = true}); //禁用CSP
wb.cdpWait("Page.addScriptToEvaluateOnNewDocument", {source = extra}); //每次页面加载时注入JS 

/* 监听加载完成的事件 */
wb.cdpSubscribe('Page.loadEventFired',function(res){
	winform.msgbox("加载完毕!");
});

2.字符串编码转换

// 怪异字符编码转换
import com.interface.IMultiLanguage2;
var mlang = com.interface.IMultiLanguage2.Create()
var str = mlang.fromto(all,936); 

//正常字符串编码转换
string.fromto("转换编码",65001,0)

3.常用目录

string.getenv("USERPROFILE"); //用户目录
io._exedir; //主程序所在目录

4.excel

excel操作:https://bbs.aardio.com/forum.php?mod=viewthread&tid=5637&highlight=excel

问题记录

  • web.view,需要启动多个webview时,不能使用同一个user-data目录,会导致闪退
  • msgbox,使用窗口对象调用时,会自动绑定当前窗口作为父窗口,不会出现窗口置顶时,被覆盖的情况