| 
 
| 赞 | 0 |  
| VIP | 15 |  
| 好人卡 | 13 |  
| 积分 | 1 |  
| 经验 | 11002 |  
| 最后登录 | 2023-7-14 |  
| 在线时间 | 156 小时 |  
 Lv1.梦旅人 
	梦石0 星屑60 在线时间156 小时注册时间2011-12-13帖子133 | 
| 
继不隐藏鼠标指针之后
x
加入我们,或者,欢迎回来。您需要 登录 才可以下载或查看,没有帐号?注册会员  继续玩一下鼠标指针[误]
 其实是@各种压力的猫君要的
 在@凌依约在http://rpg.blue/forum.php?mod=viewthread&tid=221745&page=1#pid1846645发布的脚本的基础上[真的是“基础”吗?]修改而成
 实现了在客户区内隐藏鼠标指针,在非客户区不隐藏
 不过F1有点问题 = =
   
 
 #----------------------------------------------------------------------------#  SmartCursor - 有条件地显示鼠标##   VX&VA 测试通过,XP请将108行处的"SendMessaeW"改为"DefWindowProcA"#   使用方法:在Main前插入脚本即可,越前越好#   已知问题:弹出F1那个框框时,如果鼠标指针在游戏窗口的客户区内,则不会#   显示鼠标指针。#---------------------------------------------------------------------------- #==============================================================================# ■ Kernel#------------------------------------------------------------------------------#  该模块中定义了可供所有类使用的方法。Object 类中包含了该模块。#==============================================================================module Kernel  #--------------------------------------------------------------------------  # ● 需要的 Windows API 函数  #--------------------------------------------------------------------------  GetWindowThreadProcessId = Win32API.new("user32", "GetWindowThreadProcessId", "LP", "L")  GetWindow = Win32API.new("user32", "GetWindow", "LL", "L")  GetClassName = Win32API.new("user32", "GetClassName", "LPL", "L")  GetCurrentThreadId = Win32API.new("kernel32", "GetCurrentThreadId", "V", "L")  GetForegroundWindow = Win32API.new("user32", "GetForegroundWindow", "V", "L")  #--------------------------------------------------------------------------  # ● 获取窗口句柄  #--------------------------------------------------------------------------  def get_hWnd    return @hwnd if @hwnd  ########    # 获取调用线程(RM 的主线程)的进程标识    threadID = GetCurrentThreadId.call    # 获取 Z 次序中最靠前的窗口    hWnd = GetWindow.call(GetForegroundWindow.call, 0)    # 枚举所有窗口    while hWnd != 0      # 如果创建该窗口的线程标识匹配本线程标识      if threadID == GetWindowThreadProcessId.call(hWnd, 0)        # 分配一个 11 个字节的缓冲区        className = " " * 11        # 获取该窗口的类名        GetClassName.call(hWnd, className, 12)        # 如果匹配 RGSS Player 则跳出循环        break if className == "RGSS Player"      end      # 获取下一个窗口      hWnd = GetWindow.call(hWnd, 2)    end    @hwnd=hWnd    ########    return hWnd  end   def MAKELONG(wLow,wHigh)    (wLow&0xFFFF)|((wHigh<<16)&0xFFFF0000)  end end #----------------------------------------------------------------------------$dant_ShowCursor = Win32API.new('user32', 'ShowCursor', %w(l), 'l')$dant_WFP = Win32API.new('user32', 'WindowFromPoint', 'ii', 'l')$dant_GCP  = Win32API.new('user32', 'GetCursorPos'   , %w(p), 'l')$dant_buf = "\000"*8$dant_GCP.call($dant_buf)$dant_x,$dant_y = $dant_buf.unpack('II')if $dant_WFP.call($dant_x,$dant_y) != get_hWnd  $dant_ShowCursor.call(0)end$dant_WFP        = nil$dant_GCP        = nil$dant_ShowCursor = nil$dant_x          = nil$dant_y          = nil$dant_buf        = nil#---------------------------------------------------------------------------- class DontSetCursor   PAGE_EXECUTE_READWRITE = 0x40   def initialize    @getModuleHandle=Win32API.new('kernel32.dll','GetModuleHandleA','p','i')    @getProcAddress=Win32API.new('kernel32.dll','GetProcAddress','ip','i')    @virtualProtect=Win32API.new('kernel32.dll','VirtualProtect','iiip','i')    @memcpy=Win32API.new('kernel32.dll','RtlMoveMemory','ipi','v')  end   def InstallHook    hMod = @getModuleHandle.call('user32.dll')    @FuncAddr = @getProcAddress.call(hMod,'SetCursor')    unless @FuncAddr == 0      oldProtect = "\000" * 4      if @virtualProtect.call(@FuncAddr,5,PAGE_EXECUTE_READWRITE,oldProtect) != 0        @memcpy.call(@FuncAddr,"\xC2\x04\x00",3)        @virtualProtect.call(@FuncAddr,5,oldProtect.unpack('I')[0],nil)      end    end  end end DontSetCursor.new.InstallHook#----------------------------------------------------------------------------- module Mouse_Hide  # 各种API定义 GetCursorPos  = Win32API.new('user32', 'GetCursorPos'   , %w(p), 'l') ShowCursor    = Win32API.new('user32', 'ShowCursor'     , %w(l), 'l') SendMessage   = Win32API.new('user32.dll','SendMessageW','iiii','i') GetForegroundWindow = Win32API.new('user32.dll','GetForegroundWindow','v','i') module_function  def mouse_pos   pos = [0, 0].pack('ll')   GetCursorPos.call(pos)   return pos.unpack('ll')  end # def  def cursorInClient?  #判断鼠标指针是否在客户区   x,y = mouse_pos   hr=SendMessage.call(get_hWnd,0x0084,0,MAKELONG(x,y)) #WM_NCHITTEST  HTCLIENT   hr==1 && hr != 0 && GetForegroundWindow.call == get_hWnd  end   def fuckCursor(state)  # 没有比这个更贴切的名字了 = =   if state == :hide && @prevState != :hide     hr=ShowCursor.call(0)   elsif state == :show && @prevState != :show     hr=ShowCursor.call(1)     end   @prevState = state end  def conditionally_mouse_hide    fuckCursor(cursorInClient? ? :hide : :show) end  end#module  #-----------------------------------------------------------------------------class << Graphics  alias :origin_update_dant :update  def update    origin_update_dant    Mouse_Hide.conditionally_mouse_hide  endend
