Project1

标题: 重置RM窗口过程 [打印本页]

作者: 神思    时间: 2009-11-26 20:56
标题: 重置RM窗口过程
将RM的窗口过程加多了一层.
且可选择是否将原过程打断..

这样可以做很多东西..
例如屏蔽F1 或者 屏蔽全屏..
这些在默认都是通过消息来处理的``
或者手动发送一个全屏的消息..
不需要模拟键盘..

还有个比较好的地方.
就是鼠标可以脱离API..
MOUSEMOVE 消息附带坐标位置``呵呵..而且这东西是由系统回调的...
这样就不必每帧都GetCursorPos了。
拼命的晃动鼠标都没有掉帧的现象.

其实只要截取到了消息,自己接下来干啥都可以的了。

完一下以前的想法,呵呵
  1. # API申明
  2. module WM_API
  3.   # 寻找窗口
  4.   FindWindow = Win32API.new("user32", "FindWindow", "pp", "l")
  5.   # 重置窗口过程
  6.   ReSetProc = Win32API.new("WndProc.dll", "ReSetProc", "l", "l")
  7.   # 设置RGSSEval的库
  8.   SetDLL = Win32API.new("WndProc.dll", "SetDLL", "p", "v")
  9.   # 旧的过程
  10.   OldProc = Win32API.new("WndProc.dll", "OldProc", "llll", "l")
  11.   # 设置打断
  12.   SetBreak = Win32API.new("WndProc.dll", "SetBreak", "", "v")
  13.   # 发送消息
  14.   SendMessage = Win32API.new("user32", "SendMessage", "llll", "l")
  15.   # 设置鼠标显示
  16.   ShowCursor = Win32API.new("user32", "ShowCursor", "l", "l")
  17.   # 设置鼠标位置
  18.   SetMousePos = Win32API.new("WndProc.dll", "SetMousePos", "lll", "v")
  19.   # 读取INI
  20.   GetPrivateProfileString = Win32API.new("kernel32", "GetPrivateProfileString", "pppplp", "l")

  21. end
  22. # 参数表
  23. module WM_MSG
  24.   # 关闭
  25.   WM_CLOSE                      = 0x0010
  26.   # 鼠标移动
  27.   WM_MOUSEMOVE                  = 0x0200
  28.   # 鼠标按键
  29.   WM_LBUTTONDOWN                = 0x0201
  30.   WM_LBUTTONUP                  = 0x0202
  31.   WM_LBUTTONDBLCLK              = 0x0203
  32.   WM_RBUTTONDOWN                = 0x0204
  33.   WM_RBUTTONUP                  = 0x0205
  34.   WM_RBUTTONDBLCLK              = 0x0206
  35.   WM_MBUTTONDOWN                = 0x0207
  36.   WM_MBUTTONUP                  = 0x0208
  37.   WM_MBUTTONDBLCLK              = 0x0209
  38.   WM_MOUSEWHEEL                 = 0x020a
  39.   # 全屏 or F2
  40.   WM_RM_FULL                    = 0x0111
  41.   # F1按下 or 小红叉
  42.   WM_RM_HELP                    = 0x0112
  43. end
  44. # 处理过程函数的模块
  45. module WndProc
  46.   # API
  47.   include WM_API
  48.   # 消息常数
  49.   include WM_MSG
  50.   # 消息
  51.   #@@msg = []
  52.   # 函数
  53.   module_function
  54.   # 开始
  55.   def init
  56.     ShowCursor.call(0)
  57.     self.set_dll
  58.     self.re_set_proc
  59.   end
  60.   # 窗口句柄
  61.   def hWnd
  62.     buffer = "\000"*256
  63.     GetPrivateProfileString.call("Game", "Title", "", buffer, 256, "./Game.ini")
  64.     buffer.delete!("\000")
  65.     hWnd = FindWindow.call("RGSS Player", buffer)
  66.   end
  67.   # 设置RGSSEval库
  68.   def set_dll(libname="RGSS102J.dll")
  69.     SetDLL.call(libname)
  70.   end
  71.   # 重置回调函数
  72.   def re_set_proc
  73.     ReSetProc.call(hWnd)
  74.   end
  75.   # 新的回调
  76.   def proc(hWnd, message, wParam, lParam)
  77.     #@@msg << message unless @@msg.include? message
  78.     # 处理消息
  79.     case message
  80.     # 关闭
  81.     when WM_CLOSE           # 关闭
  82.     when WM_MOUSEMOVE       # 鼠标移动
  83.       # 低位为X
  84.       x = lParam & 0xFFFF
  85.       # 高位为Y
  86.       y = (lParam >> 16) & 0xFFFF
  87.       # 设置鼠标位置
  88.       Input.mouse.set_pos(x, y)
  89.     when WM_LBUTTONDOWN     # 左按下
  90.     when WM_LBUTTONUP       # 左松开
  91.     when WM_LBUTTONDBLCLK   # 左双击
  92.     when WM_RBUTTONDOWN     # 右按下
  93.     when WM_RBUTTONUP       # 右松开
  94.     when WM_RBUTTONDBLCLK   # 右双击
  95.     when WM_MBUTTONDOWN     # 滚轮按下
  96.     when WM_MBUTTONUP       # 滚轮松开
  97.     when WM_MBUTTONDBLCLK   # 滚轮双击
  98.     when WM_MOUSEWHEEL      # 滚轮转动
  99.       if(wParam > 0)        # 向上滚
  100.       else                  # 向下滚
  101.       end
  102.     when WM_RM_HELP         # F1, 关闭也是这个消息.不过参数不同.区分即可
  103.       if wParam == 40003 &&
  104.         lParam == 65536
  105.         break_rm();
  106.       end
  107.     when WM_RM_FULL         # Alt + Enter or F2 按下,同样可以屏蔽
  108.       case wParam
  109.       # Alt + Enter 按下,同样可以屏蔽
  110.       when 105538           # Alt + Enter
  111.         # 加这个判断是为了,后面添加一个手动全屏幕的函数
  112.         if lParam == 0
  113.           break_rm();
  114.         end
  115.       # F2 按下,是可以打断的
  116.       when 105540           # F2
  117.          break_rm();
  118.       end
  119.     end
  120.   end
  121.   # 全屏
  122.   def full_screen
  123.     SendMessage.call(self.hWnd, WM_RM_FULL, 105538, 1)
  124.   end
  125.   # 打断RM的过程
  126.   def break_rm
  127.     SetBreak.call
  128.   end
  129. end
  130. # 简易鼠标
  131. class Mouse
  132.   include WndProc
  133.   attr_reader   :x
  134.   attr_reader   :y
  135.   def initialize
  136.     @x = 0
  137.     @y = 0
  138.     @sprite = Sprite.new()
  139.     @sprite.bitmap = RPG::Cache.icon("001-Weapon01")
  140.     @sprite.z = 999999
  141.     @sprite.visible = false
  142.     set_visible(true)
  143.   end
  144.   def set_visible(bool)
  145.     @sprite.visible = bool
  146.   end
  147.   def set_pos(x, y)
  148.     @x = x
  149.     @y = y
  150.     @sprite.x = x
  151.     @sprite.y = y
  152.   end
  153. end
  154. class << Input
  155.   @@mouse = Mouse.new
  156.   alias mouse_update update
  157.   def mouse
  158.     return @@mouse
  159.   end
  160. end
  161. # 开始替换过程
  162. WndProc.init
