Project1
标题: 【 exit 与 X 】 区别,当玩家按X时,做点别的事情 [打印本页]
作者: Ceopal 时间: 2013-8-11 17:27
标题: 【 exit 与 X 】 区别,当玩家按X时,做点别的事情
本帖最后由 Ceopal 于 2013-8-11 21:31 编辑
1 exit = 游戏窗右上 X 吗?
2 有没有办法在游戏进程关闭时,运行一点代码再关闭?
@沙漠点灰 刚测试,很棒哎~!PS 你的游戏快点做~ MM4就看你的了~
作者: satgo1546 时间: 2013-8-11 18:13
1.目测差不多
2.在非exit的时候(SceneManager.exit)貌似可以用END块实现,但我不知道怎么弄=-=
作者: 沙漠点灰 时间: 2013-8-11 18:24
XP与VX点右上X将会调用exit方法,修改exit就能简单控制了。
Ace取消了,不过点击X系统会发送WM_CLOSE消息给窗口,拦截处理就行。
不过奇怪的是脚本运行完了(SceneManager.exit),系统没有发送WM_CLOSE、WM_DESTROY消息,貌似直接
发送WM_QUIT,程序直接退出了。
#==============================================================================
# ■ 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
# 获取调用线程(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
return hWnd
end
end
def exit?
SceneManager.exit
end
$exit_hook = Win32API.new("System/Exit", "hookrgss", "l", "v")
$exit_hook.call(get_hWnd)
#==============================================================================
# ■ 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
# 获取调用线程(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
return hWnd
end
end
def exit?
SceneManager.exit
end
$exit_hook = Win32API.new("System/Exit", "hookrgss", "l", "v")
$exit_hook.call(get_hWnd)
自己修改 exit?方法就能处理了,SceneManager.exit直接退出
Exit.7z
(3.12 KB, 下载次数: 60)
解压至/System文件夹,即RGSS300.dll同一目录,必须使用RGSS300.dll。
附dll源代码:
#include <windows.h>
typedef DWORD (*EVALFUNC)(LPCSTR);
LONG oldWndProc;
EVALFUNC eval;
const char buf[] = "exit?";
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch(uMsg) {
case WM_CLOSE:
eval(buf);
return FALSE;
default:
return CallWindowProc((WNDPROC)oldWndProc, hWnd, uMsg, wParam, lParam);
}
}
extern "C" void __declspec(dllexport) hookrgss(HWND hwnd) {
HMODULE hRGSS;
oldWndProc = SetWindowLong(hwnd, GWL_WNDPROC, (LONG)WindowProc);
hRGSS = LoadLibrary(L"RGSS300.dll");
eval = (EVALFUNC)GetProcAddress(hRGSS, "RGSSEval");
}
#include <windows.h>
typedef DWORD (*EVALFUNC)(LPCSTR);
LONG oldWndProc;
EVALFUNC eval;
const char buf[] = "exit?";
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch(uMsg) {
case WM_CLOSE:
eval(buf);
return FALSE;
default:
return CallWindowProc((WNDPROC)oldWndProc, hWnd, uMsg, wParam, lParam);
}
}
extern "C" void __declspec(dllexport) hookrgss(HWND hwnd) {
HMODULE hRGSS;
oldWndProc = SetWindowLong(hwnd, GWL_WNDPROC, (LONG)WindowProc);
hRGSS = LoadLibrary(L"RGSS300.dll");
eval = (EVALFUNC)GetProcAddress(hRGSS, "RGSSEval");
}
作者: Ceopal 时间: 2013-8-11 19:38
标题: 【 exit 与 X 】 区别,当玩家按X时,做点别的事情
沙漠点灰 发表于 2013-8-11 18:24
XP与VX点右上X将会调用exit方法,修改exit就能简单控制了。
Ace取消了,不过点击X系统会发送WM_CLOSE消息给 ...
你的Exit.7z 点它
是attach文件吗,不能解压的吧? 还是说论坛下载出错了?
欢迎光临 Project1 (https://rpg.blue/) |
Powered by Discuz! X3.1 |