; 记录键鼠按下了什么按键的脚本示例
#Persistent
; KeypressOSD.ahk
; https://www.autohotkey.com/boards/viewtopic.php?t=225

#SingleInstance force
#NoEnv
SetBatchLines, -1
ListLines, Off

ahklog.is_out_file := true ;输出到文件
ahklog.is_out_console := true ;输出到console

; Settings
  global ShowSingleKey     := True
  global ShowMouseButton     := True
  global ShowSingleModifierKey := True
  global ShowModifierKeyCount  := true
  global ShowStickyModKeyCount := false
  global DisplayTime       := 2000   ; In milliseconds

CreateHotkey()
return

OnKeyPressed:
  try {
    key := GetKeyStr()
    ahklog.info(key)
  }
return

OnKeyUp:
return

_OnKeyUp:
  tickcount_start := A_TickCount
return

; ===================================================================================

CreateHotkey() {
  Loop, 95
  {
    k := Chr(A_Index + 31)
    k := (k = " ") ? "Space" : k

    Hotkey, % "~*" k, OnKeyPressed
    Hotkey, % "~*" k " Up", _OnKeyUp
  }

  Loop, 24 ; F1-F24
  {
    Hotkey, % "~*F" A_Index, OnKeyPressed
    Hotkey, % "~*F" A_Index " Up", _OnKeyUp
  }

  Loop, 10 ; Numpad0 - Numpad9
  {
    Hotkey, % "~*Numpad" A_Index - 1, OnKeyPressed
    Hotkey, % "~*Numpad" A_Index - 1 " Up", _OnKeyUp
  }

  Otherkeys := "WheelDown|WheelUp|WheelLeft|WheelRight|XButton1|XButton2|Browser_Forward|Browser_Back|Browser_Refresh|Browser_Stop|Browser_Search|Browser_Favorites|Browser_Home|Volume_Mute|Volume_Down|Volume_Up|Media_Next|Media_Prev|Media_Stop|Media_Play_Pause|Launch_Mail|Launch_Media|Launch_App1|Launch_App2|Help|Sleep|PrintScreen|CtrlBreak|Break|AppsKey|NumpadDot|NumpadDiv|NumpadMult|NumpadAdd|NumpadSub|NumpadEnter|Tab|Enter|Esc|BackSpace"
         . "|Del|Insert|Home|End|PgUp|PgDn|Up|Down|Left|Right|ScrollLock|CapsLock|NumLock|Pause|sc145|sc146|sc046|sc123"
  Loop, parse, Otherkeys, |
  {
    Hotkey, % "~*" A_LoopField, OnKeyPressed
    Hotkey, % "~*" A_LoopField " Up", _OnKeyUp
  }

  If ShowMouseButton {
    Loop, Parse, % "LButton|MButton|RButton", |
      Hotkey, % "~*" A_LoopField, OnKeyPressed
  }

  for i, mod in ["Ctrl", "Shift", "Alt"] {
    Hotkey, % "~*" mod, OnKeyPressed
    Hotkey, % "~*" mod " Up", OnKeyUp
  }
  for i, mod in ["LWin", "RWin"]
    Hotkey, % "~*" mod, OnKeyPressed
}

GetKeyStr() {
  static modifiers := ["Ctrl", "Shift", "Alt", "LWin", "RWin"]
  static repeatCount := 1

  for i, mod in modifiers {
    if GetKeyState(mod)
      prefix .= mod " + "
  }

  if (!prefix && !ShowSingleKey)
    throw

  key := SubStr(A_ThisHotkey, 3)

  if (key ~= "i)^(Ctrl|Shift|Alt|LWin|RWin)$") {
    if !ShowSingleModifierKey {
      throw
    }
    key := ""
    prefix := RTrim(prefix, "+ ")

    if ShowModifierKeyCount {
      if !InStr(prefix, "+") && IsDoubleClickEx() {
        if (A_ThisHotKey != A_PriorHotKey) || ShowStickyModKeyCount {
          if (++repeatCount > 1) {
            prefix .= " ( * " repeatCount " )"
          }
        } else {
          repeatCount := 0
        }
      } else {
        repeatCount := 1
      }
    }
  } else {
    if ( StrLen(key) = 1 ) {
      key := GetKeyChar(key, "A")
    } else if ( SubStr(key, 1, 2) = "sc" ) {
      key := SpecialSC(key)
    } else if (key = "LButton") && IsDoubleClick() {
      key := "Double-Click"
    }
    _key := (key = "Double-Click") ? "LButton" : key

    static pre_prefix, pre_key, keyCount := 1
    global tickcount_start
    if (prefix && pre_prefix) && (A_TickCount-tickcount_start < 300) {
      if (prefix != pre_prefix) {
        result := pre_prefix pre_key ", " prefix key
      } else {
        keyCount := (key=pre_key) ? (keyCount+1) : 1
        key := (keyCount>2) ? (key " (" keyCount ")") : (pre_key ", " key)
      }
    } else {
      keyCount := 1
    }

    pre_prefix := prefix
    pre_key := _key

    repeatCount := 1
  }
  return result ? result : prefix . key
}

SpecialSC(sc) {
  static k := {sc046: "ScrollLock", sc145: "NumLock", sc146: "Pause", sc123: "Genius LuxeMate Scroll"}
  return k[sc]
}

