本文主要介绍 aardio + AutoHotkey 混合编程。

在 aardio 中可以调用很多编程语言,例如 C语言、C++、C#、Java、Python、R、Javascript、Node.Js、Fortran、VB、Flash ActionScript、PHP、VBScript、PowerShell、NewLISP、AutoLISP、Delphi、FreeBASIC、Ruby、Rust、Julia、Nim、Go 语言、批处理 ...... 请参考《 aardio 调用第三方编程语言示例》

 

1、双击打开:aardio 工具 / 扩展库
2、扩展库名字输入 ahk,搜索结果中双击 ahk 扩展库 —— 打开最新范例。

aardio 提供了 ahk 扩展库可用于嵌入 AutoHotkey 并与 AutoHotkey 交互调用,支持 AutoHotkey v1 以及 AutoHotkey v2 版本。

aardio 调用 AutoHotkey v1

aardio 可以直接调用 AutoHotkey 函数,AutoHotkey 也可以调用 aardio 函数,非常简单:

import win.ui;
/*DSG{{*/
var winform = win.form(text="嵌入 AutoHotkey v1 演示")
winform.add(
edit={cls="edit";left=17;top=18;right=741;bottom=445;edge=1;multiline=1;z=1}
)
/*}}*/ //导入 AutoHotkey v1 扩展库
import ahk; /*
导出允许AutoHotkey 调用的 aardio 函数(函数名必须以 on 开头)。
*/
ahk.onTest = function(param){
winform.edit.print( "winform.onTest被ahk调用",param );
winform.show();
} //运行ahk代码
ahk.run( `
#Persistent ;保持 AHK 线程不退出
#NoTrayIcon ;不显示托盘图标
#include <aardio> ;启动 AHK 代码中必须加入这句才能与 aardio 交互 ; 定义函数与 aardio 有点像,aardio 一般会写为 GetPoint = function(hwnd){ return value;}
GetPoint(){ ; 直接调用aardio函数,支持任意类型、不定个数的调用参数
aardio.onTest({ x : 2, y : 3 }) return { x : 2, y : 3 }
}`); /*
直接调用ahk里定义的全局函数,
参数和返回值自动支持各种数据类型,就像调用普通aardio函数。
是不是很神奇?!
*/
var point = ahk.GetPoint(); winform.edit.print("调用ahk函数的返回值:",point);
win.loopMessage();

请注意 aardio 中文件路径以斜杆(或反斜杆)开始表示应用程序根目录,应用程序根目录在开发时指工程目录或工程外独立启动的文件所在目录,发布后指 EXE 所在目录。应用程序根目录已设为 AHK 工作目录 %A_WorkingDir% 。

导出 aardio 函数给 ahk 时也可以返回一个异步执行的函数对象,调用虚拟桌面示例:

import ahk;
import dotNet.desktop;
import win.ui;
/*DSG{{*/
var winform = win.form(text="虚拟桌面切换";right=599;bottom=399)
winform.add(
edit={cls="edit";left=17;top=18;right=565;bottom=374;edge=1;multiline=1;z=1}
)
/*}}*/ //导出 AutoHotkey 函数
ahk.onSwitch = function(index){
winform.edit.print("已切换桌面到:",index); //虚拟桌面在键盘钩子中需要通过返回异步函数异步调用。
return function() {
dotNet.desktop.get(index).MakeVisible()
}
} //运行 AutoHotkey 代码注册热键
ahk.run( `
#Persistent
#NoTrayIcon
#include <aardio> ^j:: aardio.onSwitch(1)
^k:: aardio.onSwitch(2)
`); winform.show();
win.loopMessage();

如果在 aardio 中执行以下代码:

ahk.import("path/libName"); 

则由 aardio 导入

\AutoHotkey\Lib\path\libName.ahk 

可以在 aardio 工程中添加上面的 ahk 文件 到内嵌资源目录,这样该 ahk 文件会被编译到 exe 资源内,运行时自动转存为以下文件:

%A_MyDocuments%\AutoHotkey\Lib\path\libName.ahk 

在 AHK 中可以使用以下代码引用该模块:

#include <path/libName> 

在 aardio 中可使用 ahk.setGlobal() 函数修改 AHK 全局变量:

//直接修改 AHK 全局变量的值
ahk.setGlobal("gVar","测试一下")

在 aardio 中执行 AHK 代码时还可以支持 aardio 模板语法,也就是在 AHK 代码中可以直接写 aardio 代码,只要将 aardio 代码包含在 <? ?> 标记中就可以了(类似 PHP 模板语法),例如:

//运行 AHK 代码
ahk.run( `
#Persistent ;
#NoTrayIcon ;
#include <aardio> ; global gVar := "<?="允许嵌入 aardio 代码"?>" ;
`); //直接修改 AHK 全局变量的值
ahk.setGlobal("gVar","测试一下")

