Project1
标题:
重置RM窗口过程
[打印本页]
作者:
神思
时间:
2009-11-26 20:56
标题:
重置RM窗口过程
将RM的窗口过程加多了一层.
且可选择是否将原过程打断..
这样可以做很多东西..
例如屏蔽F1 或者 屏蔽全屏..
这些在默认都是通过消息来处理的``
或者手动发送一个全屏的消息..
不需要模拟键盘..
还有个比较好的地方.
就是鼠标可以脱离API..
MOUSEMOVE 消息附带坐标位置``呵呵..而且这东西是由系统回调的...
这样就不必每帧都GetCursorPos了。
拼命的晃动鼠标都没有掉帧的现象.
其实只要截取到了消息,自己接下来干啥都可以的了。
完一下以前的想法,呵呵
# API申明
module WM_API
# 寻找窗口
FindWindow = Win32API.new("user32", "FindWindow", "pp", "l")
# 重置窗口过程
ReSetProc = Win32API.new("WndProc.dll", "ReSetProc", "l", "l")
# 设置RGSSEval的库
SetDLL = Win32API.new("WndProc.dll", "SetDLL", "p", "v")
# 旧的过程
OldProc = Win32API.new("WndProc.dll", "OldProc", "llll", "l")
# 设置打断
SetBreak = Win32API.new("WndProc.dll", "SetBreak", "", "v")
# 发送消息
SendMessage = Win32API.new("user32", "SendMessage", "llll", "l")
# 设置鼠标显示
ShowCursor = Win32API.new("user32", "ShowCursor", "l", "l")
# 设置鼠标位置
SetMousePos = Win32API.new("WndProc.dll", "SetMousePos", "lll", "v")
# 读取INI
GetPrivateProfileString = Win32API.new("kernel32", "GetPrivateProfileString", "pppplp", "l")
end
# 参数表
module WM_MSG
# 关闭
WM_CLOSE = 0x0010
# 鼠标移动
WM_MOUSEMOVE = 0x0200
# 鼠标按键
WM_LBUTTONDOWN = 0x0201
WM_LBUTTONUP = 0x0202
WM_LBUTTONDBLCLK = 0x0203
WM_RBUTTONDOWN = 0x0204
WM_RBUTTONUP = 0x0205
WM_RBUTTONDBLCLK = 0x0206
WM_MBUTTONDOWN = 0x0207
WM_MBUTTONUP = 0x0208
WM_MBUTTONDBLCLK = 0x0209
WM_MOUSEWHEEL = 0x020a
# 全屏 or F2
WM_RM_FULL = 0x0111
# F1按下 or 小红叉
WM_RM_HELP = 0x0112
end
# 处理过程函数的模块
module WndProc
# API
include WM_API
# 消息常数
include WM_MSG
# 消息
#@@msg = []
# 函数
module_function
# 开始
def init
ShowCursor.call(0)
self.set_dll
self.re_set_proc
end
# 窗口句柄
def hWnd
buffer = "\000"*256
GetPrivateProfileString.call("Game", "Title", "", buffer, 256, "./Game.ini")
buffer.delete!("\000")
hWnd = FindWindow.call("RGSS Player", buffer)
end
# 设置RGSSEval库
def set_dll(libname="RGSS102J.dll")
SetDLL.call(libname)
end
# 重置回调函数
def re_set_proc
ReSetProc.call(hWnd)
end
# 新的回调
def proc(hWnd, message, wParam, lParam)
#@@msg << message unless @@msg.include? message
# 处理消息
case message
# 关闭
when WM_CLOSE # 关闭
when WM_MOUSEMOVE # 鼠标移动
# 低位为X
x = lParam & 0xFFFF
# 高位为Y
y = (lParam >> 16) & 0xFFFF
# 设置鼠标位置
Input.mouse.set_pos(x, y)
when WM_LBUTTONDOWN # 左按下
when WM_LBUTTONUP # 左松开
when WM_LBUTTONDBLCLK # 左双击
when WM_RBUTTONDOWN # 右按下
when WM_RBUTTONUP # 右松开
when WM_RBUTTONDBLCLK # 右双击
when WM_MBUTTONDOWN # 滚轮按下
when WM_MBUTTONUP # 滚轮松开
when WM_MBUTTONDBLCLK # 滚轮双击
when WM_MOUSEWHEEL # 滚轮转动
if(wParam > 0) # 向上滚
else # 向下滚
end
when WM_RM_HELP # F1, 关闭也是这个消息.不过参数不同.区分即可
if wParam == 40003 &&
lParam == 65536
break_rm();
end
when WM_RM_FULL # Alt + Enter or F2 按下,同样可以屏蔽
case wParam
# Alt + Enter 按下,同样可以屏蔽
when 105538 # Alt + Enter
# 加这个判断是为了,后面添加一个手动全屏幕的函数
if lParam == 0
break_rm();
end
# F2 按下,是可以打断的
when 105540 # F2
break_rm();
end
end
end
# 全屏
def full_screen
SendMessage.call(self.hWnd, WM_RM_FULL, 105538, 1)
end
# 打断RM的过程
def break_rm
SetBreak.call
end
end
# 简易鼠标
class Mouse
include WndProc
attr_reader :x
attr_reader :y
def initialize
@x = 0
@y = 0
@sprite = Sprite.new()
@sprite.bitmap = RPG::Cache.icon("001-Weapon01")
@sprite.z = 999999
@sprite.visible = false
set_visible(true)
end
def set_visible(bool)
@sprite.visible = bool
end
def set_pos(x, y)
@x = x
@y = y
@sprite.x = x
@sprite.y = y
end
end
class << Input
@@mouse = Mouse.new
alias mouse_update update
def mouse
return @@mouse
end
end
# 开始替换过程
WndProc.init
复制代码
WndProc.rar
2009-11-26 20:56 上传
点击文件名下载附件
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
// WndProc.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include<stdio.h>
// 窗口过程原型
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
// 旧的过程
WNDPROC OldWndProc;
// 连接库句柄
HINSTANCE hInst = NULL;
// RGSS
long (*LoadRGSS)(LPCTSTR);
BOOL BreakRM = false;
// 重置过程
extern "C" __declspec(dllexport) long ReSetProc(HWND hWnd)
{
OldWndProc = (WNDPROC)GetWindowLong(hWnd, GWL_WNDPROC);
return SetWindowLong(hWnd, GWL_WNDPROC, (long)WndProc);
}
// 设置RGSS连接库
extern "C" __declspec(dllexport) void SetDLL(LPCTSTR lib_name)
{
hInst = LoadLibrary(lib_name);
LoadRGSS = (long (*)(LPCTSTR))GetProcAddress(hInst, "RGSSEval");
}
extern "C" __declspec(dllexport) void OldProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
OldWndProc(hWnd, message, wParam, lParam);
}
extern "C" __declspec(dllexport) void SetBreak()
{
BreakRM = true;
}
extern "C" __declspec(dllexport) void SetMousePos(HWND hWnd, long x, long y)
{
SendMessage(hWnd, WM_MOUSEMOVE, 0, MAKEWPARAM(x, y));
}
// 窗口过程
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
char rgss[128];
sprintf(rgss, "WndProc.proc(%d,%d,%d,%d)", hWnd, message, wParam, lParam);
LoadRGSS(rgss);
if(!BreakRM)
return OldWndProc(hWnd, message, wParam, lParam);
else
BreakRM = false;
return 0;
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
复制代码
作者:
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