MKScript 是一种静态强类型解释型脚本语言,其中关键词、变量名都是区分大小写的。
数据类型
类型 | 描述 | 占用字节数 | 值的范围 | 示例 |
byte | 字节型 | 1字节 | 0 ~ 255 | byte b = 1 |
char | 字符型 | 2字节 | 0 ~ 65535 | char c = 'a' |
short | 短整型 | 2字节 | -32768 ~ 32767 | short s = 1 |
int | 整型 | 4字节 | -2147483648 ~ 2147483647 | int m = 1, n = 2 |
long | 长整型 | 8字节 | -9223372036854775808 ~ 9223372036854775807 | long v = 123456789 |
float | 单精度浮点数 | 4字节 | float x = 3.14 | |
double | 双精度浮点数 | 8字节 | double x = 3.14 | |
string | 字符串 | string t = "你好" | ||
Bmp | 位图对象 | 24位色 | Bmp bmp = screen_get_bmp(64, 32, 128, 16) | |
void | 无返回值 | void (*func)(int, int *) = dll_get_function(...) |
类型 | 描述 | 示例 |
ArrayList<T> | 动态数组 | ArrayList<int> list = {1, 2, 3} |
LinkedList<T> | 链表 | LinkedList<int> list = {1, 2, 3} |
HashMap<K,V> | 哈希表 | HashMap<int, string > map |
Iterator<T> | 迭代器 | Iterator<int> iterator = hashmap_keys(map) |
说明:
1. 在子函数外部(func ...)定义的变量是【全局变量】,作用范围是全局性的。 在子函数内部(func ...)定义的是【局部变量】,作用范围仅限子函数内。
2. <T> 中的 T 表示数据的基本类型, 可以是:byte, char, short, int, long, float, double, string, Bmp中的任意一种。
静态数组
类型 | 描述 | 示例 |
byte v[3] | 字节数组 | byte v[3] = {0, 1, 2} |
char v[3] | 字符数组 | char v[3] = {'a', 'b', 'c'} |
int v[3] | 整型数组 | int v[3] = {1, 2, 3} |
long v[3] | 长整型数组 | long v[3] = {1L, 2L, 3L} |
float v[3] | 单精度浮点型数组 | float v[3] = {1.0f, 2.0f, 3.0f} |
double v[3] | 双精度浮点型数组 | double v[3] = {1.0, 2.0, 3.0} |
string v[3] | 字符串数组 | string v[3] = {"a", "b", "c"} |
Bmp v[3] | 位图对象数组 | Bmp v[3] |
算术运算符
运算符 | 描述 | 示例 |
+ | 加 | int m = 5 + 3 |
- | 减 | int m = 6 - 5 |
* | 乘 | int m = (3 + 2) * 6 |
/ | 除 | int m = 6 / 3 |
% | 余数(取模) | int m = 6 % 2 |
& | 按位与 | int m = 2 & 3 |
^ | 按位异或 | int m = 2 ^ 3 |
| | 按位或 | int m = 2 | 3 |
~ | 按位取反 | int m = ~ 1 |
<< | 左移 | int m = 16 << 1 |
>> | 右移 | int m = 16 >> 1 |
算术运算符的优先级
优先级 | 运算符 | 结合方向 | 描述 |
1 | () [] | 从左到右 | 括号(函数),数组几种结构成员访问 |
2 | -(负) ~ | 从右到左 | 负号,按位取反 |
3 | * / % | 从左到右 | 乘,除,取模 |
4 | + -(减) | 从左到右 | 加,减 |
5 | << >> | 从左到右 | 左移,右移 |
6 | & | 从左到右 | 按位与 |
7 | ^ | 从左到右 | 按位异或 |
8 | | | 从左到右 | 按位或 |
比较运算符
符号 | 描述 | 示例 |
> | 大于 | |
>= | 大于或等于 | |
== | 等于 | |
< | 小于 | |
<= | 小于或等于 | |
!= | 不等于 |
逻辑运算符
符号 | 描述 | 示例 |
&& | 与运算 (and) | a && b, 如果 a 与 b 都为 true, 结果为 true |
|| | 或运算 (or) | a || b, 如果 a 或 b 任一为 true, 结果为 true |
条件语句
语法样式 1 | 语法样式 2 | 语法样式 3 |
if a > b 代码块... endif |
if a > b 代码块... elseif a < b 代码块... else 代码块... endif |
if screen_get_color_at(x, y) == color 代码块... elseif screen_get_color_at(x, y) == color_2 代码块... else 代码块... endif |
说明:if 与 endif 必须成对出现。
循环语句
语法样式 1 | 语法样式 2 | 语法样式 3 | 语法样式 4 |
loop 3 代码块... endloop |
loop a > b 代码块... endloop |
for [int] i = 1 to 5 [step 1] 代码块... next |
for [T] var in (静态数组 | 动态数组 | 链表) 代码块... next |
说明:
loop 与 endloop 必须成对出现。
for 与 next 必须成对出现。
loop 3 表示: 循环执行代码块 3 次 。
loop -1 表示: 无限循环执行代码块 。
loop a > b 表示: 当 a > b 将一直循环执行代码块。
for 循环: For…Next 循环的语法中使用初值、终值、步长以及循环变量来完成循环操作的过程。
当进入循环第一次执行时,循环变量便由初值开始累加一次步长,一直到超过终值为止。
for 循环的中括号部分[...] 属于可选项。
关键词 | 描述 |
break | 跳出循环,跳出循环会继续执行该循环之后的代码。 |
continue | 中断循环中的当前迭代,如果出现了指定的条件,然后继续循环中的下一个迭代。 |
goto 语句
语法样式 |
for(...) for(...) 代码块... if 条件
#goto语法结构: goto 标签 endif next next
#标签定义: 标签名后面加一个冒号 ':' println("跳出多层循环") |
说明:
goto语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出多层循环体等功能。
【标签】不能在结构体内定义,只能在最外层定义。
goto语句只能goto到同一函数内,而不能从一个函数里goto到另外一个函数里。
子函数
语法样式 1 | 语法样式 2 | 语法样式 3 | 语法样式 4 |
func void funcName() 代码块... endfunc |
func int Max(int a, int b) if a > b return a else return b endif endfunc |
func int update(int *a) a = 2 endfunc int v = 1 update(v) println(v) |
func void printArr(int arr[], int count) for int i = 0 to count -1 println("arr[" + i + "]: " + arr[i]) next endfunc int list[3] = {1, 2, 3} printArr(list, 3) |
说明:
func 与 endfunc 必须成对出现。
子函数的参数类型以及返回值类型目前只支持: byte, char, short, int, long, float, double, string, Bmp
在调用子函数传递参数时, 参数默认是传值, 如需传址只需在参数类型后面加上一个 *, 比如: int* v,静态数组做为参数也是传址。
注意:尽量不要在子函数内使用递归调用,不然很容易引起栈溢出而导致程序异常关闭。
关键词 | 描述 |
void | 表示函数没有返回值。 |
return | return 表示把程序流程从被调函数转向主调函数并把表达式的值带回主调函数,实现函数值的返回,返回时可附带一个返回值,由return后面的参数指定。 |
函数指针
目前支持从【DLL动态链接库】和【COM组件对象】中获取函数指针。
函数来自 | 示例 |
DLL动态链接库 | int (*myMax)(int, int) = dll_get_function("Max") void (*updateData)(int *) = dll_get_function("updateData") |
COM组件对象 | int (*myMax)(int, int) = com_object_get_function(comObjectHandle, "Max") int (*updateData)(int *t) = com_object_get_function(comObjectHandle, "updateData") int (*adodb_stream_open_write)(byte *!) = com_object_get_function(comObjectHandle, "write") |
参数类型 | 描述 |
int | 参数传值 |
int * | 参数传址(传引用) |
byte *! | 参数是一个 COM 安全数组 byte 类型, COM 安全数组可通过 com_safe_array_new_byte() 函数创建。 |
#演示在 MKScript 中调用 Win32 API 函数
#加载 user32.dll
int dllHandle = dll_load("user32.dll")
#MessageBoxW 函数功能: 显示一个模式对话框,其中包含系统图标、一组按钮和一条简短的应用程序特定消息,例如状态或错误信息。
#消息框返回一个整数值,该值指示用户单击的按钮。
#详细说明: https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-messageboxw
#定义【函数指针: mb】映射到【MessageBoxW 函数】
int (*mb)(int, string, string, int) = dll_get_function("MessageBoxW")
#消息框中显示的按钮, 指定以下值之一
int MB_OK = 0x00000000 #消息框包含一个按钮: 确定。 这是默认值。
int MB_OKCANCEL = 0x00000001 #消息框包含两个推送按钮: “确定 ”和 “取消”。
int MB_YESNOCANCEL = 0x00000003 #消息框包含三个按钮: 是、 否和 取消。
int MB_YESNO = 0x00000004 #消息框包含两个按下按钮: 是 和 否。
int MB_RETRYCANCEL = 0x00000005 #消息框包含两个按下按钮: 重试 和 取消。
#消息框中显示图标, 指定以下值之一
int MB_ICONERROR = 0x00000010 #消息框中会显示一个停止符号图标。
int MB_ICONQUESTION = 0x00000020 #消息框中会显示一个问号图标。
int MB_ICONWARNING = 0x00000030 #消息框中会显示一个感叹号图标
int MB_ICONINFORMATION = 0x00000040 #图标由圆圈中的小写字母 i 组成,显示在消息框中。
#调用 mb() 相当于调用了 Win32 API 函数:MessageBoxW()
int status = mb(window_get_mkscript_handle(), "看到一个弹出对话框了吗?", "这是标题", MB_YESNO | MB_ICONQUESTION)
#返回值 说明
#----------------------------------
# 1 已选择【确定】按钮。
# 2 已选择【取消】按钮。
# 4 已选择【重试】按钮。
# 6 已选择【是】按钮。
# 7 已选择【否】按钮。
println("status:" + status)
include 语句
我们经常遇到需要重复使用的模块代码,通常我们将这些模块代码保存为一个单独的文件,需要使用此模块代码时,在脚本中通过 include 语句引用此文件,这样方便了脚本的后续维护。
include 语法include "脚本文件" #语法格式
include "a.m" #相对路径:引入当前脚本文件夹中的 a.m
include "inc\b.m" #相对路径:引入当前脚本文件夹的 inc 子文件夹中的 b.m
include "..\c.m" #相对路径:引入当前脚本文件夹的上一级文件夹中的 c.m
include "c:\d.m" #绝对路径:引入 c:\d.m
string filePath = "a.m"
include filePath #错误用法:include 后面的脚本文件只能使用字符串常量,不可使用变量。
代码注释
注释符号 | 描述 |
# | 单行注释符号。如果需要注释,# 可以写在行首位置。v9.0开始 # 也可以写在行尾 |
内置函数
函数类型 | 描述 | 示列 |
鼠标 | 鼠标操作相关的函数以 mouse_ 开头。 | mouse_move_to(30, 20) |
键盘 | 键盘操作相关的函数以 key_ 开头。 | key_char('a', 1) |
后台鼠标 | 后台鼠标操作相关的函数以 window_mouse_ 开头。 | window_mouse_move_to(...) |
后台键盘 | 后台键盘操作相关的函数以 window_key_ 开头。 | window_key_code(hwnd, 'A') |
屏幕颜色 | 获取屏幕尺寸、像素颜色、屏幕位图相关的函数,以 screen_开头。 | screen_get_color_at(6, 9) |
Bmp位图 | 与 Bmp 位图操作相关的函数,以 bmp_ 开头。 | bmp_find_bmp(...) |
字符串 | 字符串的查找、替换、转换。 | lcase("AbcD") |
数学 | 提供一些与数字处理相关的函数。 | floor(1.23), ceil(1.23) |
日期时间 | 获取当前的日期、时间等。 | time(), get_now() |
窗口 | 与窗口操作相关的函数,以 window_ 开头。 | window_show(...) |
文件 | 文件操作相关的函数。 | file_read("d:\\a.txt", fileBody) |
类型转换 | 数据类型转换相关的函数。 | itos(3), stoi("5") |
动态数组 | 动态数组相关的函数以 arraylist_ 开头。 | arraylist_add(list, 3) |
链表 | 链表相关的函数以 linkedlist_ 开头。 | linkedlist_add(list, 3) |
哈希表 | 哈希表相关的函数以 hashmap_ 开头。 | hashmap_put(map, ...) |
迭代器 | 迭代器相关的函数以 iterator_ 开头。 | iterator_has_next(i) |
本地存储 | 在本地存储一些简单的数据,以 storage_ 开头。 | storage_set(key, value) |
剪贴板 | 剪贴板相关的函数以 clipboard_ 开头。 | clipboard_set_text("...") |
动态链接库 | 动态链接库相关的函数以 dll_ 开头。 | dll_load("...") |
COM组件对象 | COM组件对象相关的函数以 com_ 开头。 | com_object_new("...") |
Excel 电子表格 | Excel 电子表格(Excel.Application)相关的函数 | |
数据库函数 | 数据库相关的函数 | |
Json函数 | Json相关的函数 | |
其他 | sleep(1000) |