ObjRegisterActive.ahk

/*
  ; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=6148
  ObjRegisterActive(Object, CLSID, Flags:=0)
  
    Registers an object as the active object for a given class ID.
    Requires AutoHotkey v1.1.17+; may crash earlier versions.
  
  Object:
    Any AutoHotkey object.
  CLSID:
    A GUID or ProgID of your own making.
    Pass an empty string to revoke (unregister) the object.
  Flags:
    One of the following values:
      0 (ACTIVEOBJECT_STRONG)
      1 (ACTIVEOBJECT_WEAK)
    Defaults to 0.
  
  Related:
    http://goo.gl/KJS4Dp - RegisterActiveObject
    http://goo.gl/no6XAS - ProgID
    http://goo.gl/obfmDc - CreateGUID()
*/
ObjRegisterActive(Object, CLSID, Flags:=0) {
  static cookieJar := {}
  if (!CLSID) {
    if (cookie := cookieJar.Remove(Object)) != ""
      DllCall("oleaut32\RevokeActiveObject", "uint", cookie, "ptr", 0)
    return
  }
  if cookieJar[Object]
    throw Exception("Object is already registered", -1)
  VarSetCapacity(_clsid, 16, 0)
  if (hr := DllCall("ole32\CLSIDFromString", "wstr", CLSID, "ptr", &_clsid)) < 0
    throw Exception("Invalid CLSID", -1, CLSID)
  hr := DllCall("oleaut32\RegisterActiveObject"
      , "ptr", &Object, "ptr", &_clsid, "uint", Flags, "uint*", cookie
      , "uint")
  if hr < 0
    throw Exception(format("Error 0x{:x}", hr), -1)
  cookieJar[Object] := cookie
}

 

发送端.ahk

; 已知限制:
; 如果脚本在运行远程脚本调用的方法时退出,则远程脚本将收到错误。
; AutoHotkey 如何在本地与 COM 对象交互以及 AutoHotkey 对象如何通过 COM 接口响应请求也存在一些限制。
; For 循环不支持远程对象。
; 变量无法通过 ByRef 传递到远程对象。
; 有些调用是不明确的;例如,foo.bar 触发器 foo.__Call 然后 foo.__Get

; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=6148
#Persistent
#Include <ObjRegisterActive>

; 获得一个激活的东西。
x := ComObjActive("{6B39CAA1-A320-4CB0-8DB4-352AA81E460E}")

; 组成一处房产。毕竟,这是一个AutoHotkey对象。
x.Name := "Bob"

; 调用一个方法。
x.Message("Hello, world!")

; 排队等候一些要做的工作。完成后我们会接到通知。
x.BeginWork({Complete: Func("Completed")})

Completed(work, worker) {
  MsgBox % worker.Name " 完成的工作。"
  worker.Quit()  ; Fire?
  ; PostMessage允许我们在关闭前返回。
  DetectHiddenWindows On  ; WM_CLOSE=0x10
  PostMessage 0x10,,,, ahk_id %A_ScriptHwnd%
}

 

接收端.ahk

; 注册我们的对象,以便其他脚本可以访问它
; 参数是我生成的GUID。您应该生成一个唯一的
; 到您的脚本。您可以使用[创建GUID] https://www.autohotkey.com/boards/viewtopic.php?f=6&t=4732
#Persistent
#Include <ObjRegisterActive>

ObjRegisterActive(ActiveObject, "{6B39CAA1-A320-4CB0-8DB4-352AA81E460E}")

OnExit Revoke
return

Revoke:
; 这将“撤消”对象,从而阻止任何新客户端连接
; 到它,但不会断开任何已连接的客户端。
; 实际上,在退出时这样做是完全没有必要的。
ObjRegisterActive(ActiveObject, "")
ExitApp

; 这是一个客户端将与之交互的简单类(对象)。
; 您可以注册任何对象;它不一定是一个类。
class ActiveObject {
  ; 简单的消息传递示例。
  Message(Data) {
    MsgBox 收到的消息:%Data%
    return 42
  }
  ; “工作线程”示例。
  static WorkQueue := []
  BeginWork(WorkOrder) {
    this.WorkQueue.Insert(WorkOrder)
    SetTimer Work, -100
    return

    Work:
    ActiveObject.Work()
    return
  }

  Work() {
    work := this.WorkQueue.Remove(1)
    ; 假装我们在工作,占用线程5秒。
    Sleep 5000
    ; 告诉老板我们完了。
    work.Complete(this)
  }

  Quit() {
    MsgBox 已呼叫“退出”。
    DetectHiddenWindows On  ; WM_CLOSE=0x10
    PostMessage 0x10,,,, ahk_id %A_ScriptHwnd%
    ; 现在返回,因此客户端对Quit()的调用成功。
  }
}

 

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。