| 赞 | 2 |
| VIP | |
| 好人卡 | |
| 积分 | 1 |
| 经验 | |
| 最后登录 | 2020-7-27 |
| 在线时间 | 1379 小时 |
- 梦石
- 0
- 星屑
- 76
- 在线时间
- 1379 小时
- 注册时间
- 2012-7-5
- 回帖
- 1643

|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有账号?注册会员
×
本帖最后由 kuerlulu 于 2016-6-8 16:43 编辑
Input:
author: 余烬之中
change: 1.修正 bitween 拼写错误; 2. key_type 判定微调; 3.重写 Mouse 并独立在外
Mouse:
(可选) 最后一段 alias 如果不希望和 Input 绑定在一起可以删去, Mouse 可单独使用
(为什么是"真")
之前能找到的窗口拖动的实现都建立在鼠标在窗口内, 换句话说鼠标一旦移出窗口就会判定异常, 本脚本修正了这一点
[fold=Mouse][pre lang="ruby" line="0"]
#==============================================================================
# ■ M3L::Mouse
#------------------------------------------------------------------------------
# Module for processing mouse input.
# EXAMPLE for dragging:
# update: M3L::Mouse[self] = [x, y] if M3L::Mouse.down_in? rect
# self.x = M3L::Mouse.dx self if M3L::Mouse.dref self
# self.y = M3L::Mouse.dy self if M3L::Mouse.dref self
# PS: `dx' means "dragging x" :P
#==============================================================================
M3L = Module.new unless defined? M3L
module M3L::Mouse
#--------------------------------------------------------------------------
# ● Data
#--------------------------------------------------------------------------
Data = {
:position => [0, 0],
:last_pos => [0, 0],
:dump_pos => [0, 0],
:left => [0, 0],
:middle => [0, 0],
:right => [0, 0],
:timer => 0
}
Drag = {}
#--------------------------------------------------------------------------
# ● Win32API
#--------------------------------------------------------------------------
GetCursorPos = Win32API.new("user32", "GetCursorPos" , "p" , "i")
ScreenToClient = Win32API.new("user32", "ScreenToClient" , "pp", "i")
GetActiveWindow = Win32API.new("user32", "GetActiveWindow" , "" , "i")
GetAsyncKeyState = Win32API.new("user32", "GetAsyncKeyState", "i" , "i")
ShowCursor = Win32API.new("user32", "ShowCursor" , "i" , "i")
#============================================================================
# ● MouseAPI
#============================================================================
class << self
def _hwnd
(
defined? @hWnd) ? @hWnd : (
defined? hwnd) ? (@hWnd = hwnd) : (
@hWnd = GetActiveWindow.call
)
end
def _pos
GetCursorPos.call buffer = "\0" * 8
ScreenToClient.call _hwnd, buffer
buffer.unpack "ll"
end
def _press? button
GetAsyncKeyState.call(button).abs & 0x8000 == 0x8000
end
def dump_button key, b
Data[key][1] = Data[key][0]
Data[key][0] = (_press? b) ? Data[key][0] + 1 : 0
end
private :_hwnd, :_press?, :_pos, :dump_button
#--------------------------------------------------------------------------
# ● Update Data
#--------------------------------------------------------------------------
def update
Data[:last_pos] = Data[:position]
Data[:position] = _pos
Data[:timer] = Data[:last_pos] == Data[:position] ? Data[:timer] + 1 : 0
dump_button :left , 0b001
dump_button :right , 0b010
dump_button :middle, 0b100
Data[:dump_pos] = Data[:position] if down_left?
Drag.clear if !Drag.empty? and left == 0
end
#--------------------------------------------------------------------------
# ● Shotcuts
#--------------------------------------------------------------------------
def pos ; Data[:position] ; end
def timer ; Data[:timer] ; end
def left ; Data[:left][0] ; end
def right ; Data[:right][0] ; end
def middle ; Data[:middle][0] ; end
def moving? ; Data[:timer] == 0 ; end
def down_left? ; Data[:left][1] == 0 && Data[:left][0] != 0; end
def down_right? ; Data[:right][1] == 0 && Data[:right][0] != 0; end
def down_middle?; Data[:middle][1] == 0 && Data[:middle][0] != 0; end
def hold_left? ; Data[:left][1] != 0 && Data[:left][0] != 0; end
def hold_right? ; Data[:right][1] != 0 && Data[:right][0] != 0; end
def hold_middle?; Data[:middle][1] != 0 && Data[:middle][0] != 0; end
def up_left? ; Data[:left][1] != 0 && Data[:left][0] == 0; end
def up_right? ; Data[:right][1] != 0 && Data[:right][0] == 0; end
def up_middle?; Data[:middle][1] != 0 && Data[:middle][0] == 0; end
def hold? ; hold_left? || hold_right? || hold_middle? ; end
def down? ; down_left? || down_right? || down_middle? ; end
def up_all? ; up_left? && up_right? && up_middle? ; end
alias time timer
alias dragging? hold_left?
alias click? up_left?
alias right_click? up_right?
#--------------------------------------------------------------------------
# ● Show/Hide the real mouse cursor
#--------------------------------------------------------------------------
def hide; ShowCursor.call(0); end
def show; ShowCursor.call(1); end
#--------------------------------------------------------------------------
# ● Regist/Change infos in Drag
#--------------------------------------------------------------------------
def dref k, v = nil
v ? (Drag[k] = v) : Drag[k]
end
alias [] dref
alias []= dref
#--------------------------------------------------------------------------
# ● Judge whether pos in rect
#--------------------------------------------------------------------------
def area? *args
args = args.flatten
case args.size
when 1
x, y, w, h = args[0].x, args[0].y, args[0].width, args[0].height
when 4
x, y, w, h = *args
else
raise "Invalid argument: " + args.inspect
end
pos[0].between?(x, x + w) && pos[1].between?(y, y + h)
end
alias rect? area?
#--------------------------------------------------------------------------
# ● Judge down_left? with pos in rect
#--------------------------------------------------------------------------
def down_in? *args
down_left? && area?(*args)
end
#--------------------------------------------------------------------------
# ● Get dragging position for sym (see EXAMPLE for dragging)
# return nil if not found Drag[sym]
#--------------------------------------------------------------------------
def dx sym
x = dref sym
x ? x[0] + Data[:position][0] - Data[:dump_pos][0] : ()
end
def dy sym
x = dref sym
x ? x[1] + Data[:position][1] - Data[:dump_pos][1] : ()
end
end
end
#==============================================================================
# ■ Mouse = M3L::Mouse
#==============================================================================
unless defined? Mouse
Mouse = M3L::Mouse
class << Input
alias m3l_mouse_update update
def update
m3l_mouse_update
Mouse.update
end
end
end
=begin # hhhh..
class Window_Base
alias _update update
def update
_update
M3L::Mouse[self] = [x, y] if M3L::Mouse.down_in?(x, y, width, height)
self.x = M3L::Mouse.dx(self) if M3L::Mouse.dref self
self.y = M3L::Mouse.dy(self) if M3L::Mouse.dref self
end
end
=end
[/pre][/fold]
[fold=浴巾的Input][pre lang="ruby" line="0"]
#==============================================================================
# ■ Input
#------------------------------------------------------------------------------
# 处理键盘输入信息的模块。
#==============================================================================
module Input
#--------------------------------------------------------------------------
# ● 常量
#--------------------------------------------------------------------------
DOWN=[0x28,0x62];LEFT=[0x25,0x64];RIGHT=[0x27,0x66];UP=[0x26,0x68]
A=[0x5A,0x10];B=[0x58,0x1B,0x60];C=[0x20,0x0D,0x43]
X = 0x41; Y = 0x53; Z = 0x44; L = 0x51; R = 0x57
F5 = 0x74; F6 = 0x75; F7 = 0x76; F8 = 0x77; F9 = 0x78
LETTERS = {
'A' => 0x41, 'B' => 0x42, 'C' => 0x43, 'D' => 0x44, 'E' => 0x45,
'F' => 0x46, 'G' => 0x47, 'H' => 0x48, 'I' => 0x49, 'J' => 0x4A,
'K' => 0x4B, 'L' => 0x4C, 'M' => 0x4D, 'N' => 0x4E, 'O' => 0x4F,
'P' => 0x50, 'Q' => 0x51, 'R' => 0x52, 'S' => 0x53, 'T' => 0x54,
'U' => 0x55, 'V' => 0x56, 'W' => 0x57, 'X' => 0x58, 'Y' => 0x59,
'Z' => 0x5A
}
# 0 1 2 3 4 5 6 7 8 9
NUMBERS = [0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39]
NUMPAD = [0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69]
# * + - /
Multiply = 0x6A; Add = 0x6B; Subtract = 0x6D; Divide = 0x6F;
# , .
Separator = 0x6C; Decimal = 0x6E;
# ; = , - .
SCOLON = 186; EQUALS = 187; COMMA = 188; USCORE = 189; PERIOD = 190;
# / ` [ \ ]
SLASH = 191; TILDE = 192; LBRACE = 219; BSLASH = 220; RBRACE = 221;
# '
QUOTE = 222;
# ENDK for END!
BACKSPACE = 0x08; TAB = 0x09; ENTER = 0x0D; SHIFT = 0x10;
CTRL = 0x11; ALT = 0x12; PAUSE = 0x13; CAPSLOCK = 0x14;
ESC = 0x1B; SPACEBAR = 0x20; PAGEUP = 0x21; PAGEDOWN = 0x22;
ENDK = 0x23; HOME = 0x24; LEFTARROW = 0x25; UPARROW = 0x26;
RIGHTARROW = 0x27; DOWNARROW = 0x28; SELECT = 0x29; PRINT = 0x2A;
PRINTSCREEN = 0x2C; INS = 0x2D; DEL = 0x2E; NUMLOCK = 0x90;
SCROLLLOCK = 0x91; LeftSHIFT = 0xA0; RightSHIFT = 0xA1; LeftCONTROL = 0xA2;
RightCONTROL = 0xA3; LeftALT = 0xA4; RightALT = 0xA5; LeftWin = 0x5B;
RightWin = 0x5C; App = 0x5D;
# nil, F1, F2 F3, F4, F5, F6, F7, F8, F9, F10, F11, F12
F = [nil,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B]
KeyRepeatCounter = {}
# APIs
GetAsyncKeyState = _api "user32|GetAsyncKeyState|i|i"
GetKeyState = _api "user32|GetKeyState|i|i"
class << self
def update
KeyRepeatCounter.each_key do |key|
if GetAsyncKeyState.call(key).abs & 0x8000 == 0x8000
KeyRepeatCounter[key] += 1
else
KeyRepeatCounter.delete(key)
end
end
end
def press? key
if key.is_a? String
return string_key(key, :press?)
elsif key.is_a? Symbol
return string_key(key.to_s, :press?)
elsif key.is_a? Array
return key.any?{|k| press? k }
end
return true unless KeyRepeatCounter[key].nil?
return _press? key
end
def trigger? key
if key.is_a? String
return string_key(key, :trigger?)
elsif key.is_a? Symbol
return string_key(key.to_s, :trigger?)
elsif key.is_a? Array
return key.any?{|k| trigger? k }
end
count = KeyRepeatCounter[key]
return count == 0 || (count.nil? ? _press?(key) : false)
end
def repeat? key
if key.is_a? String
return string_key(key, :repeat?)
elsif key.is_a? Symbol
return string_key(key.to_s, :repeat?)
elsif key.is_a? Array
return key.any?{|k| repeat? k }
end
count = KeyRepeatCounter[key]
return true if count == 0
return count.nil? ? _press?(key) : count >= 23 && (count - 23) % 6 == 0
end
def _press? key
if GetAsyncKeyState.call(key).abs & 0x8000 == 0x8000
KeyRepeatCounter[key] = 0
return true
end
return false
end
def string_key key, sym
if 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.include? key
method(sym).call LETTERS[key]
elsif '0123456789'.include? key
method(sym).call(NUMBERS[key.to_i]) || method(sym).call(NUMPAD[key.to_i])
else
case key.downcase
when '*'; method(sym).call Multiply
when '+'; method(sym).call(Add) || method(sym).call(EQUALS)
when '-'; method(sym).call(Subtract) || method(sym).call(USCORE)
when '/'; method(sym).call(Divide) || method(sym).call(SLASH)
when ','; method(sym).call(Separator) || method(sym).call(COMMA)
when '.'; method(sym).call(Decimal) || method(sym).call(PERIOD)
when '<'; method(sym).call COMMA
when '>'; method(sym).call PERIOD
when '?'; method(sym).call SLASH
when ';' , ':'; method(sym).call SCOLON
when '\'', '"'; method(sym).call QUOTE
when '[' , '{'; method(sym).call LBRACE
when ']' , '}'; method(sym).call RBRACE
when '`' , '~'; method(sym).call TILDE
when '\\', '|'; method(sym).call BSLASH
when '!'; method(sym).call NUMBERS[1]
when '@'; method(sym).call NUMBERS[2]
when '#'; method(sym).call NUMBERS[3]
when '$'; method(sym).call NUMBERS[4]
when '%'; method(sym).call NUMBERS[5]
when '^'; method(sym).call NUMBERS[6]
when '&'; method(sym).call NUMBERS[7]
when '*'; method(sym).call NUMBERS[8]
when '('; method(sym).call NUMBERS[9]
when ')'; method(sym).call NUMBERS[0]
when '_'; method(sym).call USCORE
when '='; method(sym).call EQUALS
when 'shift' ; method(sym).call SHIFT
when 'lshift' ; method(sym).call LeftSHIFT
when 'rshift' ; method(sym).call RightSHIFT
when 'ctrl' ; method(sym).call CTRL
when 'lctrl' ; method(sym).call LeftCTRL
when 'rctrl' ; method(sym).call RightCTRL
when 'alt' ; method(sym).call ALT
when 'lalt' ; method(sym).call LeftALT
when 'ralt' ; method(sym).call RightALT
when 'app' ; method(sym).call App
when 'tab' ; method(sym).call TAB
when 'capslock' ; method(sym).call CAPSLOCK
when 'numlock' ; method(sym).call NUMLOCK
when 'scrolllock' ; method(sym).call SCROLLLOCK
when 'enter' ; method(sym).call ENTER
when 'backspace' ; method(sym).call BACKSPACE
when 'space' ; method(sym).call SPACEBAR
when 'ins' ; method(sym).call INS
when 'del' ; method(sym).call DEL
when 'home' ; method(sym).call HOME
when 'end' ; method(sym).call ENDK
when 'pageup' ; method(sym).call PAGEUP
when 'pagedown' ; method(sym).call PAGEDOWN
when 'esc' ; method(sym).call ESC
when 'uparrow' ; method(sym).call UPARROW
when 'downarrow' ; method(sym).call DOWNARROW
when 'leftarrow' ; method(sym).call LEFTARROW
when 'rightarrow' ; method(sym).call RIGHTARROW
when 'printscreen'; method(sym).call PRINTSCREEN
when 'select' ; method(sym).call SELECT
when 'print' ; method(sym).call PRINT
when 'lwin' ; method(sym).call LeftWin
when 'rwin' ; method(sym).call RightWin
when 'win'; method(sym).call(LeftWin) || method(sym).call(RightWin)
else; key == key.slice(0, 1) ? false : string_key(key.slice(0, 1), sym)
end
end
end
def typing?
repeat?(SPACEBAR) || LETTERS.any?{|l, c| repeat? c } ||
NUMBERS.any?{|n| repeat? n } || NUMPAD.any?{|n| repeat? n } ||
repeat?(Multiply) || repeat?(Decimal)|| repeat?(Divide)|| repeat?(COMMA) ||
repeat?(Separator)|| repeat?(Add) || repeat?(EQUALS)|| repeat?(SLASH) ||
repeat?(SCOLON) || repeat?(USCORE) || repeat?(PERIOD)|| repeat?(TILDE) ||
repeat?(Subtract) || repeat?(LBRACE) || repeat?(BSLASH)|| repeat?(RBRACE)||
repeat?(QUOTE)
end
def key_type
return " " if repeat? SPACEBAR
LETTERS.each{|l, c| return upcase? ? l.upcase : l.downcase if repeat? c }
NUMPAD.each_with_index{|n, i| return i.to_s if repeat? n }
if press? SHIFT
NUMBERS.each_with_index do |n, i|
next unless repeat? n
case i
when 1; return "!"
when 2; return "@"
when 3; return "#"
when 4; return "$"
when 5; return "%"
when 6; return "^"
when 7; return "&"
when 8; return "*"
when 9; return "("
when 0; return ")"
end
end
else
NUMBERS.each_with_index{|n, i| return i.to_s if repeat? n }
end
return "*" if repeat? Multiply
return "+" if repeat? Add
return "-" if repeat? Subtract
return "/" if repeat? Divide
return "," if repeat? Separator
return "." if repeat? Decimal
return press?(SHIFT) ? ":" : ";" if repeat? SCOLON
return press?(SHIFT) ? "+" : "=" if repeat? EQUALS
return press?(SHIFT) ? "<" : "," if repeat? COMMA
return press?(SHIFT) ? "_" : "-" if repeat? USCORE
return press?(SHIFT) ? ">" : "." if repeat? PERIOD
return press?(SHIFT) ? "?" : "/" if repeat? SLASH
return press?(SHIFT) ? "~" : "`" if repeat? TILDE
return press?(SHIFT) ? "{" : "[" if repeat? LBRACE
return press?(SHIFT) ? "|" : "\\" if repeat? BSLASH
return press?(SHIFT) ? "}" : "]" if repeat? RBRACE
return press?(SHIFT) ? '"' : "'" if repeat? QUOTE
return ""
end
def upcase?
return press?(SHIFT) != (GetKeyState.call(CAPSLOCK) == 1)
end
private :_press?, :upcase?
end
end
[/pre][/fold] |
评分
-
查看全部评分
|