#encoding:utf-8
#==============================================================================
# ■ Input
#------------------------------------------------------------------------------
# 本模組處理鍵盤數入信息。
#==============================================================================
$GetAsyncKeyState = Win32API.new("user32","GetAsyncKeyState",'I','I')
module Input
KEY = {
"L_Mouse" => 1, # 0b00000001 0o001 0x01 Left mouse button
"R_Mouse" => 2, # 0b00000010 0o002 0x02 Right mouse button
"M_Mouse" => 4, # 0b00000100 0o004 0x04 Middle mouse button
"BackSpace" => 8, # 0b00001000 0o010 0x08 BACKSPACE key
"Tab" => 9, # 0b00001001 0o011 0x09 TAB key
"Enter" => 13, # 0b00001101 0o015 0x0d ENTER key
"Shift" => 16, # 0b00010000 0o020 0x10 SHIFT key
"Ctrl" => 17, # 0b00010001 0o021 0x11 CTLR key
"Alt" => 18, # 0b00010010 0o022 0x12 ALT key
"PauseBreak" => 19, # 0b00010011 0o023 0x13 PAUSE BREAK key
"CapsLock" => 20, # 0b00010100 0o024 0x14 CAPS LOCK key
"Esc" => 27, # 0b00011011 0o033 0x1b ESC key
"Space" => 32, # 0b00100000 0o040 0x20 SPACE key
"PageUp" => 33, # 0b00100001 0o041 0x21 PAGE UP key
"PageDown" => 34, # 0b00100010 0o042 0x22 PAGE DOWN key
"End" => 35, # 0b00100011 0o043 0x23 END key
"Home" => 36, # 0b00100100 0o044 0x24 HOME key
"Left" => 37, # 0b00100101 0o045 0x25 LEFT key
"Up" => 38, # 0b00100110 0o046 0x26 UP key
"Right" => 39, # 0b00100111 0o047 0x27 RIGHT key
"Down" => 40, # 0b00101000 0o050 0x28 DOWN key
"PrintSceenSysRq" => 44, # 0b00101100 0o054 0x2c PRINT SCEEN SYS RQ key
"Insert" => 45, # 0b00101101 0o055 0x2d INSERT key
"Delete" => 46, # 0b00101110 0o056 0x2e DELETE key
"0" => 48, # 0b00110000 0o060 0x30 0 key
"1" => 49, # 0b00110001 0o061 0x31 1 key
"2" => 50, # 0b00110010 0o062 0x32 2 key
"3" => 51, # 0b00110011 0o063 0x33 3 key
"4" => 52, # 0b00110100 0o064 0x34 4 key
"5" => 53, # 0b00110101 0o065 0x35 5 key
"6" => 54, # 0b00110110 0o066 0x36 6 key
"7" => 55, # 0b00110111 0o067 0x37 7 key
"8" => 56, # 0b00111000 0o070 0x38 8 key
"9" => 57, # 0b00111001 0o071 0x39 9 key
"A" => 65, # 0b01000001 0o101 0x41 A key
"B" => 66, # 0b01000010 0o102 0x42 B key
"C" => 67, # 0b01000011 0o103 0x43 C key
"D" => 68, # 0b01000100 0o104 0x44 D key
"E" => 69, # 0b01000101 0o105 0x45 E key
"F" => 70, # 0b01000110 0o106 0x46 F key
"G" => 71, # 0b01000111 0o107 0x47 G key
"H" => 72, # 0b01001000 0o110 0x48 H key
"I" => 73, # 0b01001001 0o111 0x49 I key
"J" => 74, # 0b01001010 0o112 0x4a J key
"K" => 75, # 0b01001011 0o113 0x4b K key
"L" => 76, # 0b01001100 0o114 0x4c L key
"M" => 77, # 0b01001101 0o115 0x4d M key
"N" => 78, # 0b01001110 0o116 0x4e N key
"O" => 79, # 0b01001111 0o117 0x4f O key
"P" => 80, # 0b01010000 0o120 0x50 P key
"Q" => 81, # 0b01010001 0o121 0x51 Q key
"R" => 82, # 0b01010010 0o122 0x52 R key
"S" => 83, # 0b01010011 0o123 0x53 S key
"T" => 84, # 0b01010100 0o124 0x54 T key
"U" => 85, # 0b01010101 0o125 0x55 U key
"V" => 86, # 0b01010110 0o126 0x56 V key
"W" => 87, # 0b01010111 0o127 0x57 W key
"X" => 88, # 0b01011000 0o130 0x58 X key
"Y" => 89, # 0b01011001 0o131 0x59 Y key
"Z" => 90, # 0b01011010 0o132 0x5a Z key
"L_Window" => 91, # 0b01011011 0o133 0x5b Left WINDOWS key
"R_Window" => 92, # 0b01011100 0o134 0x5c Right WINDOWS key
"Applications" => 93, # 0b01011101 0o135 0x5d APPLICATIONS key
"Num0" => 96, # 0b01100000 0o140 0x60 NUMERIC KEYPAD 0 key
"Num1" => 97, # 0b01100001 0o141 0x61 NUMERIC KEYPAD 1 key
"Num2" => 98, # 0b01100010 0o142 0x62 NUMERIC KEYPAD 2 key
"Num3" => 99, # 0b01100011 0o143 0x63 NUMERIC KEYPAD 3 key
"Num4" => 100, # 0b01100100 0o144 0x64 NUMERIC KEYPAD 4 key
"Num5" => 101, # 0b01100101 0o145 0x65 NUMERIC KEYPAD 5 key
"Num6" => 102, # 0b01100110 0o146 0x66 NUMERIC KEYPAD 6 key
"Num7" => 103, # 0b01100111 0o147 0x67 NUMERIC KEYPAD 7 key
"Num8" => 104, # 0b01101000 0o150 0x68 NUMERIC KEYPAD 8 key
"Num9" => 105, # 0b01101001 0o151 0x69 NUMERIC KEYPAD 9 key
"NumMultiplication" => 106, # 0b01101010 0o152 0x6a NUMERIC KEYPAD * key
"NumPlus" => 107, # 0b01101011 0o153 0x6b NUMERIC KEYPAD + key
"NumSubtraction" => 109, # 0b01101100 0o155 0x6d NUMERIC KEYPAD - key
"NumDot" => 110, # 0b01101101 0o156 0x6e NUMERIC KEYPAD . key
"NumDivide" => 111, # 0b01101111 0o157 0x6f NUMERIC KEYPAD / key
"F1" => 112, # 0b01110000 0o160 0x70 F1 key
"F2" => 113, # 0b01110001 0o161 0x71 F2 key
"F3" => 114, # 0b01110010 0o162 0x72 F3 key
"F4" => 115, # 0b01110011 0o163 0x73 F4 key
"F5" => 116, # 0b01110100 0o164 0x74 F5 key
"F6" => 117, # 0b01110101 0o165 0x75 F6 key
"F7" => 118, # 0b01110110 0o166 0x76 F7 key
"F8" => 119, # 0b01110111 0o167 0x77 F8 key
"F9" => 120, # 0b01111000 0o170 0x78 F9 key
"F10" => 121, # 0b01111001 0o171 0x79 F10 key
"F11" => 122, # 0b01111010 0o172 0x7a F11 key
"F12" => 123, # 0b01111011 0o173 0x7b F12 key
"NumLock" => 144, # 0b10010000 0o220 0x90 NUM LOCK key
"ScrollLock" => 145, # 0b10010001 0o221 0x91 SCROLL LOCK key
"Semicolon" => 186, # 0b10111010 0o272 0xba ; key
"Equals" => 187, # 0b10111011 0o273 0xbb = key
"Comma" => 188, # 0b10111100 0o274 0xbc , key
"Hyphen" => 189, # 0b10111101 0o275 0xbd - key
"Dot" => 190, # 0b10111110 0o276 0xbe . key
"Slash" => 191, # 0b10111111 0o277 0xbf / key
"OpenQuote" => 192, # 0b11000000 0o300 0xc0 ` key
"OpenBracket" => 219, # 0b11011011 0o333 0xdb [ key
"Backslash" => 220, # 0b11011100 0o334 0xdc \ key
"CloseBracket" => 221, # 0b11011101 0o335 0xdd ] key
"CloseQuote" => 222} # 0b11011110 0o336 0xde ' key
@keypresstime = Array.new(223,0 - 1)
#--------------------------------------------------------------------------
# ● 更新。
#--------------------------------------------------------------------------
def self.update
for t in 1..222
if @keypresstime[t] >= 1
@keypresstime[t] = 0 if $GetAsyncKeyState.call(t) == 0
@keypresstime[t] += 1 if $GetAsyncKeyState.call(t) != 0
elsif @keypresstime[t] == 0
@keypresstime[t] += 1 if $GetAsyncKeyState.call(t) != 0
@keypresstime[t] -= 1 if $GetAsyncKeyState.call(t) == 0
else
@keypresstime[t] = 1 if $GetAsyncKeyState.call(t) != 0
end
end
end
#--------------------------------------------------------------------------
# ● 返回檢測範圍內正在按下的按鍵編號陣列。
# ‧ Arr
# =key : Ari.[ {Int.檢測按鍵} ]
# Ran.檢測範圍
#--------------------------------------------------------------------------
def self.findpress(key=1..222)
begin
raise(TypeError.new("not an Array or Range")) unless key.is_a?(Array) or key.is_a?(Range)
key.each{|x| TypeError.new("#{x} is not an Integer or String") unless x.is_a?(Integer) or x.is_a?(String) } if key.is_a?(Array)
rescue
error
end
key.find_all{|x| @keypresstime[x.is_a?(Integer) ? x : KEY[x]] >= 1 }
end
#--------------------------------------------------------------------------
# ● 返回檢測範圍內剛剛按下的按鍵編號陣列。
# ‧ Arr
# =key : Ari.[ {Int.檢測按鍵} ]
# Ran.檢測範圍
#--------------------------------------------------------------------------
def self.findtrigger(key=1..222)
begin
raise(TypeError.new("not an Array or Range")) unless key.is_a?(Array) or key.is_a?(Range)
key.each{|x| TypeError.new("#{x} is not an Integer or String") unless x.is_a?(Integer) or x.is_a?(String) } if key.is_a?(Array)
rescue
error
end
key.find_all{|x| @keypresstime[x.is_a?(Integer) ? x : KEY[x]] == 1 }
end
#--------------------------------------------------------------------------
# ● 返回檢測範圍內持續按下的按鍵編號陣列。
# ‧ Arr
# delay : Int.延遲時間
# time : Int.按下時間
# =key : Ari.[ {Int.檢測按鍵} ]
# Ran.檢測範圍
#--------------------------------------------------------------------------
def self.findrepest(delay,time,key=1..222)
begin
raise(TypeError.new("not an Array or Range")) unless key.is_a?(Array) or key.is_a?(Range)
key.each{|x| TypeError.new("#{x} is not an Integer or String") unless x.is_a?(Integer) or x.is_a?(String) } if key.is_a?(Array)
rescue
error
end
delay = time if delay <= time
key.find_all{|x| @keypresstime[x.is_a?(Integer) ? x : KEY[x]] == 1 or [@keypresstime[x] - delay,0].max % time == 1 }
end
#--------------------------------------------------------------------------
# ● 返回檢測範圍內剛剛放開的按鍵編號陣列。
# ‧ Arr
# =key : Ari.[ {Int.檢測按鍵} ]
# Ran.檢測範圍
#--------------------------------------------------------------------------
def self.findunclasp(key=1..222)
begin
raise(TypeError.new("not an Array or Range")) unless key.is_a?(Array) or key.is_a?(Range)
key.each{|x| TypeError.new("#{x} is not an Integer or String") unless x.is_a?(Integer) or x.is_a?(String) } if key.is_a?(Array)
rescue
error
end
key.find_all{|x| @keypresstime[x.is_a?(Integer) ? x : KEY[x]] == 0 }
end
#--------------------------------------------------------------------------
# ● 返回檢測按鍵是否正在按下。
# ‧ Bol
# key : Ari.[ {Int/Str.檢測按鍵} ]
# Int/Ran/Str.檢測按鍵
#--------------------------------------------------------------------------
def self.press(key)
case key.class.to_s
when "Array"
key.each do |x|
case x.class.to_s
when "Fixnum"
return false if @keypresstime[x] <= 0
when "String"
return false if @keypresstime[KEY[x]] <= 0
else
return false
end
end
true
when "Fixnum"
return @keypresstime[key] >= 1
when "Range"
key.each do |x|
return false if @keypresstime[x] <= 0
end
when "String"
return @keypresstime[KEY[key]] >= 1
else
raise(TypeError.new("not an Array, Fixnum, Range or String"))
end
end
#--------------------------------------------------------------------------
# ● 返回檢測按鍵是否剛剛按下。
# ‧ Bol
# key : Ari.[ {Int/Str.檢測按鍵} ]
# Int/Ran/Str.檢測按鍵
#--------------------------------------------------------------------------
def self.trigger(key)
case key.class.to_s
when "Array"
key.each do |x|
case x.class.to_s
when "Fixnum"
return false if @keypresstime[x] != 1
when "String"
return false if @keypresstime[KEY[x]] != 1
else
return false
end
end
return true
when "Fixnum"
return @keypresstime[key] == 1
when "Range"
key.each do |x|
return false if @keypresstime[x] != 1
end
when "String"
return @keypresstime[KEY[key]] == 1
else
raise(TypeError.new("not an Array, Fixnum, Range or String"))
end
end
#--------------------------------------------------------------------------
# ● 返回檢測按鍵是否持續按下。
# ‧ Bol
# key : Ari.[ {Int/Str.檢測按鍵} ]
# Int/Ran/Str.檢測按鍵
# delay : Int.延遲時間
# time : Int.按下時間
#--------------------------------------------------------------------------
def self.repeat(key,delay,time)
delay = time if delay <= time
case key.class.to_s
when "Array"
key.each do |x|
case x.class.to_s
when "Fixnum"
return false if @keypresstime[x] != 1 and [@keypresstime[x] - delay,0].max % time != 1
when "String"
return false if @keypresstime[KEY[x]] != 1 and [@keypresstime[KEY[x]] - delay,0].max % time != 1
else
return false
end
end
return true
when "Fixnum"
return (@keypresstime[key] == 1 or [@keypresstime[key] - delay,0].max % time == 1)
when "Range"
key.each do |x|
return false if @keypresstime[x] != 1 and [@keypresstime[x] - delay,0].max % time != 1
end
when "String"
return (@keypresstime[KEY[key]] == 1 or [@keypresstime[KEY[key]] - delay,0].max % time == 1)
else
raise(TypeError.new("not an Array, Fixnum, Range or String"))
end
end
#--------------------------------------------------------------------------
# ● 返回檢測按鍵是否剛剛放開。
# ‧ Bol
# key : Ari.[ {Int/Str.檢測按鍵} ]
# Int/Ran/Str.檢測按鍵
#--------------------------------------------------------------------------
def self.unclasp(key)
case key.class.to_s
when "Array"
key.each do |x|
case x.class.to_s
when "Fixnum"
return false if @keypresstime[x] != 0
when "String"
return false if @keypresstime[KEY[x]] != 0
else
return false
end
end
return true
when "Fixnum"
return @keypresstime[key] == 0
when "Range"
key.each do |x|
return false if @keypresstime[x] != 0
end
when "String"
return @keypresstime[KEY[key]] == 0
else
raise(TypeError.new("not an Array, Fixnum, Range or String"))
end
end
end