关于 aardio 模板语法请参考 aardio 文档。

aardio 调用 AutoHotkey v2

在 aardio 使用 ahk.thread 扩展库可以调用 AutoHotkey v2,ahk.thread 不再需要在 AHK 启动代码中包含 #include <aardio>,其他用法与调用 ahk 扩展库类似。下面看例子:

import win.ui;
/*DSG{{*/
var winform = win.form(text="嵌入 AutoHotkey v2 演示")
winform.add(
edit={cls="edit";left=8;top=10;right=749;bottom=452;edge=1;multiline=1;z=1}
)
/*}}*/ winform.show(); import ahk.thread;
var ahk2 = ahk.thread(); //直接定义允许 AHK 调用的 aardio 函数(函数名以on开头)
ahk2.onTest = function(param){
winform.edit.print( "winform.onTest被ahk调用",param );
return 123
} //运行 AHK 代码
ahk2.run( `
#NoTrayIcon ;不显示托盘图标
Persistent( true) ;保持ahk线程不退出 ; 定义函数与 aardio 有点像,aardio 一般会写为 GetPoint = function(hwnd){ return value;}
GetPoint(){ ; 直接调用aardio函数,支持任意类型、不定个数的调用参数
aardio.onTest({ x : 2, y : 3 }) return { x : 2, y : 3 }
}`); /*
直接调用ahk里定义的全局函数,
参数和返回值自动支持各种数据类型,就像调用普通aardio函数。
是不是很神奇?!
*/
var point = ahk2.GetPoint();
winform.edit.print("调用ahk函数的返回值:",point); win.loopMessage();

要注意 AHK 中的变量默认是局部变量,定义全局变量要用 global 语句,aardio 则是默认全局变量,定义局部变量要用 var 语句。

进阶

有了前面的基础,我们再将范例稍微整复杂一点,例如调用 AHK v1 :

import win.ui;
/*DSG{{*/
var winform = win.form(text="嵌入 AutoHotkey v1")
winform.add(
edit={cls="edit";left=17;top=18;right=734;bottom=444;edge=1;multiline=1;z=1}
)
/*}}*/ import ahk;
ahk.onTest = function(param){
winform.edit.print( "winform.onTest被ahk调用",param );
winform.show();
} ahk.run( `
#Persistent
#NoTrayIcon
#include <aardio> GetPoint(){ ; 命令式语法 = 号后面是字符串,变量要放到百分号里
POINT_TYPE =
(
UInt x;
UInt y;
) ; 首尾两个括号都必须独占一行,用于包含多行字符串 ; 新语法 := 后面是表达式,和其他编程语言类似字符串放引号里,变量不用放百分号里
point := Struct( POINT_TYPE ) ; ; 取结构体指针,aardio 里调用 API 时结构体总是自动转为指针,不需要写这些代码
ptr := point[] ; DllCall("user32.dll\GetCursorPos", "Ptr", ptr)
GetCursorPos(ptr) ; ; 直接调用aardio函数,支持任意类型、不定个数的调用参数
aardio.onTest({ x : point.x, y : point.y }) ; 命令式语法, 百分号加一个空格表示后面是表达式
MsgBox, % "x:" point.x ",y:" point.y return { x : point.x, y : point.y }
}`); /*
直接调用ahk里定义的全局函数
*/
var point = ahk.GetPoint();
winform.edit.print("调用ahk函数的返回值:",point); win.loopMessage();

以上主要是演示 aardio 与 AHK 交互,其实 aardio 直接调用 ::User32.GetCursorPos() 代码更简单,示例:

// 当然上面的代码用 aardio 直接写会更简单,例如:
var point = {int x;int y}; //不用声明直接调用 API,不用写参数类型这些
::User32.GetCursorPos(point);

aardio 可以免声明直接调用 WinAPI ,不需要指定参数类型。

下面再来个例子,使用 aardio 暂停、继续 AHK 脚本:

import fonts.fontAwesome;
import win.ui;
/*DSG{{*/
var winform = win.form(text="嵌入autohotkey演示";right=757;bottom=467)
winform.add(
button={cls="plus";text="暂停AHK";left=19;top=11;right=109;bottom=41;bgcolor=-6960024;font=LOGFONT(name='FontAwesome';charset=0);z=2};
edit={cls="edit";left=17;top=56;right=729;bottom=443;edge=1;multiline=1;z=1}
)
/*}}*/ import ahk;
var handle = ahk.run( `
#Persistent ;保持ahk线程不退出
#NoTrayIcon ;不显示托盘图标
#include <aardio> ;启动ahk代码中必须加入这句才能与aardio交互
::hj::run无乱码
`); winform.button.onMouseClick = function(){
if(winform.button.text=="暂停AHK"){
thread.suspend(handle)
winform.button.text = "继续AHK"
}
else {
thread.resume(handle)
winform.button.text = "暂停AHK"
}
} winform.button.skin({
color={
active=0xFFFFFFFF;
default=0xFF000000;
hover=0xFFFFFFFF
};
}); winform.show();
win.loopMessage();

