赞 | 342 |
VIP | 10 |
好人卡 | 8 |
积分 | 262 |
经验 | 235776 |
最后登录 | 2024-9-23 |
在线时间 | 2387 小时 |
Lv5.捕梦者 (版主) 遠航の猫咪
- 梦石
- 3
- 星屑
- 23186
- 在线时间
- 2387 小时
- 注册时间
- 2005-10-15
- 帖子
- 1166
|
可以试一下这个版本
已经删除了对SEP公共核心的依赖,当然也删除了自动绑定窗口事件按键处理的功能
因为插件自己保留了一个Flag用于更新状态,不是完全依赖GetAsyncKeyState,所以不会出现更新延迟时丢失按键的问题,除非延迟到两帧之间存在了完整的按键+弹起的过程
#============================================================================== # ■ [Keyboard Indie] 全键盘处理核心 v1.1 by SailCat #------------------------------------------------------------------------------ # 方法:本脚本插入Main之前使用 # 依赖:无 # 版本:v1.1 (Build 220224) # 效果: # 1. 全键盘按键响应 # 2. 注入Input模块的update处理 # 3. Lock键、Shift/Ctrl/Alt/Win键状态的响应 # 4. 获得输入的字符 # 配置:重复延迟和重复间隔速率 # 冲突:其他类似脚本 # 说明: # 1. 调用全键盘方法为Keyboard.press?(键名常量、符号或字符)。 # 2. 上述press?也可替换为trigger?或repeat?,含义与Input中的同名方法相同。 # 3. 其他检测包括对于Lock键的状态,Shift/Ctrl/Alt/Win的状态检测等。 # 4. 使用Keyboard.type_char可以获得打字键入的字符。 #============================================================================== #============================================================================== # ■ SailCat's 插件公用 #============================================================================== module SailCat #-------------------------------------------------------------------------- # ● 脚本配置区 #-------------------------------------------------------------------------- module Keyboard_Config REPEAT_DELAY = 8 # 首次重复前的延迟值(帧) REPEAT_SPEED = 4 # 每次重复按键的间隔(帧),越大越慢 #-------------------------------------------------------------------------- # ● 配置检查,请勿更改 #-------------------------------------------------------------------------- raise "重复按键的间隔不能低于1帧" unless REPEAT_SPEED > 0 end end #============================================================================== # ■ 全键盘处理核心 #============================================================================== module Keyboard include SailCat::Keyboard_Config #-------------------------------------------------------------------------- # ● 常量 #-------------------------------------------------------------------------- NONE = 0 L_BUTTON, R_BUTTON, CANCEL, M_BUTTON, X_BUTTON1, X_BUTTON2 = *1..6 BACKSPACE, TAB, LINE_FEED, V_TAB, CLEAR, ENTER = *8..13 SHIFT_KEY, CONTROL_KEY, ALT_KEY, PAUSE_KEY = *16..19 CAPS_LOCK, KANA_MODE, JUNJA_MODE, DUMMY, FINAL_MODE, KANJI_MODE = *20..25 ESCAPE, IME_CONVERT, IME_NONCONVERT, IME_ACCEPT, IME_MODECHANGE = *27..31 SPACE, PAGEUP, PAGEDOWN, ENDKEY, HOME, LEFT, UP, RIGHT, DOWN = *32..40 SELECT, PRINT, EXECUTE, PRINTSCREEN, INSERT, DELETE, HELP = *41..47 D0, D1, D2, D3, D4, D5, D6, D7, D8, D9 = *48..57 A, B, C, D, E, F, G, H, I, J, K, L, M = *65..77 N, O, P, Q, R, S, T, U, V, W, X, Y, Z = *78..90 LWIN, RWIN, APPS, SLEEP = 91, 92, 93, 95 NUM0, NUM1, NUM2, NUM3, NUM4, NUM5, NUM6, NUM7, NUM8, NUM9 = *96..105 MULTIPLY, ADD, SEPARATOR, SUBTRACT, DECIMAL, DIVIDE = *106..111 F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12 = *112..123 F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24 = *124..135 NUM_LOCK, SCROLL_LOCK = 144, 145 L_SHIFT, R_SHIFT, L_CTRL, R_CTRL, L_ALT, R_ALT = *160..165 B_BACK, B_FORWARD, B_REFRESH, B_STOP, B_SEARCH, B_FAVOR, B_HOME = *166..172 VOL_MUTE, VOL_DOWN, VOL_UP = *173..175 MEDIA_NEXT, MEDIA_PREVIOUS, MEDIA_STOP, MEDIA_PLAYPAUSE = *176..179 LAUNCH_MAIL, SELECT_MEDIA, LAUNCH_APP1, LAUNCH_APP2 = *180..183 SEMICOLON, PLUS, COMMA, MINUS, PERIOD, QUESTION, TILDE = *186..192 L_BRACE, PIPE, R_BRACE, QUOTE, OEM8 = *219..223 BACKSLASH, PROCESS_KEY, PACKET = 226, 229, 231 ATTN, CRSEL, EXSEL, ERASE_EOF, PLAY, ZOOM, NONAME, PA1, OEM_CLEAR = *246..254 ANY_BUTTON = [1, 2, 4, 5, 6] ANY_KEY = [8..13, 27, 32..57, 65..90, 96..135, 186..192, 219..223].map do |x| x.to_a end.flatten #-------------------------------------------------------------------------- # ● API #-------------------------------------------------------------------------- GetAsyncKeyState = Win32API.new("user32", "GetAsyncKeyState", "i", "i") GetKeyState = Win32API.new("user32", "GetKeyState", "i", "i") #-------------------------------------------------------------------------- # ● 用于检测重复按键的标记器 #-------------------------------------------------------------------------- Flags = {} #-------------------------------------------------------------------------- # ● 更新键盘输入,该方法每帧调用1次 #-------------------------------------------------------------------------- def self.update @keychar = nil Flags.each_key do |k| GetAsyncKeyState.call(k) & 32768 != 0 ? Flags[k] += 1 : Flags.delete(k) end end #-------------------------------------------------------------------------- # ● 判断对应的键是否现在被按下 #-------------------------------------------------------------------------- def self.press?(key) key = get_key(key) unless key.is_a?(Numeric) or key.is_a?(Array) return key.any?{|k| press?(k)} if key.is_a?(Array) GetAsyncKeyState.call(key) & 32768 != 0 ? (Flags[key] ||= 0; true) : false end #-------------------------------------------------------------------------- # ● 判断对应的键是否重新被按下 #-------------------------------------------------------------------------- def self.trigger?(key) key = get_key(key) unless key.is_a?(Numeric) or key.is_a?(Array) return key.any?{|k| trigger?(k)} if key.is_a?(Array) Flags[key] ? Flags[key] == 0 : press?(key) end #-------------------------------------------------------------------------- # ● 判断对应的键是否重复被按下 #-------------------------------------------------------------------------- def self.repeat?(key) key = get_key(key) unless key.is_a?(Numeric) or key.is_a?(Array) return key.any?{|k| repeat?(k)} if key.is_a?(Array) Flags[key] ? (Flags[key] == 0 or Flags[key] >= REPEAT_DELAY and (Flags[key] - REPEAT_DELAY) % REPEAT_SPEED == 0) : press?(key) end #-------------------------------------------------------------------------- # ● 键盘状态判断 #-------------------------------------------------------------------------- def self.lock?(key); GetKeyState.call(key) & 1 == 1; end def self.caps_lock?; lock?(CAPS_LOCK); end def self.num_lock?; lock?(NUM_LOCK); end def self.scroll_lock?; lock?(SCROLL_LOCK); end #-------------------------------------------------------------------------- # ● 修饰键判断 #-------------------------------------------------------------------------- def self.shift?; press?([SHIFT_KEY, L_SHIFT, R_SHIFT]); end def self.ctrl?; press?([CONTROL_KEY, L_CTRL, R_CTRL]); end def self.alt?; press?([ALT_KEY, L_ALT, R_ALT]); end def self.win?; press?([L_WIN, R_WIN]); end #-------------------------------------------------------------------------- # ● 当前按下的键名 #-------------------------------------------------------------------------- def self.key_code a = ANY_KEY.select{|key| repeat?(key)} a.empty? ? 0 : a[0] end #-------------------------------------------------------------------------- # ● 当前输入的字符 #-------------------------------------------------------------------------- def self.type_char @keychar ||= key2char(key_code, shift?, caps_lock?, num_lock?) end #-------------------------------------------------------------------------- # ● 打字中判定 #-------------------------------------------------------------------------- def self.typing? not type_char.empty? end #-------------------------------------------------------------------------- # ● 根据字符或符号取得键名 #-------------------------------------------------------------------------- def self.get_key(key) if key.is_a?(Symbol) const_get(key) rescue NONE elsif key.is_a?(String) char2key(key) end end #-------------------------------------------------------------------------- # ● 将按键转化为字符 #-------------------------------------------------------------------------- def self.key2char(code, shift = false, caps = false, num = true) case code when NONE "" when BACKSPACE..ENTER, ESCAPE, SPACE code.chr when D0..D9 shift ? ")!@#\$%^&*("[code - D0].chr : code.chr when A..Z shift ^ caps ? code.chr : (code + 32).chr when NUM0..NUM9 num ? (code - 48).chr : "" when MULTIPLY..DIVIDE (num || code != DECIMAL) ? "*+,-./"[code - 106].chr : "" when SEMICOLON..TILDE ";:=+,<-_.>/?`~"[(code - SEMICOLON << 1) + (shift ? 1 : 0)].chr when L_BRACE..QUOTE "[{\\|]}\'\""[(code - L_BRACE << 1) + (shift ? 1 : 0)].chr else "" end end #-------------------------------------------------------------------------- # ● 将字符转化为按键 #-------------------------------------------------------------------------- def self.char2key(char) return NONE if char.empty? case char[0] when 8..13, 27, 32, 48..57, 65..90 char[0] when 97..122 char[0] - 32 else pindex = ")!@#\$%^&*(".index(char[0]) return D0 + pindex if pindex pindex = ";:=+,<-_.>/?`~".index(char[0]) return SEMICOLON + (pindex >> 1) if pindex pindex = "[{\\|]}\'\"".index(char[0]) return L_BRACE + (pindex >> 1) if pindex NONE end end end #============================================================================== # ■ Input 模块的注入 #============================================================================== module Input unless method_defined?(:sailcat_kb_update) alias sailcat_kb_update update def update sailcat_kb_update Keyboard.update end end end
#==============================================================================
# ■ [Keyboard Indie] 全键盘处理核心 v1.1 by SailCat
#------------------------------------------------------------------------------
# 方法:本脚本插入Main之前使用
# 依赖:无
# 版本:v1.1 (Build 220224)
# 效果:
# 1. 全键盘按键响应
# 2. 注入Input模块的update处理
# 3. Lock键、Shift/Ctrl/Alt/Win键状态的响应
# 4. 获得输入的字符
# 配置:重复延迟和重复间隔速率
# 冲突:其他类似脚本
# 说明:
# 1. 调用全键盘方法为Keyboard.press?(键名常量、符号或字符)。
# 2. 上述press?也可替换为trigger?或repeat?,含义与Input中的同名方法相同。
# 3. 其他检测包括对于Lock键的状态,Shift/Ctrl/Alt/Win的状态检测等。
# 4. 使用Keyboard.type_char可以获得打字键入的字符。
#==============================================================================
#==============================================================================
# ■ SailCat's 插件公用
#==============================================================================
module SailCat
#--------------------------------------------------------------------------
# ● 脚本配置区
#--------------------------------------------------------------------------
module Keyboard_Config
REPEAT_DELAY = 8 # 首次重复前的延迟值(帧)
REPEAT_SPEED = 4 # 每次重复按键的间隔(帧),越大越慢
#--------------------------------------------------------------------------
# ● 配置检查,请勿更改
#--------------------------------------------------------------------------
raise "重复按键的间隔不能低于1帧" unless REPEAT_SPEED > 0
end
end
#==============================================================================
# ■ 全键盘处理核心
#==============================================================================
module Keyboard
include SailCat::Keyboard_Config
#--------------------------------------------------------------------------
# ● 常量
#--------------------------------------------------------------------------
NONE = 0
L_BUTTON, R_BUTTON, CANCEL, M_BUTTON, X_BUTTON1, X_BUTTON2 = *1..6
BACKSPACE, TAB, LINE_FEED, V_TAB, CLEAR, ENTER = *8..13
SHIFT_KEY, CONTROL_KEY, ALT_KEY, PAUSE_KEY = *16..19
CAPS_LOCK, KANA_MODE, JUNJA_MODE, DUMMY, FINAL_MODE, KANJI_MODE = *20..25
ESCAPE, IME_CONVERT, IME_NONCONVERT, IME_ACCEPT, IME_MODECHANGE = *27..31
SPACE, PAGEUP, PAGEDOWN, ENDKEY, HOME, LEFT, UP, RIGHT, DOWN = *32..40
SELECT, PRINT, EXECUTE, PRINTSCREEN, INSERT, DELETE, HELP = *41..47
D0, D1, D2, D3, D4, D5, D6, D7, D8, D9 = *48..57
A, B, C, D, E, F, G, H, I, J, K, L, M = *65..77
N, O, P, Q, R, S, T, U, V, W, X, Y, Z = *78..90
LWIN, RWIN, APPS, SLEEP = 91, 92, 93, 95
NUM0, NUM1, NUM2, NUM3, NUM4, NUM5, NUM6, NUM7, NUM8, NUM9 = *96..105
MULTIPLY, ADD, SEPARATOR, SUBTRACT, DECIMAL, DIVIDE = *106..111
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12 = *112..123
F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24 = *124..135
NUM_LOCK, SCROLL_LOCK = 144, 145
L_SHIFT, R_SHIFT, L_CTRL, R_CTRL, L_ALT, R_ALT = *160..165
B_BACK, B_FORWARD, B_REFRESH, B_STOP, B_SEARCH, B_FAVOR, B_HOME = *166..172
VOL_MUTE, VOL_DOWN, VOL_UP = *173..175
MEDIA_NEXT, MEDIA_PREVIOUS, MEDIA_STOP, MEDIA_PLAYPAUSE = *176..179
LAUNCH_MAIL, SELECT_MEDIA, LAUNCH_APP1, LAUNCH_APP2 = *180..183
SEMICOLON, PLUS, COMMA, MINUS, PERIOD, QUESTION, TILDE = *186..192
L_BRACE, PIPE, R_BRACE, QUOTE, OEM8 = *219..223
BACKSLASH, PROCESS_KEY, PACKET = 226, 229, 231
ATTN, CRSEL, EXSEL, ERASE_EOF, PLAY, ZOOM, NONAME, PA1, OEM_CLEAR = *246..254
ANY_BUTTON = [1, 2, 4, 5, 6]
ANY_KEY = [8..13, 27, 32..57, 65..90, 96..135, 186..192, 219..223].map do |x|
x.to_a
end.flatten
#--------------------------------------------------------------------------
# ● API
#--------------------------------------------------------------------------
GetAsyncKeyState = Win32API.new("user32", "GetAsyncKeyState", "i", "i")
GetKeyState = Win32API.new("user32", "GetKeyState", "i", "i")
#--------------------------------------------------------------------------
# ● 用于检测重复按键的标记器
#--------------------------------------------------------------------------
Flags = {}
#--------------------------------------------------------------------------
# ● 更新键盘输入,该方法每帧调用1次
#--------------------------------------------------------------------------
def self.update
@keychar = nil
Flags.each_key do |k|
GetAsyncKeyState.call(k) & 32768 != 0 ? Flags[k] += 1 : Flags.delete(k)
end
end
#--------------------------------------------------------------------------
# ● 判断对应的键是否现在被按下
#--------------------------------------------------------------------------
def self.press?(key)
key = get_key(key) unless key.is_a?(Numeric) or key.is_a?(Array)
return key.any?{|k| press?(k)} if key.is_a?(Array)
GetAsyncKeyState.call(key) & 32768 != 0 ? (Flags[key] ||= 0; true) : false
end
#--------------------------------------------------------------------------
# ● 判断对应的键是否重新被按下
#--------------------------------------------------------------------------
def self.trigger?(key)
key = get_key(key) unless key.is_a?(Numeric) or key.is_a?(Array)
return key.any?{|k| trigger?(k)} if key.is_a?(Array)
Flags[key] ? Flags[key] == 0 : press?(key)
end
#--------------------------------------------------------------------------
# ● 判断对应的键是否重复被按下
#--------------------------------------------------------------------------
def self.repeat?(key)
key = get_key(key) unless key.is_a?(Numeric) or key.is_a?(Array)
return key.any?{|k| repeat?(k)} if key.is_a?(Array)
Flags[key] ? (Flags[key] == 0 or Flags[key] >= REPEAT_DELAY and
(Flags[key] - REPEAT_DELAY) % REPEAT_SPEED == 0) : press?(key)
end
#--------------------------------------------------------------------------
# ● 键盘状态判断
#--------------------------------------------------------------------------
def self.lock?(key); GetKeyState.call(key) & 1 == 1; end
def self.caps_lock?; lock?(CAPS_LOCK); end
def self.num_lock?; lock?(NUM_LOCK); end
def self.scroll_lock?; lock?(SCROLL_LOCK); end
#--------------------------------------------------------------------------
# ● 修饰键判断
#--------------------------------------------------------------------------
def self.shift?; press?([SHIFT_KEY, L_SHIFT, R_SHIFT]); end
def self.ctrl?; press?([CONTROL_KEY, L_CTRL, R_CTRL]); end
def self.alt?; press?([ALT_KEY, L_ALT, R_ALT]); end
def self.win?; press?([L_WIN, R_WIN]); end
#--------------------------------------------------------------------------
# ● 当前按下的键名
#--------------------------------------------------------------------------
def self.key_code
a = ANY_KEY.select{|key| repeat?(key)}
a.empty? ? 0 : a[0]
end
#--------------------------------------------------------------------------
# ● 当前输入的字符
#--------------------------------------------------------------------------
def self.type_char
@keychar ||= key2char(key_code, shift?, caps_lock?, num_lock?)
end
#--------------------------------------------------------------------------
# ● 打字中判定
#--------------------------------------------------------------------------
def self.typing?
not type_char.empty?
end
#--------------------------------------------------------------------------
# ● 根据字符或符号取得键名
#--------------------------------------------------------------------------
def self.get_key(key)
if key.is_a?(Symbol)
const_get(key) rescue NONE
elsif key.is_a?(String)
char2key(key)
end
end
#--------------------------------------------------------------------------
# ● 将按键转化为字符
#--------------------------------------------------------------------------
def self.key2char(code, shift = false, caps = false, num = true)
case code
when NONE
""
when BACKSPACE..ENTER, ESCAPE, SPACE
code.chr
when D0..D9
shift ? ")!@#\$%^&*("[code - D0].chr : code.chr
when A..Z
shift ^ caps ? code.chr : (code + 32).chr
when NUM0..NUM9
num ? (code - 48).chr : ""
when MULTIPLY..DIVIDE
(num || code != DECIMAL) ? "*+,-./"[code - 106].chr : ""
when SEMICOLON..TILDE
";:=+,<-_.>/?`~"[(code - SEMICOLON << 1) + (shift ? 1 : 0)].chr
when L_BRACE..QUOTE
"[{\\|]}\'\""[(code - L_BRACE << 1) + (shift ? 1 : 0)].chr
else
""
end
end
#--------------------------------------------------------------------------
# ● 将字符转化为按键
#--------------------------------------------------------------------------
def self.char2key(char)
return NONE if char.empty?
case char[0]
when 8..13, 27, 32, 48..57, 65..90
char[0]
when 97..122
char[0] - 32
else
pindex = ")!@#\$%^&*(".index(char[0])
return D0 + pindex if pindex
pindex = ";:=+,<-_.>/?`~".index(char[0])
return SEMICOLON + (pindex >> 1) if pindex
pindex = "[{\\|]}\'\"".index(char[0])
return L_BRACE + (pindex >> 1) if pindex
NONE
end
end
end
#==============================================================================
# ■ Input 模块的注入
#==============================================================================
module Input
unless method_defined?(:sailcat_kb_update)
alias sailcat_kb_update update
def update
sailcat_kb_update
Keyboard.update
end
end
end
|
|