赞 | 2 |
VIP | 143 |
好人卡 | 1 |
积分 | 1 |
经验 | 216792 |
最后登录 | 2019-10-10 |
在线时间 | 24 小时 |
Lv1.梦旅人
- 梦石
- 0
- 星屑
- 61
- 在线时间
- 24 小时
- 注册时间
- 2008-8-5
- 帖子
- 1924
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
本帖最后由 紫苏 于 2009-11-25 11:30 编辑
RMVXBR.rar
(258.57 KB, 下载次数: 2818)
2009/07/14:
- 修正了 DLL 是调试编译,而非独立 DLL 的问题;
- 修正了窗口不在键盘焦点时按键按下仍然保持失去焦点前状态的问题(例:地图上按住 ←,切换到其它窗口,角色就会一直保持左移)
2009/09/01:
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
调用源代码:- unless $_Start
- $_Start = Win32API.new("Lib/BackgroundRunning","Start",'V','L')
- $_Stop = Win32API.new("Lib/BackgroundRunning","Stop",'V','L')
- $_OnFocus = Win32API.new("Lib/BackgroundRunning","OnFocus",'V','L')
- $_Start.call
- module Input
- InputUpdate = method :update
- InputTrigger = method :trigger?
- InputPress = method :press?
- InputRepeat = method :repeat?
- InputDir4 = method :dir4
- InputDir8 = method :dir8
- def self.update
- InputUpdate.call if $_OnFocus.call != 0
- end
- def self.trigger?(num)
- return $_OnFocus.call != 0 ? InputTrigger.call(num) : false
- end
- def self.press?(num)
- return $_OnFocus.call != 0 ? InputPress.call(num) : false
- end
- def self.repeat?(num)
- return $_OnFocus.call != 0 ? InputRepeat.call(num) : false
- end
- def self.dir4
- return $_OnFocus.call != 0 ? InputDir4.call : 0
- end
- def self.dir8
- return $_OnFocus.call != 0 ? InputDir8.call : 0
- end
- end
- end
复制代码 DLL 源代码:
- #include <windows.h>
- #include <stdio.h>
- HWND g_hWnd = NULL;
- LONG g_pOldWndProc = NULL;
- BOOL g_onFocus = TRUE;
- bool g_started = FALSE;
- LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch(uMsg)
- {
- case WM_ACTIVATEAPP:
- g_onFocus = wParam;
- return TRUE;
- default:
- return CallWindowProc((WNDPROC)g_pOldWndProc, hWnd, uMsg, wParam, lParam);
- }
- }
- int Start()
- {
- if(!g_started)
- {
- // Retrieve the current thread identifier.
- DWORD threadID = GetCurrentThreadId();
- // Retrieve the handle to the front-most window.
- g_hWnd = GetWindow(GetForegroundWindow(), GW_HWNDFIRST);
- // Enumerate all the windows.
- while(g_hWnd)
- {
- // If the current thread identifier matches the one being enumerated, then
- if(threadID == GetWindowThreadProcessId(g_hWnd, NULL))
- {
- // Allocate a buffer of length 12.
- char className[12];
- // Get the class name of the window.
- GetClassName(g_hWnd, className, 12);
- // break the loop if the class name matches.
- if(strcmp(className, "RGSS Player") == 0)
- break;
- }
- // Retrieve the handle to the next window.
- g_hWnd = GetWindow(g_hWnd, GW_HWNDNEXT);
- }
- // Failed when retrieving the handle to the window.
- if(!g_hWnd)
- return 1;
- g_pOldWndProc = SetWindowLong(g_hWnd, GWL_WNDPROC, (LONG)WindowProc);
- // Failed when replacing window proc.
- if(!g_pOldWndProc)
- return 2;
- g_started = true;
- }
- return 0;
- }
- int Stop()
- {
- if(g_started)
- {
- // Failed when retrieving the handle to the window.
- if(!g_hWnd)
- return 1;
- // Failed when reverting the window proc.
- if(!SetWindowLong(g_hWnd, GWL_WNDPROC, (LONG)g_pOldWndProc))
- return 2;
- g_started = false;
- }
- return 0;
- }
- int OnFocus()
- {
- return g_onFocus;
- }
复制代码 |
|