#---------------------------------------------------------------------------- 
#  SmartCursor - 有条件地显示鼠标 
# 
#   VX&VA 测试通过,XP请将108行处的"SendMessaeW"改为"DefWindowProcA" 
#   使用方法:在Main前插入脚本即可,越前越好 
#   已知问题:弹出F1那个框框时,如果鼠标指针在游戏窗口的客户区内,则不会 
#   显示鼠标指针。 
#---------------------------------------------------------------------------- 
  
#============================================================================== 
# ■ Kernel 
#------------------------------------------------------------------------------ 
#  该模块中定义了可供所有类使用的方法。Object 类中包含了该模块。 
#============================================================================== 
module Kernel 
  #-------------------------------------------------------------------------- 
  # ● 需要的 Windows API 函数 
  #-------------------------------------------------------------------------- 
  GetWindowThreadProcessId = Win32API.new("user32", "GetWindowThreadProcessId", "LP", "L") 
  GetWindow = Win32API.new("user32", "GetWindow", "LL", "L") 
  GetClassName = Win32API.new("user32", "GetClassName", "LPL", "L") 
  GetCurrentThreadId = Win32API.new("kernel32", "GetCurrentThreadId", "V", "L") 
  GetForegroundWindow = Win32API.new("user32", "GetForegroundWindow", "V", "L") 
  #-------------------------------------------------------------------------- 
  # ● 获取窗口句柄 
  #-------------------------------------------------------------------------- 
  def get_hWnd 
    return @hwnd if @hwnd  ######## 
    # 获取调用线程(RM 的主线程)的进程标识 
    threadID = GetCurrentThreadId.call 
    # 获取 Z 次序中最靠前的窗口 
    hWnd = GetWindow.call(GetForegroundWindow.call, 0) 
    # 枚举所有窗口 
    while hWnd != 0 
      # 如果创建该窗口的线程标识匹配本线程标识 
      if threadID == GetWindowThreadProcessId.call(hWnd, 0) 
        # 分配一个 11 个字节的缓冲区 
        className = " " * 11 
        # 获取该窗口的类名 
        GetClassName.call(hWnd, className, 12) 
        # 如果匹配 RGSS Player 则跳出循环 
        break if className == "RGSS Player" 
      end 
      # 获取下一个窗口 
      hWnd = GetWindow.call(hWnd, 2) 
    end 
    @hwnd=hWnd    ######## 
    return hWnd 
  end 
  
  def MAKELONG(wLow,wHigh) 
    (wLow&0xFFFF)|((wHigh<<16)&0xFFFF0000) 
  end 
  
