AHK V1转V2 之初步经验

V2相对V1,语法不仅变化多,而且V1中很多函数也被删除或者被改名了,而且V2增加了一些函数或对象.

不过转的话面临一个问题,原来V1的库或者函数,或者代码怎么办?

如果是V1库或者函数,这个好办,你可以把他想象为另外一种语言,比如JS. 而AHK可以调用JS,对吧,那么AHKV2同样的也可以调用V1吧?

当然可以的啦.

反正,我现在是把V2的代码文件类型自定义为的是.AH2,这样就可以将V2的文件和V1的文件区分开,执行他们的解释器也就分别关联,V1的还用原来的执行,V2的AH2用V2的执行.

那么在V2中如何引用或使用V1的库或者函数呢? (如果实在是暂时不想转换成为V2的格式)

方式如下,只需要在V2中定义一个调用函数就行了

例子:比如使用V1下的btt.ahk这个库,而这个库里面又引用了gdip_all.ahk这个库

 bttv1 := import_v1lib("BTT.ahk","C:\Program Files\AutoHotkey\AutoHotkey.exe")

bttv1.btt("v2调用V1",800,800,"style6") 

这样就可以了

v2下import_v1lib这个函数如下:

import_v1lib(pathsorcode, ahkv1runtime := "C:\Program Files\AutoHotkey\AutoHotkey.exe") {
	static IDispatch := Buffer(16), _ := NumPut("int64", 0x20400, "int64", 0x46000000000000c0, IDispatch)
	lresult := DllCall("oleacc\LresultFromObject", "ptr", IDispatch, "ptr", 0, "ptr", ObjPtr(client := { proxy: 0 }), "ptr")
	; free com marshal on fail
	autofree := { ptr: lresult, __Delete: (s) => DllCall("oleacc\ObjectFromLresult", "ptr", s, "ptr", IDispatch, "ptr", 0, "ptr*", ComValue(9, 0)) }
	if !FileExist(ahkv1runtime)
		throw Error("AutoHotkey v1 runtime isn't exist")
	if pathsorcode is Array {
		t := pathsorcode, pathsorcode := ""
		for p in t
			pathsorcode .= "`n#include " p
	}
	v1script := Format("
	(
		#Persistent
		#NoTrayIcon
		class AHKv1LibHelper {
			__New(name, args*) {
				static _ := (VarSetCapacity(IDispatch, 16), NumPut(0x46000000000000c0, NumPut(0x20400, IDispatch, "int64"), "int64"), DllCall("oleacc\ObjectFromLresult", "ptr", {}, "ptr", &IDispatch, "ptr", 0, "ptr*", idisp := 0), ComObject(9, idisp).proxy := new AHKv1LibHelper(), ObjRelease(idisp))
				return IsObject(name) ? new name(args*) : new %name%(args*)
			}
			__Call(name, args*) {
				return %name%(args*)
			}
			__Get(name) {
				global
				return val := %name%
			}
			__Set(name, val) {
				global
				return %name% := val
			}
			__Delete() {
				SetTimer ExitApp, -1
				return
				ExitApp:
					ExitApp
			}
		}
		{}
	)", lresult, FileExist(pathsorcode) ? "#include " pathsorcode : pathsorcode)
	if ahkv1runtime ~= "i)\.dll$" {
		if !DllCall("GetModuleHandle", "str", ahkv1runtime) && !DllCall("LoadLibrary", "str", ahkv1runtime)
			throw Error("load AutoHotkey.dll fail")
		if !hThread := DllCall(ahkv1runtime "\ahktextdll", "str", v1script, "str", "", "str", "", "cdecl ptr")
			throw Error("Failed to load script")
		while !client.proxy
			Sleep(10)
	} else {
		exec := ComObject("WScript.Shell").Exec('"' ahkv1runtime '" /ErrorStdOut *')
		exec.StdIn.Write(v1script), exec.StdIn.Close()
		while exec.Status = 0 && !client.proxy
			Sleep(10)
		if exec.Status != 0 {
			ex := Error("Failed to load script")
			if RegExMatch(err := exec.StdErr.ReadAll(), "s)(.*?) \((\d+)\) : ==> (.*?)(?:\s*Specifically: (.*?))?\R?$", &m)
				ex.Message .= "`n`nReason:`t" m[3] "`nLine text:`t" m[4] "`nFile:`t" m[1] "`nLine:`t" m[2]
			throw ex
		}
	}
	autofree.DeleteProp("__Delete")
	return client.proxy
}

 

当然,如果想彻底和V1决裂的话,就是彻底的将V1代码转换为V2,有一个转换器,不过不完美,只是固定规则,原作者还在完善中,贴上这个转换器的下载地址:

https://github.com/mmikeww/AHK-v2-script-converter/archive/master.zip

给TA捐赠
共{{data.count}}人
人已捐赠
其他

AHKV2 利用GDIP实现ColorPicker的自定义

2022-3-15 14:26:44

其他

AHKV1 如何用起来像V2语法一般

2022-3-15 20:20:18

4 条回复 A文章作者 M管理员
  1. hexuren

    不错的基础贴,感谢分享

  2. hexuren
    1河许人给您打赏了¥2
  3. 五分钟

    ?

  4. 麻花藤

    ?

个人中心
购物车
优惠劵
有新私信 私信列表
搜索