#----------------------------------------------------------------------------
# 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