aardio + AutoHotkey 混合编程的更多相关文章

  1. aardio + VBScript 混合开发

    aardio 与 VBScript 可以直接混合编程,VBScript 属于 Windows 系统自带组件 -- 可以方便地生成独立 EXE 程序. 快速入门 首先创建 VBScript 解释器,aa ...

  2. 如玫瑰一般的PHP与C#混合编程

    故事背景是这样的,有一套项目,服务器端是用C#写的,为了完成某种事情,它需要使用到一个组件,这个组件很小但很重要,很不巧的是,这个这个组件是用PHP语言写的,如果为了使用这个组件而专门搭建一个PHP的 ...

  3. C和C++混合编程中的extern "C" {}

    引言 在用C++的项目源码中,经常会不可避免的会看到下面的代码: 1 2 3 4 5 6 7 8 9 #ifdef __cplusplus extern "C" { #endif ...

  4. C# 托管和非托管混合编程

    在非托管模块中实现你比较重要的算法,然后通过 CLR 的平台互操作,来使托管代码调用它,这样程序仍然能够正常工作,但对非托管的本地代码进行反编译,就很困难.   最直接的实现托管与非托管编程的方法就是 ...

  5. [转载:]C#与Fortran混合编程之本地调用Fortran动态链接库

    前言 C#发展到现在,已是一门相当完善的语言,他基于C语言风格,演化于C++.并依靠强大的.NET底层框架.C#可以用来快速构建桌面及Web应用.然而在我们的实际工作中,尽管C#已经非常完善,但还是不 ...

  6. C#Matlab混合编程类 初始化问题解决方法

    ************** 异常文本 ************** System.TypeInitializationException: “myPlus.matClass”的类型初始值设定项引发异 ...

  7. 国内第一部C#.Net调用Matlab混合编程视频教程

       本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录:[目录]Matlab和C#混合编程文章目录 一.视频说明 2014年的5.1,我将这套视频教 ...

  8. 【5.1送礼】国内第一部Matlab和C#.Net混合编程视频教程【免费】

                  本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新    Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 上一次写博客很久了 ...

  9. 【原创】Matlab.NET混合编程技巧之找出Matlab内置函数

                  本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新    Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 Matlab与.N ...

随机推荐

  1. 网络营销谁在行?PHP小哥打个样

    PHP -ゞ 阿白同学的学习笔记 PHP学习笔记 - 01 - web2.0 - 网络营销 @ 目录 一. 前言 二. 开始(借助菜鸟教程平台练习) 1. Hello World -- 第一个案例 2 ...

  2. 手把手教你在netty中使用TCP协议请求DNS服务器

    目录 简介 DNS传输协议简介 DNS的IP地址 Do53/TCP在netty中的使用 搭建DNS netty client 发送DNS查询消息 DNS查询的消息处理 总结 简介 DNS的全称doma ...

  3. 使用uart串口接收模块接收信号,控制led灯闪烁

    功能描述: 使用遵循uart协议的接收模块接收控制信号,用来控制led的闪烁. 设计输入: 1.uart输入信号 2.时钟信号 3.复位信号 4.led信号 设计思路: 总体上:前面已经写了串口接收模 ...

  4. @Document注解与Lombok的区别

  5. vue使用vuex报错 "export 'watch' was not found in 'vue'

    问题 安装Vuex后报错"export 'watch' was not found in 'vue' 解决方法 如果你的vue版本是 2.X ,将vuex升到 3.X.X 就能够解决 npm ...

  6. Postgres常用SQL

  7. 服务器配置IP

    1.服务器系统一般有两个或多个网卡.在企业中一般给服务器网卡配一个可连外网的IP,如172.16.20.22 255.255.255.0 172.16.20.1 方便联网下载安装部分软件,若没有VPN ...

  8. 汇编语言基于8086CUP(想学操作系统的前奏!!!)

    汇编语言基于8086CUP(想学操作系统的前奏!!!) 1.汇编语言的产生 1.1.思维图 1.2.单位转换 1B=8bit 1KB=1024B 1MB=1024KB 1GB=1024MB 1TB=1 ...

  9. typora的第一天

    一级标题 二级标题 三级标题 ..... 表格 java spring mybatis 代码 java代码 public void Hello(){ } 字体 hello word! hello wo ...

  10. Docker与GU 安装管理配置

    Linux 下的 Docker 安装与使用 一.安装与配置 1.安装依赖包 1 sudo yum install -y yum-utils device-mapper-persistent-data ...