aardio + AutoHotkey 混合编程
本文主要介绍 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 调用第三方编程语言示例》。
使用 ahk 扩展库
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 混合编程的更多相关文章
- aardio + VBScript 混合开发
aardio 与 VBScript 可以直接混合编程,VBScript 属于 Windows 系统自带组件 -- 可以方便地生成独立 EXE 程序. 快速入门 首先创建 VBScript 解释器,aa ...
- 如玫瑰一般的PHP与C#混合编程
故事背景是这样的,有一套项目,服务器端是用C#写的,为了完成某种事情,它需要使用到一个组件,这个组件很小但很重要,很不巧的是,这个这个组件是用PHP语言写的,如果为了使用这个组件而专门搭建一个PHP的 ...
- C和C++混合编程中的extern "C" {}
引言 在用C++的项目源码中,经常会不可避免的会看到下面的代码: 1 2 3 4 5 6 7 8 9 #ifdef __cplusplus extern "C" { #endif ...
- C# 托管和非托管混合编程
在非托管模块中实现你比较重要的算法,然后通过 CLR 的平台互操作,来使托管代码调用它,这样程序仍然能够正常工作,但对非托管的本地代码进行反编译,就很困难. 最直接的实现托管与非托管编程的方法就是 ...
- [转载:]C#与Fortran混合编程之本地调用Fortran动态链接库
前言 C#发展到现在,已是一门相当完善的语言,他基于C语言风格,演化于C++.并依靠强大的.NET底层框架.C#可以用来快速构建桌面及Web应用.然而在我们的实际工作中,尽管C#已经非常完善,但还是不 ...
- C#Matlab混合编程类 初始化问题解决方法
************** 异常文本 ************** System.TypeInitializationException: “myPlus.matClass”的类型初始值设定项引发异 ...
- 国内第一部C#.Net调用Matlab混合编程视频教程
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录:[目录]Matlab和C#混合编程文章目录 一.视频说明 2014年的5.1,我将这套视频教 ...
- 【5.1送礼】国内第一部Matlab和C#.Net混合编程视频教程【免费】
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 上一次写博客很久了 ...
- 【原创】Matlab.NET混合编程技巧之找出Matlab内置函数
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 Matlab与.N ...
随机推荐
- APISpace 未来7天生活指数API接口 免费好用
随着经济的发展,我们的生活水平在不断的提高,生活指数在我们的生活中也越来越受到关注,根据当天的生活指数,我们就可以知道在今天我们可以干什么比较好. 未来7天生活指数API,支持国内3400+个城市 ...
- Redis基础课程讲义
Redis基础 课程内容 Redis入门 Redis数据类型 Redis常用命令 在Java中操作Redis 1. 前言 1.1 什么是Redis Redis是一个基于内存的key-value结构数据 ...
- Trie树模板2
Trie数模板2 problem 这道题然后我们求最大异或对,我们很容易想出来 \(O(n^2)\) 的做法,两层循环遍历搞定 然后我们知道这样是肯定是肯定过不了的,我们考虑用字典树解决,然后我们来看 ...
- 建立二叉树的二叉链表存储结构(严6.70)--------西工大noj
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct TreeNode ...
- 第十天python3 函数的销毁
全局函数销毁 三种方式: 1.重新定义同名函数 2.del语句删除函数对象 3.程序结束时 局部函数销毁 三种方式: 1.重新在上级作用域定义同名函数: 2.del语句删除函数对象: 3.上级作用域销 ...
- SpringBoot集成文件 - 如何使用POI导出Word文档?
前文我们介绍了通过Apache POI导出excel,而Apache POI包含是操作Office Open XML(OOXML)标准和微软的OLE 2复合文档格式(OLE2)的Java API.所以 ...
- 日夕如是寒暑不间,基于Python3+Tornado6+APScheduler/Celery打造并发异步动态定时任务轮询服务
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_220 定时任务的典型落地场景在各行业中都很普遍,比如支付系统中,支付过程中因为网络或者其他因素导致出现掉单.卡单的情况,账单变成了 ...
- 在docker中出现的僵尸进程怎么处理
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 一.发现问题 小玲是一名数据库测试人员,这一天她尝试在docker环境中部署GreatDB集群,结果在对greatsqld ...
- 出票系统:根据淡旺季的月份和年龄,打印票价[课后练习] 出票系统:根据淡旺季的月份和年龄,打印票价[课后练习] 4 10旺季: 4 10旺季: 成人(18-60) : 60 成人(18-60):60 儿童(<18) :半价 儿童(<18):半价 老人(>60) :1/3 老人(>60):1/3 淡季: 淡季: 成人: 40 成人:40 其他: 20 其他:20
用if适合新手练习 package LianXiTi;import java.util.Scanner;public class first2 {// 出票系统:根据淡旺季的月份和年龄,打印票价[课后 ...
- 毕昇编译器优化:Lazy Code Motion
摘要:本文中,我们将介绍通过代码移动(插入)的方式消除冗余计算的一个典型方法. 本文分享自华为云社区<编译器优化那些事儿(3):Lazy Code Motion>,作者:毕昇小助手. 导语 ...