Project1

标题: 有条件地显示鼠标 [打印本页]

作者: dant    时间: 2012-2-8 11:22
标题: 有条件地显示鼠标
不隐藏鼠标指针之后
继续玩一下鼠标指针[误]
其实是@各种压力的猫君要的
@凌依约http://rpg.blue/forum.php?mod=viewthread&tid=221745&page=1#pid1846645发布的脚本的基础上[真的是“基础”吗?]修改而成
实现了在客户区内隐藏鼠标指针,在非客户区不隐藏
不过F1有点问题 = =

RUBY 代码复制
  1. #----------------------------------------------------------------------------
  2. #  SmartCursor - 有条件地显示鼠标
  3. #
  4. #   VX&VA 测试通过,XP请将108行处的"SendMessaeW"改为"DefWindowProcA"
  5. #   使用方法:在Main前插入脚本即可,越前越好
  6. #   已知问题:弹出F1那个框框时,如果鼠标指针在游戏窗口的客户区内,则不会
  7. #   显示鼠标指针。
  8. #----------------------------------------------------------------------------
  9.  
  10. #==============================================================================
  11. # ■ Kernel
  12. #------------------------------------------------------------------------------
  13. #  该模块中定义了可供所有类使用的方法。Object 类中包含了该模块。
  14. #==============================================================================
  15. module Kernel
  16.   #--------------------------------------------------------------------------
  17.   # ● 需要的 Windows API 函数
  18.   #--------------------------------------------------------------------------
  19.   GetWindowThreadProcessId = Win32API.new("user32", "GetWindowThreadProcessId", "LP", "L")
  20.   GetWindow = Win32API.new("user32", "GetWindow", "LL", "L")
  21.   GetClassName = Win32API.new("user32", "GetClassName", "LPL", "L")
  22.   GetCurrentThreadId = Win32API.new("kernel32", "GetCurrentThreadId", "V", "L")
  23.   GetForegroundWindow = Win32API.new("user32", "GetForegroundWindow", "V", "L")
  24.   #--------------------------------------------------------------------------
  25.   # ● 获取窗口句柄
  26.   #--------------------------------------------------------------------------
  27.   def get_hWnd
  28.     return @hwnd if @hwnd  ########
  29.     # 获取调用线程(RM 的主线程)的进程标识
  30.     threadID = GetCurrentThreadId.call
  31.     # 获取 Z 次序中最靠前的窗口
  32.     hWnd = GetWindow.call(GetForegroundWindow.call, 0)
  33.     # 枚举所有窗口
  34.     while hWnd != 0
  35.       # 如果创建该窗口的线程标识匹配本线程标识
  36.       if threadID == GetWindowThreadProcessId.call(hWnd, 0)
  37.         # 分配一个 11 个字节的缓冲区
  38.         className = " " * 11
  39.         # 获取该窗口的类名
  40.         GetClassName.call(hWnd, className, 12)
  41.         # 如果匹配 RGSS Player 则跳出循环
  42.         break if className == "RGSS Player"
  43.       end
  44.       # 获取下一个窗口
  45.       hWnd = GetWindow.call(hWnd, 2)
  46.     end
  47.     @hwnd=hWnd    ########
  48.     return hWnd
  49.   end
  50.  
  51.   def MAKELONG(wLow,wHigh)
  52.     (wLow&0xFFFF)|((wHigh<<16)&0xFFFF0000)
  53.   end
  54.  
  55. end
  56.  
  57. #----------------------------------------------------------------------------
  58. $dant_ShowCursor = Win32API.new('user32', 'ShowCursor', %w(l), 'l')
  59. $dant_WFP = Win32API.new('user32', 'WindowFromPoint', 'ii', 'l')
  60. $dant_GCP  = Win32API.new('user32', 'GetCursorPos'   , %w(p), 'l')
  61. $dant_buf = "\000"*8
  62. $dant_GCP.call($dant_buf)
  63. $dant_x,$dant_y = $dant_buf.unpack('II')
  64. if $dant_WFP.call($dant_x,$dant_y) != get_hWnd
  65.   $dant_ShowCursor.call(0)
  66. end
  67. $dant_WFP        = nil
  68. $dant_GCP        = nil
  69. $dant_ShowCursor = nil
  70. $dant_x          = nil
  71. $dant_y          = nil
  72. $dant_buf        = nil
  73. #----------------------------------------------------------------------------
  74.  
  75. class DontSetCursor
  76.  
  77.   PAGE_EXECUTE_READWRITE = 0x40
  78.  
  79.   def initialize
  80.     @getModuleHandle=Win32API.new('kernel32.dll','GetModuleHandleA','p','i')
  81.     @getProcAddress=Win32API.new('kernel32.dll','GetProcAddress','ip','i')
  82.     @virtualProtect=Win32API.new('kernel32.dll','VirtualProtect','iiip','i')
  83.     @memcpy=Win32API.new('kernel32.dll','RtlMoveMemory','ipi','v')
  84.   end
  85.  
  86.   def InstallHook
  87.     hMod = @getModuleHandle.call('user32.dll')
  88.     @FuncAddr = @getProcAddress.call(hMod,'SetCursor')
  89.     unless @FuncAddr == 0
  90.       oldProtect = "\000" * 4
  91.       if @virtualProtect.call(@FuncAddr,5,PAGE_EXECUTE_READWRITE,oldProtect) != 0
  92.         @memcpy.call(@FuncAddr,"\xC2\x04\x00",3)
  93.         @virtualProtect.call(@FuncAddr,5,oldProtect.unpack('I')[0],nil)
  94.       end
  95.     end
  96.   end
  97.  
  98. end
  99.  
  100. DontSetCursor.new.InstallHook
  101. #-----------------------------------------------------------------------------
  102.  
  103. module Mouse_Hide
  104.  
  105. # 各种API定义
  106. GetCursorPos  = Win32API.new('user32', 'GetCursorPos'   , %w(p), 'l')
  107. ShowCursor    = Win32API.new('user32', 'ShowCursor'     , %w(l), 'l')
  108. SendMessage   = Win32API.new('user32.dll','SendMessageW','iiii','i')
  109. GetForegroundWindow = Win32API.new('user32.dll','GetForegroundWindow','v','i')
  110.  
  111. module_function
  112. def mouse_pos
  113.    pos = [0, 0].pack('ll')
  114.    GetCursorPos.call(pos)
  115.    return pos.unpack('ll')
  116. end # def
  117.  
  118. def cursorInClient?  #判断鼠标指针是否在客户区
  119.    x,y = mouse_pos
  120.    hr=SendMessage.call(get_hWnd,0x0084,0,MAKELONG(x,y)) #WM_NCHITTEST  HTCLIENT
  121.    hr==1 && hr != 0 && GetForegroundWindow.call == get_hWnd
  122. end
  123.  
  124. def fuckCursor(state)  # 没有比这个更贴切的名字了 = =
  125.    if state == :hide && @prevState != :hide
  126.      hr=ShowCursor.call(0)
  127.    elsif state == :show && @prevState != :show
  128.      hr=ShowCursor.call(1)  
  129.    end
  130.    @prevState = state
  131. end
  132.  
  133. def conditionally_mouse_hide
  134.     fuckCursor(cursorInClient? ? :hide : :show)
  135. end
  136.  
  137.  
  138. end#module
  139.  
  140.  
  141. #-----------------------------------------------------------------------------
  142. class << Graphics
  143.   alias :origin_update_dant :update
  144.   def update
  145.     origin_update_dant
  146.     Mouse_Hide.conditionally_mouse_hide
  147.   end
  148. end






欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1