AutoHotkey_L の #if をうまく使用すれば、修飾キー付きのキーを内部から送信するソフトウェアにうまく対応できそうだ。以下のスクリプトでは、Clibor の自動貼り付け処理と、ユーザーが実際に Ctrl-v を打鍵したときの処理を区別できるようにしている。
AutoHotkey の不具合であるCtrl-zのための処理を追加しなくてはならないが*1、それを除けば、概ねこのような処理で大丈夫だろう。
#UseHook #InstallKeybdHook #InstallMouseHook #NoEnv #SingleInstance FORCE ;; Clibor のようなソフトウェアから送信されたキーなのか、 ;; それとも、ユーザーがまさにそのキーを打鍵したのかを検出する *v::tooltip,% test() F12::reload /* ;;; ホットキーどおりユーザーがキーを物理的に打鍵したとき、 ;;; すなわち、他のソフトウェアからキーが送信されていないときに限り ;;; ホットキーの処理をすすめる #if get_state_of_modifier_and_key( a_thishotkey ) *v::tooltip,% test() */ test(){ ;; 他のソフトウェアにより送信されたキーか? return, % "OS 起動時からの経過秒:`t" . a_tickcount . "`n`n" . "設定している修飾キーがすべて物理的に押し下げられている?`t" . get_state_of_modifier( a_thishotkey ) . "`n" . "修飾キー以外のキーは物理的に押し下げられている?`t" . get_state_of_key( a_thishotkey ) . "`n" . "設定しているホットキーはすべて物理的に押し下げられている?`t" . get_state_of_modifier_and_key( a_thishotkey ) } get_state_of_modifier_and_key( p_set_key ) { return, % ( ( get_state_of_modifier( a_thishotkey ) ) and ( get_state_of_key( a_thishotkey ) ) ) } get_state_of_key( p_set_key ) { return, GetKeyState( get_key_without_modifier( p_set_key ), "P") } get_state_of_modifier( p_set_key ) { all_state := Array() ;; ホットキーの設定から修飾キーの設定を読み取る for index,key_name in get_modifier( p_set_key ) { ;; 修飾キーすべての状態を調べあげるとき if ( key_name = "all") { if ( ( GetKeyState("shift", "P") ) or ( GetKeyState("alt", "P") ) or ( GetKeyState("rwin", "P") ) or ( GetKeyState("lwin", "P") ) or ( GetKeyState("ctrl", "P") ) ) { all_state[index] := True } else { all_state[index] := False } } else if ( key_name = "win") { all_state[index] := ( GetKeyState("lwin", "P") ) or ( GetKeyState("rwin", "P") ) } else { all_state[index] := GetKeyState(key_name, "P") } } ;; 物理的に押し下げられていないキーがあれば False ;; すべて押し下げられていれば True return, % all_state.indexOf(False) ? False : True } get_modifier( p_keys ) { keys := Array() RegExMatch(p_keys, "[\^\!\+\*#]+", modifier) Loop, Parse, modifier { if ( A_LoopField ) { if (A_LoopField = "^") { keys.append("ctrl") } else if (A_LoopField = "+") { keys.append("shift") } else if (A_LoopField = "!") { keys.append("alt") } else if (A_LoopField = "#") { keys.append("win") } else { keys.append("all") } } } return keys } get_key_without_modifier( p_keys ) { RegExMatch(p_keys, "[\^\!\+\*#]+(.+)", key_without_modifier) return key_without_modifier1 } ;;; [AHK_L] Arrays ;;; http://www.autohotkey.com/forum/topic49736.html ;;; 一度に操作しうる要素の数を制限しないようにした ; Array Lib - temp01 - http://www.autohotkey.com/forum/viewtopic.php?t=49736 Array(params*){ static ArrBase := Object("len", "Array_Length" , "indexOf", "Array_indexOf" , "join", "Array_Join" , "append", "Array_Append") arr := Object("base", ArrBase) for index,param in params { arr.insert(index, param) } Return arr } Array_indexOf(p_arr, p_val, p_startpos=1){ for index,value in p_arr { If ( index >= p_startpos && value == p_val ) { Return index } } } Array_Join(p_arr, p_sep="`n"){ str := "" for index,value in p_arr { str .= p_arr[index] . p_sep } StringTrimRight, str, str, % StrLen(p_sep) return str } Array_Append(p_arr, params*) { max_index := p_arr.MaxIndex() for index,value in params { p_arr.insert(value) } return p_arr }