A.ahk创建的菜单,如何通过B.ahk来显示A的菜单或直接调用A的某个功能?
例如,A.ahk
MyMenu := Menu()
MyMenu.Add('Item 1', MenuHandler)
MyMenu.Add('Item 2', MenuHandler)
MenuHandler(ItemName, ItemPos, MyMenu) {
MsgBox "You selected " ItemName " (position " ItemPos ")"
if(ItemName="Item 2")
item2Action()
}
item2Action() {
MsgBox "item2Action"
}
B.ahk
;显示菜单,由人来选择菜单项
#b::{
a_script_obj.MyMenu.Show
}
;直接调用某个功能
#a::
{
a_script_obj.item2Action()
}
1、通过Include将两个脚本整合一个。本文是希望解耦,所以不讨论该法。
2、通过OnMessage,实现消息机制。类似TC或xyPlorer的机制,感兴趣可以参考
XYplorer论坛的ahk帖子
3、通过微软COM模型实现两个ahk进程间协同。
本文主要介绍 方案3。
#Requires AutoHotkey v2
Persistent
MyClsid := '{E020E44C-6F6B-43D9-9BA6-1CEE1005ED91}'
MyMenu := Menu()
MyMenu.Add('Item 1', MenuHandler)
MyMenu.Add('Item 2', MenuHandler)
MenuHandler(ItemName, ItemPos, MyMenu) {
MsgBox "You selected " ItemName " (position " ItemPos ")"
if(ItemName="Item 2")
item2Action()
}
item2Action() {
MsgBox "item2Action"
}
;ActiveObject.Register(MyMenu, MyClsid)
ActiveObject.Register(Adapter(), MyClsid)
class Adapter {
__Call(name, args) {
return %name%(args*)
}
__Get(Key, Params) {
global
return Params.Length ? %Key%[Params*] : %Key%
}
__Set(Key, Params, Value) {
global
if Params.Length
%Key%[Params*] := Value
else %Key% := Value
}
__delete() {
ExitApp()
}
}
class ActiveObject
{ ; based on https://www.autohotkey.com/boards/viewtopic.php?f=6&t=6148
static objects := Map()
static Register(obj, sCLSID?) {
if this.objects.Has(obj) {
return this.objects[obj].clsid
}
sCLSID ?? sCLSID := this.CreateCLSID()
GUID := this.GUIDFromString(sCLSID)
hReg := this.RegisterActiveObject(obj, GUID)
this.objects[obj] := {clsid: sCLSID, reg: hReg}
OnExit(ObjBindMethod(this, 'Revoke', sCLSID))
return sCLSID
}
static Revoke(ObjOrClsid, *) {
if !IsObject(ObjOrClsid) {
for obj, info in this.objects {
if info.clsid = ObjOrClsid {
ObjOrClsid := obj
}
} until IsObject(ObjOrClsid)
}
try (IsObject(ObjOrClsid) && hReg := this.objects.Delete(ObjOrClsid).reg)
(IsSet(hReg) && DllCall('OleAut32\RevokeActiveObject', 'UInt', hReg, 'Ptr', 0))
}
static RegisterActiveObject(obj, GUID) {
static flag := ACTIVEOBJECT_STRONG := 0
DllCall('OleAut32\RegisterActiveObject', 'Ptr', ObjPtr(obj), 'Ptr', GUID, 'UInt', flag, 'UIntP', &hReg := 0)
return hReg
}
static GUIDFromString(sCLSID) => (DllCall('Ole32\CLSIDFromString', 'Str', sCLSID, 'Ptr', GUID := Buffer(16)), GUID)
static CreateCLSID() => ComObject('Scriptlet.TypeLib').GUID
}
#Requires AutoHotkey v2
MyClsid := '{E020E44C-6F6B-43D9-9BA6-1CEE1005ED91}'
try a_script_obj := ComObjActive(MyClsid)
catch {
MsgBox 'Object not found'
ExitApp
}
;显示菜单,由人来选择菜单项
#b::
{
a_script_obj.MyMenu.Show()
}
;直接调用某个功能
#a::
{
a_script_obj.item2Action()
}
如果不想使用这个 '{E020E44C-6F6B-43D9-9BA6-1CEE1005ED91}',可以用这个语句创建一个新的:
A_Clipboard := ComObject('Scriptlet.TypeLib').GUID