赞 | 12 |
VIP | 107 |
好人卡 | 6 |
积分 | 4 |
经验 | 31122 |
最后登录 | 2024-6-29 |
在线时间 | 1606 小时 |
Lv2.观梦者 傻♂逼
- 梦石
- 0
- 星屑
- 374
- 在线时间
- 1606 小时
- 注册时间
- 2007-3-13
- 帖子
- 6562
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
本帖最后由 yangff 于 2012-1-2 14:43 编辑
基本和VX鼠标统一接口了,有几个函数不是很理解就暂时没弄。。
WndProc的代码使用了@晴兰的http://rpg.blue/thread-216658-1-1.html 不过他的那段有点问题所以这里放的是修改好的。- $apicache = {}
- class String
- def apicall(*args)
- $apicache[self] = Win32API.new(*self.split("|")) unless $apicache.include? self
- $apicache[self].call(*args)
- end
- end
- class Symbol
- def method_missing(*args, &block)
- self.to_s.send(*args, &block)
- end
- end
- class Win32API
- WM_ACTIVATEAPP=0x1C
- WM_MOUSEMOVE=0x200
- WM_MOUSEWHEEL = 0x020A
- WM_LBUTTONDOWN = 0x201
- WM_RBUTTONDOWN = 0x204
- WM_MOUSEDOWN = 0x210
- WM_LBUTTONUP = 0x202
- WM_RBUTTONUP = 0x205
- WM_LBUTTONDBLCLK = 0x203
- WM_RBUTTONDBLCLK = 0x204
- end
- module Roost
- module MainWindow
- def self.getwndproc
- @wndproc
- end
- def self.setwndproc(obj)
- @wndproc=obj
- end
- def self.addwndproc(obj)
- @@wndprocs.push(obj)
- end
- @@wndprocs=[]
- @wndproc = lambda {|hwnd, msg, wp, lp|
- @@handle=false
- for i in @@wndprocs
- i.call(hwnd, msg, wp, lp)
- end
- return Roost::MainWindow.use_rm_proc(hwnd, msg, wp, lp)
- }
- def self.use_rm_proc(hwnd,msg,wp,lp)
- if (not @@handle)
- @@handle=true
- return :"user32|CallWindowProc|iiiii|i".apicall(@@oHandle,hwnd,msg,wp,lp)
- end
- end
- def self.disable_rm_proc
- @@handle=true
- end
- def self.enable
- Roost::MainWindow.instance_eval do
- def self.enable
- end
- end
- Roost::MainWindow.instance_eval do
- @msg = "\0"*24
- @hwnd = 0
- while @hwnd==0
- :"user32|GetMessage|piii|v".apicall(@msg, 0, 0, 0)
- @kmsg = @msg
- :"user32|TranslateMessage|p|v".apicall(@kmsg)
- :"user32|DispatchMessage|p|v".apicall(@kmsg)
- @hwnd = @msg.unpack("i*")[0]
- end
- @hdc = :"user32|GetDC|i|i".apicall(@hwnd)
- def self.hwnd
- return @hwnd
- end
- def self.hdc
- return @hdc
- end
-
- def self.findProc(l, n)
- lib = :"kernel32|LoadLibrary|p|i".apicall(l);
- ret = :"kernel32|GetProcAddress|ip|l".apicall(lib, n);
- :"kernel32|FreeLibrary|l|v".apicall(lib)
- return ret
- end
- def self.loadfindProc(l, n)
- lib = :"kernel32|LoadLibrary|p|i".apicall(l);
- ret = :"kernel32|GetProcAddress|ip|l".apicall(lib, n);
- return ret
- end
- def self.enableWndProc
- Roost::MainWindow.instance_eval do
- def self.enableWndProc
- end
- end
- @malloc = :"msvcrt|malloc|i|i"
- @memcpy = :"msvcrt|memcpy|ipi|v"
-
-
- sprintf = self.findProc("msvcrt", "sprintf")
- rgsseval = self.findProc("RGSS300", "RGSSGetInt")
- old = :"user32|GetWindowLong|ll|l".apicall(@hwnd, -4)
- buf = @malloc.apicall(1024)
- fmt = @malloc.apicall(2048)
- sprintfvar = @malloc.apicall(8)
- rgssevalvar= @malloc.apicall(8)
- oldvar = @malloc.apicall(8)
- fmtvar = @malloc.apicall(8)
- bufvar = @malloc.apicall(8)
- defvar = @malloc.apicall(8)
-
- :"msvcrt|strcpy|pp|p".apicall(fmt, "Roost::MainWindow.getwndproc.call(%d,%d,%d,%d)")
-
- @memcpy.apicall(sprintfvar, [sprintf].pack("i"), 4)
- @memcpy.apicall(rgssevalvar,[rgsseval].pack("i"), 4)
- @memcpy.apicall(oldvar, [old].pack("i"), 4)
- @memcpy.apicall(fmtvar, [fmt].pack("i"), 4)
- @memcpy.apicall(bufvar, [buf].pack("i"), 4)
- @memcpy.apicall(defvar, [self.findProc("user32", "DefWindowProcA")].pack("i"), 4)
-
- @code = [0x55,0x89,0xe5,0xff,0x75,0x14,
- 0xff,0x75,0x10,0xff,0x75,0x0c,
- 0xff,0x75,0x08,0xff,0x35].pack('C*')
- @code << [fmtvar].pack('l') << [0xff, 0x35].pack('C*')
- @code << [bufvar].pack('l') << [0xff, 0x15].pack('C*')
- @code << [sprintfvar].pack("l")
- @code << [0xff, 0x15].pack('C*')
- @code << [rgssevalvar].pack("l")
- =begin
- @code << [0x83,0xc4,0x18, 0xff, 0x75, 0x14,
- 0xff,0x75, 0x10, 0xff, 0x75, 0x0c,
- 0xff,0x75, 0x08, 0xff, 0x15].pack('C*')
- @code << [oldvar].pack("l")
- =end
- @code << [0x83,0xc4,0x18].pack('C*')
- @code << [0xc9,0xc2,0x10,0x00].pack('C*')
- #0xD1, 0xE8
- @shellcode = @malloc.apicall(2048)
- @memcpy.apicall(@shellcode, @code, @code.size)
- @@oHandle= :"user32|SetWindowLong|iii|i".apicall(@hwnd, -4, @shellcode)
- #Returning Test : should be 5
- #Roost::MainWindow.setwndproc (lambda{|hwnd, msg, wp, lp| 5})
- #p :"user32|CallWindowProc|iiiii|i".apicall(@shellcode, 0, 0, 0, 0)
- end
- end
-
- end
-
- end
- end
- Roost::MainWindow.enable
- Roost::MainWindow.enableWndProc
- module Mouse
- module_function
- LKEY,RKEY,MKEY = 1,2,4
- DBLCTIME = (Win32API.new('user32','GetDoubleClickTime','','l').call * 60.0 / 1000).round
- @count = 0 ## 双击时间计数
- @dblc = [] ## 双击记录[key,wait,[mouse_x,mouse_y]]
- @move_pos = [] ## 移动记录
- @clicks = [] ## 单击记录
- def _init_
- @press,@toggled=0,0
-
- @pos=[0,0]
- Roost::MainWindow.addwndproc (lambda {|hwnd, msg, wp, lp|
- Mouse.onLMouseDown if msg==Win32API::WM_LBUTTONDOWN
- Mouse.onRMouseDown if msg==Win32API::WM_RBUTTONDOWN
- Mouse.onLMouseUp if msg==Win32API::WM_LBUTTONUP
- Mouse.onRMouseUp if msg==Win32API::WM_RBUTTONUP
- Mouse.onLMouseDD if msg==Win32API::WM_LBUTTONDBLCLK
- Mouse.onRMouseDD if msg==Win32API::WM_RBUTTONDBLCLK
- if msg==Win32API::WM_MOUSEMOVE
- Mouse.setMouse([lp&0xffff,lp>>16])
- end
- })
- @ldown=false
- @ltd=false
- @rdown=false
- @rtd=false
- @lup=false
- @rup=false
- end
- def onLMouseDown
- @ltd=true
- @ltd=false if @ldown
- @ldown=true
- end
- def onLMouseUp
- @ldown=false
- @ltd=false
- end
- def onLMouseDD
-
- end
- def onRMouseDown
- @rtd=true
- @rtd=false if @rdown
- @rdown=true
-
- end
- def onRMouseUp
- @rdown=false
- @rtd=false
- end
- def onRMouseDD
-
- end
- def setMouse(p)
- @pos=p
- end
-
- #--------------------------------------------------------------------------
- # ## 触发?
- #--------------------------------------------------------------------------
- def self.toggled?(key)
- return @toggled & key != 0
- end
- #--------------------------------------------------------------------------
- # ## 按下?
- #--------------------------------------------------------------------------
- def Mouse.press?(key)
- return @press & key != 0
- end
- #--------------------------------------------------------------------------
- # ## 单击?
- #--------------------------------------------------------------------------
- def self.click?(key)
- return false if key == LKEY and !$click_abled
- return @clicks[0] & key == 0 && @clicks[1] & key != 0
- end
- #--------------------------------------------------------------------------
- # ## 双击?
- #--------------------------------------------------------------------------
- def self.dbl_click?(key)
- return false if @dblc.size < 2
- ## 键值有效
- if @dblc[1][0] & key != 0 and @dblc[0][0] & key != 0
- ## 间隔有效
- if @dblc[1][1] - @dblc[0][1] < DBLCTIME
- ## 坐标有效
- if @dblc[1][2] == @dblc[0][2]
- return @clicks[0] & key == 0 && @clicks[1] & key != 0
- end
- end
- end
- return false
- end
- def pos
- return @pos
- end
- def update
- @press,@toggled=0,0
- @press += LKEY if @ldown
- @press += RKEY if @rdown
- @toggled += LKEY if @ltd
- @toggled += RKEY if @rtd
- @clicks.shift if @clicks.size >=2
- @clicks.push @press
- if @dblc.size >= 2
- @dblc.clear
- @count = 0
- end
- if @dblc.size == 1 and @count - @dblc[0][1] > DBLCTIME
- @dblc.clear
- @count = 0
- end
- if @clicks[0] == 0 and @clicks[1] != 0
- if @dblc.size == 1 and @dblc[0][0] != @clicks[1]
- @dblc.clear
- @count = 0
- end
- @dblc.push [@press,@count,@pos]
- end
- @count += 1 unless @dblc.empty?
- @move_pos.shift if @move_pos.size >= 2
- @move_pos.push @pos
- $click_abled=true
- end
- def down(p)
- if (p==LEFT)
- return @ldown
- else
- return @rdown
- end
- end
- end
- Mouse._init_
- class << Mouse
- Win32API.new('user32', 'ShowCursor', 'l', 'l').call(0)
- $mousec = Sprite.new
- $mousec.z = 10001
- $mousec.x = $mousec.y = 1000
- $mouse_icon = 'Pointer'
- $mousec.bitmap = Cache.system($mouse_icon)
-
- alias wor_mouse_upd_mouse update unless $@
- def Mouse.update
- wor_mouse_upd_mouse
- if $mouse_old_icon.nil? or $mouse_old_icon != $mouse_icon
- $mouse_old_icon = $mouse_icon
- $mousec.bitmap = Cache.system($mouse_old_icon)
- end
- if @pos.nil?
- $mousec.x = 1000 if $mousec.x != 1000
- $mousec.y = 1000 if $mousec.y != 1000
- Win32API.new('user32', 'ShowCursor', 'l', 'l').call(1)
- else
- $mousec.x = @pos[0] if $mousec.x != @pos[0]
- $mousec.y = @pos[1] if $mousec.y != @pos[1]
- Win32API.new('user32', 'ShowCursor', 'l', 'l').call(0)
- end
- ## 鼠标刷新
- $mousec.update
- end
- #--------------------------------------------------------------------------
- # ## 经过?
- # obj : 对象实例
- # **支持Sprite,Window,Viewport,Rect,Plane,可补充
- #--------------------------------------------------------------------------
- def Mouse.over?(obj)
- case obj
- when Sprite
- x = obj.x-obj.ox; y = obj.y-obj.oy
- unless obj.viewport.nil?
- x += obj.viewport.rect.x
- y += obj.viewport.rect.y
- end
- return Mouse.area?(x, y, obj.width, obj.height)
- when Window
- x = obj.x;y = obj.y
- unless obj.viewport.nil?
- x += obj.viewport.rect.x
- y += obj.viewport.rect.y
- end
- return Mouse.area?(x, y, obj.width, obj.height)
- when Viewport
- return Mouse.area?(obj.rect.x, obj.rect.y, obj.rect.width, obj.rect.height)
- when Rect
- return Mouse.area?(obj.x, obj.y, obj.width, obj.height)
- when Plane
- x = obj.x;y = obj.y
- unless obj.viewport.nil?
- x += obj.viewport.rect.x
- y += obj.viewport.rect.y
- end
- return Mouse.area?(x, y, obj.width, obj.height)
- end
- end
- #--------------------------------------------------------------------------
- # * Mouse in_area
- #--------------------------------------------------------------------------
- def Mouse.area?(x, y, width=32, height=32)
- return false if @pos == nil
- return true if @pos[0] >= x and @pos[0] <= (x+width) and @pos[1] >= y and @pos[1] <= (y+height)
- return false
- end
- end
- #==============================================================================
- # ## Window_Selectable
- #==============================================================================
- class Window_Selectable < Window_Base
- alias wor_winsel_ini_mouse initialize
- alias wor_winsel_upd_mouse update
- def initialize(*args)
- wor_winsel_ini_mouse(*args)
- @scroll_wait = 0
- @cursor_wait = 0
- end
- def update
- wor_winsel_upd_mouse
- if self.active and self.visible
- update_mouse
- end
- end
-
- def update_mouse
- @cursor_wait -= 1 if @cursor_wait > 0
- (0...item_max).each do |i|
- irect = mouse_rect(i)
- irx = self.x + 16 + irect.x - self.ox
- iry = self.y + 16 + irect.y - self.oy
- result = Mouse.area?(irx, iry, irect.width, irect.height)
- move_cursor(i) if result
- ## 控制单击条件
- $click_abled = false if i == @index and !result
- end
- end
-
- ## 鼠标区域
- def mouse_rect(i)
- rect = item_rect(i)
- return rect if rect.width <= 32
- rect.x += 4
- rect.y += 4
- rect.width -= 8
- rect.height -= 8
- return rect
- end
- def column_max
- return row_max
- end
- def move_cursor(index)
- ## 不响应
- return if @cursor_wait > 0
- return if self.index == index
- @scroll_wait -= 1 if @scroll_wait > 0
- row1 = self.index / column_max
- row2 = index / column_max
- bottom = self.top_row + (self.page_row_max - 1)
- if row1 == self.top_row and row2 < self.top_row
- return if @scroll_wait > 0
- self.index = [self.index - column_max, 0].max
- @scroll_wait = 4
- elsif row1 == bottom and row2 > bottom
- return if @scroll_wait > 0
- self.index = [self.index + column_max, item_max - 1].min
- @scroll_wait = 4
- else
- self.index = index
- end
- return if @cursor_wait > 0
- Sound.play_cursor
- @cursor_wait += 2
- end
- end
- #==============================================================================
- # ** Input
- #==============================================================================
- class << Input
- alias wor_input_upd_mouse update unless $@
- alias wor_input_trig_mouse trigger? unless $@
- alias wor_input_rep_mouse repeat? unless $@
- def Input.update
- wor_input_upd_mouse
- Mouse.update
- end
- def Input.trigger?(input)
- return wor_input_trig_mouse(input) if Mouse.pos.nil?
- case input
- when Input::B
- return (wor_input_trig_mouse(input) or Mouse.click?(Mouse::RKEY))
- when Input::C
- if SceneManager.scene.is_a?(Scene_Map) and !$game_message.visible
- return wor_input_trig_mouse(input)
- else
- return (wor_input_trig_mouse(input) or Mouse.click?(Mouse::LKEY))
- end
- else
- return wor_input_trig_mouse(input)
- end
- end
-
- def Input.repeat?(input)
- if input == Input::B
- return (wor_input_rep_mouse(input) or Mouse.click?(Mouse::RKEY))
- else
- return wor_input_rep_mouse(input)
- end
- end
- end
复制代码 |
评分
-
查看全部评分
|