Project1

标题: ieval(读作山寨irb)以及紫苏的精确获取窗口句柄加强 [打印本页]

作者: veal    时间: 2012-12-30 06:52
标题: ieval(读作山寨irb)以及紫苏的精确获取窗口句柄加强
本帖最后由 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!"

二楼是紫苏的精确获取窗口句柄加强和用例。
RUBY 代码复制
  1. #encoding:utf-8
  2. #==============================================================================
  3. # ■ IEval v0.9
  4. #------------------------------------------------------------------------------
  5. #  读作:山寨irb
  6. # 使用:
  7. # - VA的情况下,确保使用控制台(VA编辑器菜单-测试-显示主控制台)
  8. # - 调用ieval(binding)然后在控制台输入需要eval的指令
  9. # - 例如在scene的update方法中加入 ieval(binding) if $TEST && Input.trigger?(:F5)
  10. # 特点:
  11. # - 可以分多行输入
  12. # - 输入空行的话结束本次ieval调用
  13. # - 临时变量全局保存,每次ieval均能获取之前设定的临时变量
  14. # - 总之就是可以在RGSS上跑的弱化版irb
  15. #==============================================================================
  16. module IEval
  17. #--------------------------------------------------------------------------
  18. # ● ieval
  19. #--------------------------------------------------------------------------
  20. def ieval(bind)
  21. # 载入保存的临时变量
  22. prescript = ''
  23. IEval.locals.each_key{|var| prescript << var.to_s + "= IEval.locals[:#{var}]\n"}
  24. eval(prescript, bind)
  25. # 开始ieval
  26. script = ''
  27. while true
  28. print "ieval> "
  29. line = gets
  30. # ieval结束
  31. if !line || line.strip.empty?
  32. print "ieval end\n"
  33. # 保存临时变量
  34. eval("local_variables.each{|var| IEval.locals[var] = eval(var.to_s)}", bind)
  35. return
  36. # 运行输入的内容
  37. else
  38. script << line
  39. begin
  40. print "=> #{eval(script, bind)}\n"
  41. script.clear
  42. rescue SyntaxError => e
  43. rescue Exception => e
  44. p e
  45. script.clear
  46. end
  47. end
  48. end
  49. end
  50. #--------------------------------------------------------------------------
  51. # ● eval局域临时变量保存
  52. #--------------------------------------------------------------------------
  53. @@locals = {}
  54. def self.locals
  55. return @@locals
  56. end
  57. #--------------------------------------------------------------------------
  58. # ● 测试
  59. #--------------------------------------------------------------------------
  60. def self.test
  61. loop do
  62. p "=== another call to ieval ==="
  63. ieval(binding)
  64. end
  65. end
  66. end
  67. include IEval
  68. #IEval.test


作者: veal    时间: 2012-12-30 06:59
本帖最后由 veal 于 2012-12-30 07:14 编辑

精确获取窗口句柄加强,
添加获取控制台的窗口句柄和激活窗口,
主要目的是ieval调用时自动将焦点切换至控制台,
ieval结束时自动将焦点返回游戏
RUBY 代码复制
  1. #encoding:utf-8
  2. #==============================================================================
  3. # [XP/VX] 精确获取窗口句柄 by 紫苏
  4. #==============================================================================
  5. # ■ Kernel
  6. #==============================================================================
  7. module Kernel
  8.   #--------------------------------------------------------------------------
  9.   # ● 需要的 Windows API 函数
  10.   #--------------------------------------------------------------------------
  11.   GetWindowThreadProcessId = Win32API.new("user32", "GetWindowThreadProcessId", "LP", "L")
  12.   GetWindow = Win32API.new("user32", "GetWindow", "LL", "L")
  13.   GetClassName = Win32API.new("user32", "GetClassName", "LPL", "L")
  14.   GetCurrentThreadId = Win32API.new("kernel32", "GetCurrentThreadId", "V", "L")
  15.   GetForegroundWindow = Win32API.new("user32", "GetForegroundWindow", "V", "L")
  16.   SetForegroundWindow = Win32API.new("user32", "SetForegroundWindow", "L", "L")
  17.   #--------------------------------------------------------------------------
  18.   # ● 通过窗口类获取窗口句柄
  19.   #--------------------------------------------------------------------------
  20.   def get_thread_hwnd(class_name)
  21.     # 获取调用线程(RM 的主线程)的进程标识
  22.     threadID = GetCurrentThreadId.call
  23.     # 获取 Z 次序中最靠前的窗口
  24.     hWnd = GetWindow.call(GetForegroundWindow.call, 0)
  25.     # 枚举所有窗口
  26.     while hWnd != 0
  27.       # 如果创建该窗口的线程标识匹配本线程标识
  28.       if threadID == GetWindowThreadProcessId.call(hWnd, 0)
  29.         # 分配一个 11 个字节的缓冲区
  30.         className = " " * 11
  31.         # 获取该窗口的类名
  32.         GetClassName.call(hWnd, className, 12)
  33.         # 如果匹配 class_name 则跳出循环
  34.         break if className == class_name
  35.       end
  36.       # 获取下一个窗口
  37.       hWnd = GetWindow.call(hWnd, 2)
  38.     end
  39.     return hWnd
  40.   end
  41.   #--------------------------------------------------------------------------
  42.   # ● 获取窗口句柄
  43.   #--------------------------------------------------------------------------
  44.   def get_hwnd
  45.     return get_thread_hwnd("RGSS Player")
  46.   end
  47.   #--------------------------------------------------------------------------
  48.   # ● 获取DEBUG窗口句柄
  49.   #--------------------------------------------------------------------------
  50.   def get_console_hwnd
  51.     return get_thread_hwnd("ConsoleWind")
  52.   end
  53.   #--------------------------------------------------------------------------
  54.   # ● 激活游戏窗口
  55.   #--------------------------------------------------------------------------
  56.   def foreground_game
  57.     SetForegroundWindow.call(get_hwnd)
  58.   end
  59.   #--------------------------------------------------------------------------
  60.   # ● 激活DEBUG窗口
  61.   #--------------------------------------------------------------------------
  62.   def foreground_console
  63.     SetForegroundWindow.call(get_console_hwnd)
  64.   end
  65. end

ieval用例
RUBY 代码复制
  1. #==============================================================================
  2. # ■ Scene_Map
  3. #------------------------------------------------------------------------------
  4. #  地图画面
  5. #==============================================================================
  6.  
  7. module SealTest_Scene_Map
  8.   def update
  9.     super
  10.     update_console_debug
  11.   end
  12.   def update_console_debug
  13.     if $TEST && Input.trigger?(:F5)
  14.       foreground_console
  15.       ieval(binding)
  16.       foreground_game
  17.     end
  18.   end
  19. end
  20.  
  21. class Scene_Map
  22.   include SealTest_Scene_Map
  23. end





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