复制代码

WndProc.rar

14.09 KB, 下载次数: 244


作者: 奶油Da蛋糕    时间: 2009-11-26 21:45
强大。
看到深思了,来膜拜下。
大家无视我好了。
沙发!
作者: 后知后觉    时间: 2009-11-26 21:48
这个....和 【真·后台运行】有冲突么?....
作者: 神思    时间: 2009-11-26 21:52
只要没有涉及到窗口过程就应该不会由问题吧.-__________-||||
作者: 后知后觉    时间: 2009-11-26 22:07
那个就是用到了窗口过程我才这样问的嘛- -
用的是夏娜写的那个窗口过程
作者: 神思    时间: 2009-11-26 22:12
-_____-那一定会出事......
窗口毕竟只能存在一个回调函数.....

做这个东西唯一的新发现就是
0x0111这个全屏消息可以手动SendMessage到RM``然后让他全屏.......
模拟按键经常会出现不弹出来的情况.....
作者: 神思    时间: 2009-11-26 22:22
不过同样可以截取WM_ACTIVATEAPP这个消息..然后break_rm();...后台运行就OK了-___________-|||
作者: 后知后觉    时间: 2009-11-26 22:30
哦.这样的啊.明白了.谢谢了!
作者: 神思    时间: 2009-11-26 22:58
呵呵``客气了.
-_______-最近房东把网速给限制了````
刷新一下都要N++久
作者: orochi2k    时间: 2009-11-27 00:16
求动态链接库源码 囧
作者: 神思    时间: 2009-11-27 01:00
VC6下编译OK
  1. // WndProc.cpp : Defines the entry point for the DLL application.
  2. //
  3. #include "stdafx.h"
  4. #include<stdio.h>
  5. // 窗口过程原型
  6. LRESULT CALLBACK        WndProc(HWND, UINT, WPARAM, LPARAM);
  7. // 旧的过程
  8. WNDPROC OldWndProc;
  9. // 连接库句柄
  10. HINSTANCE hInst = NULL;
  11. // RGSS
  12. long (*LoadRGSS)(LPCTSTR);
  13. BOOL BreakRM = false;
  14. // 重置过程
  15. extern "C" __declspec(dllexport) long ReSetProc(HWND hWnd)
  16. {
  17.          OldWndProc = (WNDPROC)GetWindowLong(hWnd, GWL_WNDPROC);
  18.          return SetWindowLong(hWnd, GWL_WNDPROC, (long)WndProc);
  19. }
  20. // 设置RGSS连接库
  21. extern "C" __declspec(dllexport) void SetDLL(LPCTSTR lib_name)
  22. {
  23.          hInst = LoadLibrary(lib_name);
  24.          LoadRGSS = (long (*)(LPCTSTR))GetProcAddress(hInst, "RGSSEval");
  25. }
  26. extern "C" __declspec(dllexport) void OldProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  27. {
  28.          OldWndProc(hWnd, message, wParam, lParam);
  29. }
  30. extern "C" __declspec(dllexport) void SetBreak()
  31. {
  32.          BreakRM = true;
  33. }
  34. extern "C" __declspec(dllexport) void SetMousePos(HWND hWnd, long x, long y)
  35. {
  36.         SendMessage(hWnd, WM_MOUSEMOVE, 0, MAKEWPARAM(x, y));
  37. }
  38. // 窗口过程
  39. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  40. {
  41.         char rgss[128];
  42.         sprintf(rgss, "WndProc.proc(%d,%d,%d,%d)", hWnd, message, wParam, lParam);
  43.         LoadRGSS(rgss);
  44.         if(!BreakRM)
  45.                 return OldWndProc(hWnd, message, wParam, lParam);
  46.         else
  47.                 BreakRM = false;
  48.                 return 0;
  49. }
  50. BOOL APIENTRY DllMain( HANDLE hModule,
  51.                        DWORD  ul_reason_for_call,
  52.                        LPVOID lpReserved
  53.                                          )
  54. {
  55.     return TRUE;
  56. }

复制代码

作者: orochi2k    时间: 2009-11-27 10:52
感谢神思,偶去学习一下 囧
作者: 神思    时间: 2009-11-27 22:37
呵呵...小蛇子客气了.
作者: guyun    时间: 2009-11-27 23:44
提示: 作者被禁止或删除 内容自动屏蔽
作者: 咳嗽的夜鸟    时间: 2009-12-1 17:31
提示: 作者被禁止或删除 内容自动屏蔽
作者: 神思    时间: 2009-12-2 12:41
用个全局变量转接过去..
作者: 瓦沙尔    时间: 2009-12-12 19:08
提示: 作者被禁止或删除 内容自动屏蔽




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