查看: 1991|回复: 1

[RMVA发布] ieval(读作山寨irb)以及紫苏的精确获取窗口句柄加强

[复制链接]

v

梦石
0
星屑
50
在线时间
55 小时
注册时间
2007-12-19
回帖
97
发表于 2012-12-30 06:52:51 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 veal 于 2013-1-5 17:56 编辑

山寨irb,
也就是read–eval–print loop,
可以eval控制台输入的内容,
主要用于ad hoc debug。
当然也可以像irb那样当作计算器和语法玩具:
1+1
=>2
def hello
  "hello from ieval!"
end
hello
=>"hello from ieval!"

二楼是紫苏的精确获取窗口句柄加强和用例。
[pre lang="ruby" line="1"]#encoding:utf-8
#==============================================================================
# ■ IEval v0.9
#------------------------------------------------------------------------------
#  读作:山寨irb
# 使用:
# - VA的情况下,确保使用控制台(VA编辑器菜单-测试-显示主控制台)
# - 调用ieval(binding)然后在控制台输入需要eval的指令
# - 例如在scene的update方法中加入 ieval(binding) if $TEST && Input.trigger?(:F5)
# 特点:
# - 可以分多行输入
# - 输入空行的话结束本次ieval调用
# - 临时变量全局保存,每次ieval均能获取之前设定的临时变量
# - 总之就是可以在RGSS上跑的弱化版irb
#==============================================================================
module IEval
#--------------------------------------------------------------------------
# ● ieval
#--------------------------------------------------------------------------
def ieval(bind)
# 载入保存的临时变量
prescript = ''
IEval.locals.each_key{|var| prescript << var.to_s + "= IEval.locals[:#{var}]\n"}
eval(prescript, bind)
# 开始ieval
script = ''
while true
print "ieval> "
line = gets
# ieval结束
if !line || line.strip.empty?
print "ieval end\n"
# 保存临时变量
eval("local_variables.each{|var| IEval.locals[var] = eval(var.to_s)}", bind)
return
# 运行输入的内容
else
script << line
begin
print "=> #{eval(script, bind)}\n"
script.clear
rescue SyntaxError => e
rescue Exception => e
p e
script.clear
end
end
end
end
#--------------------------------------------------------------------------
# ● eval局域临时变量保存
#--------------------------------------------------------------------------
@@locals = {}
def self.locals
return @@locals
end
#--------------------------------------------------------------------------
# ● 测试
#--------------------------------------------------------------------------
def self.test
loop do
p "=== another call to ieval ==="
ieval(binding)
end
end
end
include IEval
#IEval.test
[/pre]

v

梦石
0
星屑
50
在线时间
55 小时
注册时间
2007-12-19
回帖
97
 楼主| 发表于 2012-12-30 06:59:22 | 显示全部楼层
本帖最后由 veal 于 2012-12-30 07:14 编辑

精确获取窗口句柄加强,
添加获取控制台的窗口句柄和激活窗口,
主要目的是ieval调用时自动将焦点切换至控制台,
ieval结束时自动将焦点返回游戏
[pre lang="ruby" line="1"]#encoding:utf-8
#==============================================================================
# [XP/VX] 精确获取窗口句柄 by 紫苏
#==============================================================================
# ■ Kernel
#==============================================================================
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")
  SetForegroundWindow = Win32API.new("user32", "SetForegroundWindow", "L", "L")
  #--------------------------------------------------------------------------
  # ● 通过窗口类获取窗口句柄
  #--------------------------------------------------------------------------
  def get_thread_hwnd(class_name)
    # 获取调用线程(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)
        # 如果匹配 class_name 则跳出循环
        break if className == class_name
      end
      # 获取下一个窗口
      hWnd = GetWindow.call(hWnd, 2)
    end
    return hWnd
  end
  #--------------------------------------------------------------------------
  # ● 获取窗口句柄
  #--------------------------------------------------------------------------
  def get_hwnd
    return get_thread_hwnd("RGSS Player")
  end
  #--------------------------------------------------------------------------
  # ● 获取DEBUG窗口句柄
  #--------------------------------------------------------------------------
  def get_console_hwnd
    return get_thread_hwnd("ConsoleWind")
  end
  #--------------------------------------------------------------------------
  # ● 激活游戏窗口
  #--------------------------------------------------------------------------
  def foreground_game
    SetForegroundWindow.call(get_hwnd)
  end
  #--------------------------------------------------------------------------
  # ● 激活DEBUG窗口
  #--------------------------------------------------------------------------
  def foreground_console
    SetForegroundWindow.call(get_console_hwnd)
  end
end[/pre]
ieval用例
[pre lang="ruby" line="1"]#==============================================================================
# ■ Scene_Map
#------------------------------------------------------------------------------
#  地图画面
#==============================================================================

module SealTest_Scene_Map
  def update
    super
    update_console_debug
  end
  def update_console_debug
    if $TEST && Input.trigger?(:F5)
      foreground_console
      ieval(binding)
      foreground_game
    end
  end
end

class Scene_Map
  include SealTest_Scene_Map
end[/pre]
回复

使用道具 举报

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

本版积分规则

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

在本版发帖返回顶部