查看: 2313|回复: 3

[已经解决] 【 exit 与 X 】 区别,当玩家按X时,做点别的事情

[复制链接]
梦石
0
星屑
50
在线时间
521 小时
注册时间
2011-12-7
回帖
148
发表于 2013-8-11 17:27:08 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 Ceopal 于 2013-8-11 21:31 编辑


   1 exit  =  游戏窗右上 X 吗?

   2 有没有办法在游戏进程关闭时,运行一点代码再关闭?





@沙漠点灰 刚测试,很棒哎~!PS 你的游戏快点做~ MM4就看你的了~
梦石
0
星屑
660
在线时间
1286 小时
注册时间
2011-6-14
回帖
3949
发表于 2013-8-11 18:13:05 | 显示全部楼层
1.目测差不多
2.在非exit的时候(SceneManager.exit)貌似可以用END块实现,但我不知道怎么弄=-=
回复

使用道具 举报

梦石
0
星屑
55
在线时间
323 小时
注册时间
2010-8-21
回帖
638
发表于 2013-8-11 18:24:39 | 显示全部楼层
XP与VX点右上X将会调用exit方法,修改exit就能简单控制了。
Ace取消了,不过点击X系统会发送WM_CLOSE消息给窗口,拦截处理就行。
不过奇怪的是脚本运行完了(SceneManager.exit),系统没有发送WM_CLOSE、WM_DESTROY消息,貌似直接
发送WM_QUIT,程序直接退出了。

[pre lang="ruby" line="1"]#==============================================================================
# ■ 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)
[/pre]
自己修改 exit?方法就能处理了,SceneManager.exit直接退出

Exit.7z (3.12 KB, 下载次数: 58)
解压至/System文件夹,即RGSS300.dll同一目录,必须使用RGSS300.dll。

附dll源代码:
[pre lang="cpp" line="1"]#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");
}[/pre]

评分

参与人数 1梦石 +2 收起 理由
Sion + 2 认可答案

查看全部评分

>>猛戳>>MetalSagaR游戏主页<<这里<<
欢迎提供您的意见
回复

使用道具 举报

梦石
0
星屑
50
在线时间
521 小时
注册时间
2011-12-7
回帖
148
 楼主| 发表于 2013-8-11 19:38:54 | 显示全部楼层

【 exit 与 X 】 区别,当玩家按X时,做点别的事情

沙漠点灰 发表于 2013-8-11 18:24
XP与VX点右上X将会调用exit方法,修改exit就能简单控制了。
Ace取消了,不过点击X系统会发送WM_CLOSE消息给 ...

你的Exit.7z  点它

无标题.jpg

是attach文件吗,不能解压的吧? 还是说论坛下载出错了?

点评

论坛bug吧,改名字和后缀名  发表于 2013-8-11 20:03
回复

使用道具 举报

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

本版积分规则

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

在本版发帖返回顶部