; 用于区分多键盘按键并设置按键触发的类库简化版【免驱动和dll】 By dbgba
; 另一个要安装驱动的多键盘区分:https://github.com/evilC/AutoHotInterception
#NoEnv
#SingleInstance Force
SetBatchLines -1
CoordMode ToolTip

MK := New MultiKeyboard()  ; 创建多键盘监控实例

MK.Tip(1)  ; 开启监控按键提示

A键盘设备ID := 65611
Return

F1::Clipboard := MK.记录["设备ID"]  ; 将设备ID存到剪贴板中,填写到 "A键盘设备ID" 变量中

Escape::
if (MK.记录[MK.记录["区分键名"]]=1) {
  if (MK.记录["设备ID"]=A键盘设备ID) {
    ToolTip % "A键盘:" A_ThisLabel, A_ScreenWidth, A_ScreenHeight//1.09, 17
  } else {
    ToolTip % "B键盘:" A_ThisLabel, A_ScreenWidth, A_ScreenHeight//1.09, 17
  }
}
MK.记录[A_ThisLabel] := 0
Return

F3::
if (MK.记录[MK.记录["区分键名"]]=1) {
  if (MK.记录["设备ID"]=A键盘设备ID) {
    ToolTip % "A键盘:" A_ThisLabel, A_ScreenWidth, A_ScreenHeight//1.09, 17
  } else {
    ToolTip % "B键盘:" A_ThisLabel, A_ScreenWidth, A_ScreenHeight//1.09, 17
  }
}
MK.记录[A_ThisLabel] := 0
Return

1::ToolTip % "计数测试:" n := n="" ? 1 : ++n

; 带修饰键的组合不需要 "if MK.记录[MK.记录["区分键名"]]",以下示例为:Ctrl+1
^1::
if (MK.记录["设备ID"]=A键盘设备ID) {
  ToolTip % "A键盘:" A_ThisLabel, A_ScreenWidth, A_ScreenHeight//1.09, 17
} else {
  ToolTip % "B键盘:" A_ThisLabel, A_ScreenWidth, A_ScreenHeight//1.09, 17
}
Return

; F4::MK.Stop()  ; 停止多键盘监控

; 已知问题:复杂化区分逻辑【$无效,~无法区分】
Class MultiKeyboard {
  __New() {
    this.记录 := {}
    , this.DeviceMovedFn := this.DeviceMoved.Bind(this)
    , VarSetCapacity(RAWINPUTDEVICE, DevSize := 8 + A_PtrSize)
    , NumPut(1, RAWINPUTDEVICE, 0, "UShort")  ; 注册键盘消息
    , NumPut(6, RAWINPUTDEVICE, 2, "UShort")  ; 注册指定设备
    , NumPut(0x00000100, RAWINPUTDEVICE, 4, "Uint")
    , NumPut(A_ScriptHwnd, RAWINPUTDEVICE, 8, "UPtr")  ; 脚本的隐藏主窗口
    , DllCall("RegisterRawInputDevices", "Ptr", &RAWINPUTDEVICE, "UInt", 1, "UInt", DevSize)
    , OnMessage(0x00FF, this.DeviceMovedFn)
  }

  Stop() {
    OnMessage(0x00FF, this.DeviceMovedFn, 0)
    , this.RegisterRawInputDevices(6, 0x00000001)  ; 停止键盘消息
    , this.DeviceMovedFn := this.记录 := ""
  }

  Tip(Log:=0) {
    this.Log := Log
  }

  DeviceMoved(wParam, lParam) {
    Critical
    ; 获取数据长度
    DllCall("GetRawInputData", "UInt", lParam, "UInt", 0x10000003, "Ptr", 0, "UInt*", iSize, "UInt", 8 + (A_PtrSize * 2))
    , VarSetCapacity(uRawInput, iSize)
    ; 获取原始输入数据
    , DllCall("GetRawInputData", "UInt", lParam, "UInt", 0x10000003, "Ptr", &uRawInput, "UInt*", iSize, "UInt", 8 + (A_PtrSize * 2))

    , this.记录["设备ID"] := NumGet(uRawInput, 8, "UPtr")
    , DllCall("GetRawInputDeviceInfo", "Ptr", 设备ID, "UInt", 0x20000007, "Ptr", 0, "UIntP", Size)
    ; , VarSetCapacity(info, Size)
    ; ; 获取设备详细信息
    ; , DllCall("GetRawInputDeviceInfo", "Ptr", this.记录["设备ID"], "UInt", 0x20000007, "Ptr", &info, "UIntP", Size)

    , this.记录["区分键名"] := GetKeyName("sc" Format("{:x}", NumGet(uRawInput, (8+A_PtrSize*2), "UShort")))
    , this.记录["按键状态"] := (NumGet(uRawInput, (16+A_PtrSize*2))=257 ? 0 : 1)  ; 按下或抬起

    if (this.Log=1)
      ToolTip % "设备ID:" this.记录["设备ID"] "`n按键:" this.记录["区分键名"] "`n按键状态:" this.记录["按键状态"] ; "`n设备详细信息:" StrGet(&info)

    if IsLabel(this.记录["区分键名"]) and (this.记录[this.记录["区分键名"]]!="")
      SetTimer % this.记录["区分键名"], % "-" this.记录[this.记录["区分键名"]] := 1
  }
}

 

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