; by Lexikos -- https://autohotkey.com/board/topic/110808-getkeyname-for-other-languages/#entry682236
GetKeyChar(Key, WinTitle:=0) {
  thread := WinTitle=0 ? 0
    : DllCall("GetWindowThreadProcessId", "ptr", WinExist(WinTitle), "ptr", 0)
  hkl := DllCall("GetKeyboardLayout", "uint", thread, "ptr")
  vk := GetKeyVK(Key), sc := GetKeySC(Key)
  VarSetCapacity(state, 256, 0)
  VarSetCapacity(char, 4, 0)
  n := DllCall("ToUnicodeEx", "uint", vk, "uint", sc
    , "ptr", &state, "ptr", &char, "int", 2, "uint", 0, "ptr", hkl)
  return StrGet(&char, n, "utf-16")
}

IsDoubleClick(MSec = 300) {
  Return (A_ThisHotKey = A_PriorHotKey) && (A_TimeSincePriorHotkey < MSec)
}

IsDoubleClickEx(MSec = 300) {
  preHotkey := RegExReplace(A_PriorHotkey, "i) Up$")
  Return (A_ThisHotKey = preHotkey) && (A_TimeSincePriorHotkey < MSec)
}

;-------------------log相关函数---------------------------------
class ahklog {
  static line := true
  static file := true
  static func := true
  static log_mode := "info"
  static log_strim := ""
  static is_log_open := true
  static is_out_console := true
  static is_out_file := false
  static console_create_flag := false
  __New() {
    DllCall("AllocConsole")
  }
  __Delete() {
    DllCall("FreeConsole")
  }
  to_str(str) {
    local
    rtn := ""
    if(IsObject(str)) {
      rtn := obj2json4log(str)
      ;删除换行空格
      rtn := StrReplace(rtn, "`r`n")
      rtn := StrReplace(rtn, " ")
    } else {
      rtn := str
    }
    return rtn
  }
  log(ByRef str) {
    if(this.is_out_console) {
      DllCall("AllocConsole")
      FileAppend,% "[" A_Now "." A_MSec "]" str "`r`n", *
    }
    if(this.is_out_file) {
      FileAppend,% "[" A_Now "." A_MSec "]" str "`r`n", key_history
    }
  }
  log_out(para*) {
    local
    global G_MY_DLL_USE_MAP, G_MY_DLL_BUFFER_SIZE
    if(this.is_log_open == False || (this.is_out_console == false && this.is_out_file == false)) {
      return
    }
    if(this.is_out_console == true && this.console_create_flag == false) {
      dllcall("AllocConsole")
      this.console_create_flag := true
    }
    if(A_IsCompiled) {
      this.line := false
    }
    err_obj := Exception("", -2)
    err_obj_up := Exception("", -3)
    SplitPath,% err_obj.file, file_info
    line_info := err_obj.line
    func_info := err_obj_up.what
    if(RegExMatch(func_info, "^-3")) {
      func_info := "Auto-execute"
    }
    file_info := this.file ? "[FILE:" file_info "]" : ""
    line_info := this.line ? "[LINE:" line_info "]" : ""
    func_info := this.func ? "[FUNC:" func_info "]" : ""
    mode_info := "[" this.log_mode "]"
    log_str := ""
    for k,v in para {
      log_str .= this.to_str(v)
    }
    log_str := mode_info file_info  line_info func_info this.log_strim ":" log_str
    this.log(log_str)
  }
  info(para*) {
    this.log_strim := ""
    this.log_mode := "info"
    this.log_out(para*)
  }
  warn(para*) {
    this.log_strim := ""
    this.log_mode := "warn"
    this.log_out(para*)
  }
  err(para*) {
    this.log_strim := ""
    this.log_mode := "err"
    this.log_out(para*)
  }
  critical(para *) {
    this.log_strim := ""
    this.log_mode := "critical"
    this.log_out(para*)
  }
  get_trim_position() {
    this.log_mode := "info"
    stack_position := 0
    index_position := 0
    while(1) {
      stack_position++

      func_stack := Exception("", index_position--)
      if(RegExMatch(func_stack.what, "^-")) {
        break
      }
      if(stack_position > 20) {
        break
      }
    }
    return stack_position
  }
  in(para *) {
    stack_position := this.get_trim_position()
    strim := ""
    loop,% stack_position - 3 {
      strim .= ">"
    }
    this.log_strim := strim
    this.log_out(para*)
  }
  out(para *) {
    stack_position := this.get_trim_position()
    strim := ""
    loop,% stack_position - 3
    {
      strim .= "<"
    }
    this.log_strim := strim
    this.log_out(para*)
  }
}

/*
;------------------------------------
;  json转码纯AHK实现 v2.0  By FeiYue
;------------------------------------
*/
obj2json4log(obj, space:="") {  ; AHK对象转Json字符串
  local
  ; 默认不替换 "/-->\/" 与 "Unicode字符-->\uXXXX"
  static rep:=[ ["\\","\"], ["\""",""""]  ; , ["\/","/"]
  , ["\r","`r"], ["\n","`n"], ["\t","`t"]
  , ["\b","`b"], ["\f","`f"] ]
  if !IsObject(obj)
  {
  if obj is Number
    return obj
  if (obj=="true" or obj=="false" or obj=="null")
    return obj
  For k,v in rep
    obj:=StrReplace(obj, v.2, v.1)
  ; While RegExMatch(obj, "[^\x20-\x7e]", k)
  ;   obj:=StrReplace(obj, k, Format("\u{:04x}",Ord(k)))
  return """" obj """"
  }
  is_arr:=1  ; 是简单数组
  For k,v in obj
  if (k!=A_Index) and !(is_arr:=0)
    Break
  s:="", space2:=space . "  "
  For k,v in obj
  s.= "`r`n" space2 . (is_arr ? ""
    : """" Trim(%A_ThisFunc%(Trim(k)),"""") """: ")
    . %A_ThisFunc%(v,space2) . ","
  return (is_arr?"[":"{") . Trim(s,",")
     . "`r`n" space . (is_arr?"]":"}")
}

 

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