设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 26003|回复: 29
打印 上一主题 下一主题

[RMVA发布] VA简易鼠标完整

[复制链接]

Lv2.观梦者

傻♂逼

梦石
0
星屑
374
在线时间
1606 小时
注册时间
2007-3-13
帖子
6562

烫烫烫开拓者

跳转到指定楼层
发表于 2012-1-2 01:54:17 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 yangff 于 2012-1-2 14:43 编辑

基本和VX鼠标统一接口了,有几个函数不是很理解就暂时没弄。。
WndProc的代码使用了@晴兰http://rpg.blue/thread-216658-1-1.html 不过他的那段有点问题所以这里放的是修改好的。
  1. $apicache = {}
  2. class String
  3.    def apicall(*args)
  4.        $apicache[self] = Win32API.new(*self.split("|")) unless $apicache.include? self
  5.        $apicache[self].call(*args)
  6.    end
  7. end

  8. class Symbol
  9.   def method_missing(*args, &block)
  10.         self.to_s.send(*args, &block)
  11.   end
  12. end
  13. class Win32API
  14.   WM_ACTIVATEAPP=0x1C
  15.   WM_MOUSEMOVE=0x200
  16.   WM_MOUSEWHEEL = 0x020A
  17.   WM_LBUTTONDOWN = 0x201
  18.   WM_RBUTTONDOWN = 0x204
  19.   WM_MOUSEDOWN = 0x210
  20.   WM_LBUTTONUP = 0x202
  21.   WM_RBUTTONUP = 0x205
  22.   WM_LBUTTONDBLCLK  = 0x203
  23.   WM_RBUTTONDBLCLK  = 0x204
  24. end
  25. module Roost   
  26.     module MainWindow
  27.         def self.getwndproc
  28.            @wndproc
  29.          end
  30.         def self.setwndproc(obj)
  31.            @wndproc=obj
  32.         end
  33.         def self.addwndproc(obj)
  34.           @@wndprocs.push(obj)
  35.         end
  36.         @@wndprocs=[]
  37.         @wndproc = lambda {|hwnd, msg, wp, lp|
  38.           @@handle=false
  39.           for i in @@wndprocs
  40.             i.call(hwnd, msg, wp, lp)
  41.           end
  42.           return Roost::MainWindow.use_rm_proc(hwnd, msg, wp, lp)
  43.         }
  44.         def self.use_rm_proc(hwnd,msg,wp,lp)
  45.           if (not @@handle)
  46.             @@handle=true
  47.             return :"user32|CallWindowProc|iiiii|i".apicall(@@oHandle,hwnd,msg,wp,lp)
  48.           end
  49.         end
  50.         def self.disable_rm_proc
  51.           @@handle=true
  52.         end
  53.         def self.enable
  54.               Roost::MainWindow.instance_eval do
  55.                 def self.enable
  56.                 end
  57.               end
  58.             Roost::MainWindow.instance_eval do
  59.               @msg = "\0"*24
  60.               @hwnd = 0
  61.               while @hwnd==0
  62.                :"user32|GetMessage|piii|v".apicall(@msg, 0, 0, 0)
  63.                @kmsg = @msg
  64.                :"user32|TranslateMessage|p|v".apicall(@kmsg)
  65.                :"user32|DispatchMessage|p|v".apicall(@kmsg)
  66.                @hwnd = @msg.unpack("i*")[0]
  67.              end
  68.             @hdc = :"user32|GetDC|i|i".apicall(@hwnd)
  69.             def self.hwnd
  70.                return @hwnd
  71.             end
  72.             def self.hdc
  73.               return @hdc
  74.             end
  75.             
  76.             def self.findProc(l, n)
  77.                    lib = :"kernel32|LoadLibrary|p|i".apicall(l);
  78.                    ret = :"kernel32|GetProcAddress|ip|l".apicall(lib, n);
  79.                    :"kernel32|FreeLibrary|l|v".apicall(lib)
  80.                    return ret
  81.             end
  82.                  def self.loadfindProc(l, n)
  83.                    lib = :"kernel32|LoadLibrary|p|i".apicall(l);
  84.                    ret = :"kernel32|GetProcAddress|ip|l".apicall(lib, n);
  85.                    return ret
  86.             end
  87.             def self.enableWndProc
  88.               Roost::MainWindow.instance_eval do
  89.                 def self.enableWndProc
  90.                 end
  91.               end
  92.               @malloc = :"msvcrt|malloc|i|i"
  93.               @memcpy = :"msvcrt|memcpy|ipi|v"
  94.               
  95.               
  96.              sprintf    = self.findProc("msvcrt",    "sprintf")
  97.              rgsseval   = self.findProc("RGSS300",  "RGSSGetInt")
  98.              old        = :"user32|GetWindowLong|ll|l".apicall(@hwnd, -4)
  99.              buf        = @malloc.apicall(1024)  
  100.              fmt        = @malloc.apicall(2048)
  101.              sprintfvar = @malloc.apicall(8)
  102.              rgssevalvar= @malloc.apicall(8)
  103.              oldvar     = @malloc.apicall(8)
  104.              fmtvar     = @malloc.apicall(8)
  105.              bufvar     = @malloc.apicall(8)
  106.              defvar     = @malloc.apicall(8)
  107.             
  108.              :"msvcrt|strcpy|pp|p".apicall(fmt, "Roost::MainWindow.getwndproc.call(%d,%d,%d,%d)")
  109.             
  110.              @memcpy.apicall(sprintfvar, [sprintf].pack("i"),  4)
  111.              @memcpy.apicall(rgssevalvar,[rgsseval].pack("i"), 4)
  112.              @memcpy.apicall(oldvar,     [old].pack("i"),      4)
  113.              @memcpy.apicall(fmtvar,     [fmt].pack("i"),      4)
  114.              @memcpy.apicall(bufvar,     [buf].pack("i"),      4)
  115.              @memcpy.apicall(defvar,     [self.findProc("user32", "DefWindowProcA")].pack("i"),      4)
  116.             
  117.              @code = [0x55,0x89,0xe5,0xff,0x75,0x14,
  118.                       0xff,0x75,0x10,0xff,0x75,0x0c,
  119.                       0xff,0x75,0x08,0xff,0x35].pack('C*')
  120.              @code << [fmtvar].pack('l') << [0xff, 0x35].pack('C*')
  121.              @code << [bufvar].pack('l') << [0xff, 0x15].pack('C*')
  122.              @code << [sprintfvar].pack("l")
  123.              @code << [0xff, 0x15].pack('C*')
  124.              @code << [rgssevalvar].pack("l")
  125. =begin
  126.              @code << [0x83,0xc4,0x18, 0xff, 0x75, 0x14,
  127.                        0xff,0x75, 0x10, 0xff, 0x75, 0x0c,
  128.                        0xff,0x75, 0x08, 0xff, 0x15].pack('C*')
  129.              @code << [oldvar].pack("l")
  130. =end
  131.              @code << [0x83,0xc4,0x18].pack('C*')
  132.              @code << [0xc9,0xc2,0x10,0x00].pack('C*')
  133.              #0xD1, 0xE8
  134.              @shellcode = @malloc.apicall(2048)  
  135.              @memcpy.apicall(@shellcode, @code, @code.size)
  136.              @@oHandle= :"user32|SetWindowLong|iii|i".apicall(@hwnd, -4, @shellcode)
  137.               #Returning Test : should be 5
  138.               #Roost::MainWindow.setwndproc (lambda{|hwnd, msg, wp, lp| 5})
  139.               #p :"user32|CallWindowProc|iiiii|i".apicall(@shellcode, 0, 0, 0, 0)
  140.             end
  141.           end
  142.          
  143.         end
  144.         
  145.   end
  146. end

  147. Roost::MainWindow.enable
  148. Roost::MainWindow.enableWndProc
  149. module Mouse
  150.   module_function
  151.   LKEY,RKEY,MKEY   = 1,2,4
  152.   DBLCTIME         = (Win32API.new('user32','GetDoubleClickTime','','l').call * 60.0 / 1000).round
  153.   @count    = 0     ## 双击时间计数
  154.   @dblc     = []    ## 双击记录[key,wait,[mouse_x,mouse_y]]
  155.   @move_pos = []    ## 移动记录
  156.   @clicks   = []    ## 单击记录
  157.   def _init_
  158.     @press,@toggled=0,0
  159.    
  160.     @pos=[0,0]

  161.     Roost::MainWindow.addwndproc (lambda {|hwnd, msg, wp, lp|
  162.       Mouse.onLMouseDown if msg==Win32API::WM_LBUTTONDOWN
  163.       Mouse.onRMouseDown if msg==Win32API::WM_RBUTTONDOWN
  164.       Mouse.onLMouseUp if msg==Win32API::WM_LBUTTONUP
  165.       Mouse.onRMouseUp if msg==Win32API::WM_RBUTTONUP
  166.       Mouse.onLMouseDD if msg==Win32API::WM_LBUTTONDBLCLK
  167.       Mouse.onRMouseDD if msg==Win32API::WM_RBUTTONDBLCLK
  168.       if msg==Win32API::WM_MOUSEMOVE
  169.         Mouse.setMouse([lp&0xffff,lp>>16])
  170.       end
  171.     })
  172.     @ldown=false
  173.     @ltd=false
  174.     @rdown=false
  175.     @rtd=false
  176.     @lup=false
  177.     @rup=false
  178.   end
  179.   def onLMouseDown
  180.     @ltd=true
  181.     @ltd=false if @ldown
  182.     @ldown=true
  183.   end
  184.   def onLMouseUp
  185.     @ldown=false
  186.     @ltd=false
  187.   end
  188.   def onLMouseDD
  189.    
  190.   end
  191.   def onRMouseDown
  192.     @rtd=true
  193.     @rtd=false if @rdown
  194.     @rdown=true
  195.    
  196.   end
  197.   def onRMouseUp
  198.     @rdown=false
  199.     @rtd=false
  200.   end
  201.   def onRMouseDD
  202.    
  203.   end
  204.   def setMouse(p)
  205.     @pos=p
  206.   end
  207.   
  208.   #--------------------------------------------------------------------------
  209.   # ## 触发?
  210.   #--------------------------------------------------------------------------
  211.   def self.toggled?(key)
  212.     return @toggled & key != 0
  213.   end
  214.   #--------------------------------------------------------------------------
  215.   # ## 按下?
  216.   #--------------------------------------------------------------------------
  217.   def Mouse.press?(key)
  218.     return @press & key != 0
  219.   end
  220.   #--------------------------------------------------------------------------
  221.   # ## 单击?
  222.   #--------------------------------------------------------------------------
  223.   def self.click?(key)
  224.     return false if key == LKEY and !$click_abled
  225.     return @clicks[0] & key == 0 && @clicks[1] & key != 0
  226.   end
  227.   #--------------------------------------------------------------------------
  228.   # ## 双击?
  229.   #--------------------------------------------------------------------------
  230.   def self.dbl_click?(key)
  231.     return false if @dblc.size < 2
  232.     ## 键值有效
  233.     if @dblc[1][0] & key != 0 and @dblc[0][0] & key != 0
  234.       ## 间隔有效
  235.       if @dblc[1][1] - @dblc[0][1] < DBLCTIME
  236.         ## 坐标有效
  237.         if @dblc[1][2] == @dblc[0][2]
  238.           return @clicks[0] & key == 0 && @clicks[1] & key != 0
  239.         end
  240.       end
  241.     end
  242.     return false
  243.   end
  244.   def pos
  245.     return @pos
  246.   end
  247.   def update
  248.     @press,@toggled=0,0
  249.     @press += LKEY   if @ldown
  250.     @press += RKEY   if @rdown
  251.     @toggled += LKEY if @ltd
  252.     @toggled += RKEY  if @rtd
  253.     @clicks.shift if @clicks.size >=2
  254.     @clicks.push @press
  255.     if @dblc.size >= 2
  256.       @dblc.clear
  257.       @count = 0
  258.     end
  259.     if @dblc.size == 1 and @count - @dblc[0][1] > DBLCTIME
  260.       @dblc.clear
  261.       @count = 0
  262.     end
  263.     if @clicks[0] == 0 and @clicks[1] != 0
  264.       if @dblc.size == 1 and @dblc[0][0] != @clicks[1]
  265.         @dblc.clear
  266.         @count = 0
  267.       end
  268.       @dblc.push [@press,@count,@pos]
  269.     end
  270.     @count += 1 unless @dblc.empty?
  271.     @move_pos.shift if @move_pos.size >= 2
  272.     @move_pos.push @pos
  273.     $click_abled=true
  274.   end
  275.   def down(p)
  276.     if (p==LEFT)
  277.       return @ldown
  278.     else
  279.       return @rdown
  280.     end
  281.   end
  282. end

  283. Mouse._init_






  284. class << Mouse
  285.   Win32API.new('user32', 'ShowCursor', 'l', 'l').call(0)
  286.   $mousec = Sprite.new
  287.   $mousec.z = 10001
  288.   $mousec.x = $mousec.y = 1000
  289.   $mouse_icon = 'Pointer'
  290.   $mousec.bitmap = Cache.system($mouse_icon)
  291.   
  292.   alias wor_mouse_upd_mouse update unless $@
  293.   def Mouse.update
  294.     wor_mouse_upd_mouse
  295.     if $mouse_old_icon.nil? or $mouse_old_icon != $mouse_icon
  296.       $mouse_old_icon = $mouse_icon
  297.       $mousec.bitmap = Cache.system($mouse_old_icon)
  298.     end
  299.     if @pos.nil?
  300.       $mousec.x = 1000 if $mousec.x != 1000
  301.       $mousec.y = 1000 if $mousec.y != 1000
  302.       Win32API.new('user32', 'ShowCursor', 'l', 'l').call(1)
  303.     else
  304.       $mousec.x = @pos[0] if $mousec.x != @pos[0]
  305.       $mousec.y = @pos[1] if $mousec.y != @pos[1]
  306.       Win32API.new('user32', 'ShowCursor', 'l', 'l').call(0)
  307.     end
  308.     ## 鼠标刷新
  309.     $mousec.update
  310.   end
  311.   #--------------------------------------------------------------------------
  312.   # ## 经过?
  313.   #     obj       : 对象实例
  314.   #                 **支持Sprite,Window,Viewport,Rect,Plane,可补充
  315.   #--------------------------------------------------------------------------
  316.   def Mouse.over?(obj)
  317.     case obj
  318.     when Sprite
  319.       x = obj.x-obj.ox; y = obj.y-obj.oy
  320.       unless obj.viewport.nil?
  321.         x += obj.viewport.rect.x
  322.         y += obj.viewport.rect.y
  323.       end
  324.       return Mouse.area?(x, y, obj.width, obj.height)
  325.     when Window
  326.       x = obj.x;y = obj.y
  327.       unless obj.viewport.nil?
  328.         x += obj.viewport.rect.x
  329.         y += obj.viewport.rect.y
  330.       end
  331.       return Mouse.area?(x, y, obj.width, obj.height)
  332.     when Viewport
  333.       return Mouse.area?(obj.rect.x, obj.rect.y, obj.rect.width, obj.rect.height)
  334.     when Rect
  335.       return Mouse.area?(obj.x, obj.y, obj.width, obj.height)
  336.     when Plane
  337.       x = obj.x;y = obj.y
  338.       unless obj.viewport.nil?
  339.         x += obj.viewport.rect.x
  340.         y += obj.viewport.rect.y
  341.       end
  342.       return Mouse.area?(x, y, obj.width, obj.height)
  343.     end
  344.   end
  345.   #--------------------------------------------------------------------------
  346.   # * Mouse in_area
  347.   #--------------------------------------------------------------------------
  348.   def Mouse.area?(x, y, width=32, height=32)
  349.     return false if @pos == nil
  350.     return true if @pos[0] >= x and @pos[0] <= (x+width) and @pos[1] >= y and @pos[1] <= (y+height)
  351.     return false
  352.   end

  353. end







  354. #==============================================================================
  355. # ## Window_Selectable
  356. #==============================================================================
  357. class Window_Selectable < Window_Base
  358.   alias wor_winsel_ini_mouse initialize
  359.   alias wor_winsel_upd_mouse update
  360.   def initialize(*args)
  361.     wor_winsel_ini_mouse(*args)
  362.     @scroll_wait = 0
  363.     @cursor_wait = 0
  364.   end

  365.   def update
  366.     wor_winsel_upd_mouse
  367.     if self.active and self.visible
  368.       update_mouse
  369.     end
  370.   end
  371.   
  372.   def update_mouse
  373.     @cursor_wait -= 1 if @cursor_wait > 0
  374.     (0...item_max).each do |i|
  375.       irect = mouse_rect(i)
  376.       irx = self.x + 16 + irect.x - self.ox
  377.       iry = self.y + 16 + irect.y - self.oy
  378.       result = Mouse.area?(irx, iry, irect.width, irect.height)
  379.       move_cursor(i) if result
  380.       ## 控制单击条件
  381.       $click_abled = false if i == @index and !result
  382.     end

  383.   end
  384.   
  385.   ## 鼠标区域
  386.   def mouse_rect(i)
  387.     rect = item_rect(i)
  388.     return rect if rect.width <= 32
  389.     rect.x += 4
  390.     rect.y += 4
  391.     rect.width -= 8
  392.     rect.height -= 8
  393.     return rect
  394.   end
  395.   def column_max
  396.     return row_max
  397.   end
  398.   def move_cursor(index)
  399.     ## 不响应
  400.     return if @cursor_wait > 0
  401.     return if self.index == index
  402.     @scroll_wait -= 1 if @scroll_wait > 0
  403.     row1 = self.index / column_max
  404.     row2 = index / column_max
  405.     bottom = self.top_row + (self.page_row_max - 1)
  406.     if row1 == self.top_row and row2 < self.top_row
  407.       return if @scroll_wait > 0
  408.       self.index = [self.index - column_max, 0].max
  409.       @scroll_wait = 4
  410.     elsif row1 == bottom and row2 > bottom
  411.       return if @scroll_wait > 0
  412.       self.index = [self.index + column_max, item_max - 1].min
  413.       @scroll_wait = 4
  414.     else
  415.       self.index = index
  416.     end
  417.     return if @cursor_wait > 0
  418.     Sound.play_cursor
  419.     @cursor_wait += 2
  420.   end
  421. end

  422. #==============================================================================
  423. # ** Input
  424. #==============================================================================
  425. class << Input
  426.   alias wor_input_upd_mouse update unless $@
  427.   alias wor_input_trig_mouse trigger? unless $@
  428.   alias wor_input_rep_mouse repeat? unless $@
  429.   def Input.update
  430.     wor_input_upd_mouse
  431.     Mouse.update
  432.   end
  433.   def Input.trigger?(input)

  434.     return wor_input_trig_mouse(input) if Mouse.pos.nil?
  435.     case input
  436.     when Input::B
  437.       return (wor_input_trig_mouse(input) or Mouse.click?(Mouse::RKEY))
  438.     when Input::C
  439.       if SceneManager.scene.is_a?(Scene_Map) and !$game_message.visible
  440.         return wor_input_trig_mouse(input)
  441.       else
  442.         return (wor_input_trig_mouse(input) or Mouse.click?(Mouse::LKEY))
  443.       end
  444.     else
  445.       return wor_input_trig_mouse(input)
  446.     end
  447.   end
  448.   
  449.   def Input.repeat?(input)

  450.     if input == Input::B
  451.       return (wor_input_rep_mouse(input) or Mouse.click?(Mouse::RKEY))
  452.     else
  453.       return wor_input_rep_mouse(input)
  454.     end
  455.   end
  456. end


