查看: 2605|回复: 0

[通用发布] 有条件地显示鼠标

[复制链接]
梦石
0
星屑
60
在线时间
156 小时
注册时间
2011-12-13
回帖
127
发表于 2012-2-8 11:22:14 | 显示全部楼层 |阅读模式

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

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

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

[pre lang="ruby" line="1"]#----------------------------------------------------------------------------
#  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
[/pre]
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部