设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 13135|回复: 11
打印 上一主题 下一主题

[RMVX发布] [RMVX] 真·后台运行(2009/11/25 重要更新)

 关闭 [复制链接]

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
跳转到指定楼层
1
发表于 2009-7-14 15:46:06 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式

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

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

x
本帖最后由 紫苏 于 2009-11-25 11:30 编辑

RMVXBR.rar (258.57 KB, 下载次数: 2818)

2009/07/14:
  • 修正了 DLL 是调试编译,而非独立 DLL 的问题;
  • 修正了窗口不在键盘焦点时按键按下仍然保持失去焦点前状态的问题(例:地图上按住 ←,切换到其它窗口,角色就会一直保持左移)


2009/09/01:
  • 修正了 DLL 中获取窗口句柄潜在的问题(详情请阅读:http://rpg.blue/viewthread.php?tid=133018);
  • 将获取窗口句柄的操作放到了 Start 函数中;
  • 添加对 Input.trigger? 的键盘焦点判断;
  • 修改了 DLL 的文件名,这样 RMXP 和 RMVX 都可以使用同一份 DLL


2009/11/25:
  • 改变后台运行 DLL 为静态链接 C 运行时(CRT),这样在没有安装 CRT 的平台上也能使用该 DLL。这个改变增加了约 5 倍于原 DLL 的文件大小


前不久刚发布了 RMXP 真·后台运行,当时感觉应该可以直接应用到 RMVX,结果 zh 测试后发现会发生错误。

通过调试发现,在 DLL 中不能直接调用老的窗口过程函数,而必须把地址传递给 CallWindowProc 函数让它来调用,否则在 VX 中就会出错,原因按照 MSDN 的说法,是因为 SetWindowLong 的返回值可能是函数地址,也可能是一个只对 CallWindowProc 有意义的特殊值~

修改为调用 CallWindowProc 之后,倒是不会出错了,但却又衍生出新的问题——在程序响应移动窗口、最大化、最小化等窗口消息时十分缓慢,原因不明……

于是今天尝试把拦截 WM_ACTIVATEAPP 的过程直接写到 DLL 中,测试就冇问题了 = =||
推测之前的问题可能是由于 RGSS2***.dll 中的 RGSSEval 函数效率不及 RGSS1***.dll 的,导致在 dll 中解释 Ruby 窗口过程缓慢……

用法见范例工程,绑定失去焦点时不响应键盘功能,否则可能被杀软认为是 keylogger~
请务必保留 Lib 文件夹 以及其中的 BackgroundRunning.dll

调用源代码:
  1. unless $_Start


  2. $_Start = Win32API.new("Lib/BackgroundRunning","Start",'V','L')
  3. $_Stop = Win32API.new("Lib/BackgroundRunning","Stop",'V','L')
  4. $_OnFocus = Win32API.new("Lib/BackgroundRunning","OnFocus",'V','L')

  5. $_Start.call

  6. module Input
  7.   InputUpdate = method :update
  8.   InputTrigger = method :trigger?
  9.   InputPress = method :press?
  10.   InputRepeat = method :repeat?
  11.   InputDir4 = method :dir4
  12.   InputDir8 = method :dir8
  13.   def self.update
  14.     InputUpdate.call if $_OnFocus.call != 0
  15.   end
  16.   def self.trigger?(num)
  17.     return $_OnFocus.call != 0 ? InputTrigger.call(num) : false
  18.   end
  19.   def self.press?(num)
  20.     return $_OnFocus.call != 0 ? InputPress.call(num) : false
  21.   end
  22.   def self.repeat?(num)
  23.     return $_OnFocus.call != 0 ? InputRepeat.call(num) : false
  24.   end
  25.   def self.dir4
  26.     return $_OnFocus.call != 0 ? InputDir4.call : 0   
  27.   end
  28.   def self.dir8
  29.     return $_OnFocus.call != 0 ? InputDir8.call : 0   
  30.   end
  31. end


  32. end
复制代码
DLL 源代码:

  1. #include <windows.h>
  2. #include <stdio.h>

  3. HWND g_hWnd = NULL;
  4. LONG g_pOldWndProc = NULL;
  5. BOOL g_onFocus = TRUE;
  6. bool g_started = FALSE;

  7. LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  8. {
  9.     switch(uMsg)
  10.     {
  11.     case WM_ACTIVATEAPP:
  12.         g_onFocus = wParam;
  13.         return TRUE;
  14.     default:
  15.         return CallWindowProc((WNDPROC)g_pOldWndProc, hWnd, uMsg, wParam, lParam);
  16.     }
  17. }

  18. int Start()
  19. {
  20.     if(!g_started)
  21.     {
  22.         // Retrieve the current thread identifier.
  23.         DWORD threadID = GetCurrentThreadId();
  24.         // Retrieve the handle to the front-most window.
  25.         g_hWnd = GetWindow(GetForegroundWindow(), GW_HWNDFIRST);
  26.         // Enumerate all the windows.
  27.         while(g_hWnd)
  28.         {
  29.             // If the current thread identifier matches the one being enumerated, then
  30.             if(threadID == GetWindowThreadProcessId(g_hWnd, NULL))
  31.             {
  32.                 // Allocate a buffer of length 12.
  33.                 char className[12];
  34.                 // Get the class name of the window.
  35.                 GetClassName(g_hWnd, className, 12);
  36.                 // break the loop if the class name matches.
  37.                 if(strcmp(className, "RGSS Player") == 0)
  38.                     break;
  39.             }
  40.             // Retrieve the handle to the next window.
  41.             g_hWnd = GetWindow(g_hWnd, GW_HWNDNEXT);
  42.         }

  43.         // Failed when retrieving the handle to the window.
  44.         if(!g_hWnd)
  45.             return 1;

  46.         g_pOldWndProc = SetWindowLong(g_hWnd, GWL_WNDPROC, (LONG)WindowProc);
  47.         // Failed when replacing window proc.
  48.         if(!g_pOldWndProc)
  49.             return 2;

  50.         g_started = true;
  51.     }
  52.     return 0;
  53. }

  54. int Stop()
  55. {
  56.     if(g_started)
  57.     {
  58.         // Failed when retrieving the handle to the window.
  59.         if(!g_hWnd)
  60.             return 1;

  61.         // Failed when reverting the window proc.
  62.         if(!SetWindowLong(g_hWnd, GWL_WNDPROC, (LONG)g_pOldWndProc))
  63.             return 2;

  64.         g_started = false;
  65.     }
  66.     return 0;
  67. }

  68. int OnFocus()
  69. {
  70.     return g_onFocus;
  71. }
复制代码

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
12
 楼主| 发表于 2009-9-1 06:12:57 | 只看该作者
主楼更新,厚颜自顶 =w=

话说……那个键盘好像没重定义trigger……如果刚按下一个键的时候切到后台了
然后不更新,就一直trigger了
(好吧我是来挑刺的)
zh99998 发表于 2009-8-4 15:24

trigger? 不是只判断按下的瞬间么 o.o
……算了,加上判断好了~
这个强大的东西,7月份就发表了?...之前怎么没发现= =//
rm没办法直接用回调函数...
沉影不器 发表于 2009-8-7 22:35

确实,要用也只能把函数放在 DLL 里……
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv1.梦旅人 (禁止发言)

梦石
0
星屑
46
在线时间
10 小时
注册时间
2007-5-27
帖子
2558

第1届Title华丽大赛新人奖

11
发表于 2009-8-7 22:35:58 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复 支持 反对

使用道具 举报

Lv2.观梦者 (管理员)

八云紫的式神

梦石
0
星屑
609
在线时间
1243 小时
注册时间
2008-1-1
帖子
4282

烫烫烫

10
发表于 2009-8-4 15:24:41 | 只看该作者
话说……那个键盘好像没重定义trigger……如果刚按下一个键的时候切到后台了
然后不更新,就一直trigger了
(好吧我是来挑刺的)
rm for linux(wine)制作中,期待夏娜SAMA能实现到webrm上
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
55
在线时间
17 小时
注册时间
2008-9-18
帖子
14
9
发表于 2009-7-18 14:03:50 | 只看该作者
  1. 脚本 '真·后台运行' 的第 4 行发生了 RuntimeError .
复制代码
故障依然…………
马甲,马甲。
回复 支持 反对

使用道具 举报

Lv2.观梦者 (管理员)

八云紫的式神

梦石
0
星屑
609
在线时间
1243 小时
注册时间
2008-1-1
帖子
4282

烫烫烫

8
发表于 2009-7-14 20:17:38 | 只看该作者
外星星人
现在再下载一次试试呢
rm for linux(wine)制作中,期待夏娜SAMA能实现到webrm上
回复 支持 反对

使用道具 举报

Lv1.梦旅人

风雪夜不归人

梦石
0
星屑
50
在线时间
276 小时
注册时间
2006-3-7
帖子
6721

贵宾

7
发表于 2009-7-14 20:02:26 | 只看该作者
昨天看到问题,今天就看到脚本。LZ真有效率,支持一个。
有些人,到了七八月份就会诈尸。
宫斗,是女生永远的爱。
冷门,是本人不变的欲。
作弊,是玩家自由的痛。
练级,是橙光割舍的情。
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv1.梦旅人 (禁止发言)

梦石
0
星屑
50
在线时间
0 小时
注册时间
2009-7-11
帖子
33
6
发表于 2009-7-14 19:48:54 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
5
 楼主| 发表于 2009-7-14 17:56:34 | 只看该作者
1、2楼的问题已经修复,感谢提出 ^^
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
238 小时
注册时间
2006-10-2
帖子
417
4
发表于 2009-7-14 17:51:42 | 只看该作者
打开工程运行正常。
回复 支持 反对

使用道具 举报

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

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-27 01:31

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表