复制代码

点评

alias wor_input_rep_mouse repeat? unless $@ 这种代码改掉吧(异常信息可能会被清空的 对于某些脚本(:比如cc.call  发表于 2012-1-12 19:27

评分

参与人数 2星屑 +14 +2 收起 理由
hys111111 + 14
退屈£无聊 + 2

查看全部评分

哎呀,蛋疼什么的最有爱了

Lv3.寻梦者

梦石
3
星屑
65
在线时间
200 小时
注册时间
2008-7-8
帖子
180
29
发表于 2015-8-6 19:59:13 | 只看该作者
nice,拿来用了
回复 支持 反对

使用道具 举报

Lv4.逐梦者 (版主)

梦石
1
星屑
6666
在线时间
2650 小时
注册时间
2013-8-23
帖子
2315

开拓者

28
发表于 2013-8-24 13:59:08 | 只看该作者
学习下...
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
390
在线时间
11 小时
注册时间
2013-1-27
帖子
2
27
发表于 2013-6-24 17:18:18 | 只看该作者
有没有范例啊?
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
182 小时
注册时间
2012-2-11
帖子
233
26
发表于 2013-2-23 12:01:42 | 只看该作者
yangff 发表于 2013-2-22 18:10
www.github.com/project7
……鼠标键盘都有,不过要去掉一点无用的代码。。

233{:2_280:}
回复 支持 反对

使用道具 举报

Lv2.观梦者

傻♂逼

梦石
0
星屑
374
在线时间
1606 小时
注册时间
2007-3-13
帖子
6562

烫烫烫开拓者

25
 楼主| 发表于 2013-2-22 18:10:01 | 只看该作者
viktor 发表于 2013-2-21 15:14
project7? 求传送门
另外求全键盘脚本……、
不会弄这些

www.github.com/project7
……鼠标键盘都有,不过要去掉一点无用的代码。。
哎呀,蛋疼什么的最有爱了
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
182 小时
注册时间
2012-2-11
帖子
233
24
发表于 2013-2-21 15:14:37 | 只看该作者
yangff 发表于 2013-2-21 13:11
嗯……因为消息确实同步起来有点蛋疼,要鼠标还是用project7里面的吧。。

project7? 求传送门
另外求全键盘脚本……、
不会弄这些
回复 支持 反对

使用道具 举报

Lv2.观梦者

傻♂逼

梦石
0
星屑
374
在线时间
1606 小时
注册时间
2007-3-13
帖子
6562

烫烫烫开拓者

23
 楼主| 发表于 2013-2-21 13:11:37 | 只看该作者
viktor 发表于 2013-2-21 11:24
最近在做界面库,使用了一下这个 发现单击和双击的判定还是有问题啊……

嗯……因为消息确实同步起来有点蛋疼,要鼠标还是用project7里面的吧。。
哎呀,蛋疼什么的最有爱了
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
182 小时
注册时间
2012-2-11
帖子
233
22
发表于 2013-2-21 11:24:08 | 只看该作者
最近在做界面库,使用了一下这个 发现单击和双击的判定还是有问题啊……
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
205
在线时间
1 小时
注册时间
2013-1-20
帖子
3
21
发表于 2013-1-20 15:01:51 | 只看该作者
为什么..读取不到文件呢..
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
109 小时
注册时间
2011-7-18
帖子
70
20
发表于 2012-12-2 13:40:12 | 只看该作者
鼠标卡在左上角动不了
66RPG论坛
超级VIP
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-24 14:51

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表