end 
  
#---------------------------------------------------------------------------- 
$dant_ShowCursor = Win32API.new('user32', 'ShowCursor', %w(l), 'l') 
$dant_WFP = Win32API.new('user32', 'WindowFromPoint', 'ii', 'l') 
$dant_GCP  = Win32API.new('user32', 'GetCursorPos'   , %w(p), 'l') 
$dant_buf = "\000"*8 
$dant_GCP.call($dant_buf) 
$dant_x,$dant_y = $dant_buf.unpack('II') 
if $dant_WFP.call($dant_x,$dant_y) != get_hWnd 
  $dant_ShowCursor.call(0) 
end 
$dant_WFP        = nil 
$dant_GCP        = nil 
$dant_ShowCursor = nil 
$dant_x          = nil 
$dant_y          = nil 
$dant_buf        = nil 
#---------------------------------------------------------------------------- 
  
class DontSetCursor 
  
  PAGE_EXECUTE_READWRITE = 0x40 
  
  def initialize 
    @getModuleHandle=Win32API.new('kernel32.dll','GetModuleHandleA','p','i') 
    @getProcAddress=Win32API.new('kernel32.dll','GetProcAddress','ip','i') 
    @virtualProtect=Win32API.new('kernel32.dll','VirtualProtect','iiip','i') 
    @memcpy=Win32API.new('kernel32.dll','RtlMoveMemory','ipi','v') 
  end 
  
  def InstallHook 
    hMod = @getModuleHandle.call('user32.dll') 
    @FuncAddr = @getProcAddress.call(hMod,'SetCursor') 
    unless @FuncAddr == 0 
      oldProtect = "\000" * 4 
      if @virtualProtect.call(@FuncAddr,5,PAGE_EXECUTE_READWRITE,oldProtect) != 0 
        @memcpy.call(@FuncAddr,"\xC2\x04\x00",3) 
        @virtualProtect.call(@FuncAddr,5,oldProtect.unpack('I')[0],nil) 
      end 
    end 
  end 
  
end 
  
DontSetCursor.new.InstallHook 
#----------------------------------------------------------------------------- 
  
module Mouse_Hide 
  
 # 各种API定义 
 GetCursorPos  = Win32API.new('user32', 'GetCursorPos'   , %w(p), 'l') 
 ShowCursor    = Win32API.new('user32', 'ShowCursor'     , %w(l), 'l') 
 SendMessage   = Win32API.new('user32.dll','SendMessageW','iiii','i') 
 GetForegroundWindow = Win32API.new('user32.dll','GetForegroundWindow','v','i') 
  
module_function  
 def mouse_pos 
   pos = [0, 0].pack('ll') 
   GetCursorPos.call(pos) 
   return pos.unpack('ll')  
 end # def 
  
 def cursorInClient?  #判断鼠标指针是否在客户区 
   x,y = mouse_pos 
   hr=SendMessage.call(get_hWnd,0x0084,0,MAKELONG(x,y)) #WM_NCHITTEST  HTCLIENT 
   hr==1 && hr != 0 && GetForegroundWindow.call == get_hWnd  
 end  
  
 def fuckCursor(state)  # 没有比这个更贴切的名字了 = = 
   if state == :hide && @prevState != :hide 
     hr=ShowCursor.call(0) 
   elsif state == :show && @prevState != :show 
     hr=ShowCursor.call(1)   
   end 
   @prevState = state 
 end 
  
 def conditionally_mouse_hide 
    fuckCursor(cursorInClient? ? :hide : :show) 
 end 
  
  
end#module 
  
  
#----------------------------------------------------------------------------- 
class << Graphics 
  alias :origin_update_dant :update 
  def update 
    origin_update_dant 
    Mouse_Hide.conditionally_mouse_hide 
  end 
end 
 | 
 |