Project1
标题: 任意字符输入的实现 [打印本页]
作者: 各种压力的猫君 时间: 2012-2-7 18:00
标题: 任意字符输入的实现1.API
require 'Win32API'
# require 'dl/win32'
class Win32API
# type flag
MB_OK = 0
MB_OKCANCEL = 1
MB_ABORTRETRYIGNORE = 2
MB_YESNOCANCEL = 3
MB_YESNO = 4
MB_RETRYCANCEL = 5
# return values
IDOK = 1
IDCANCEL = 2
IDABORT = 3
IDRETRY = 4
IDIGNORE = 5
IDYES = 6
IDNO = 7
def Win32API.MessageBox ( wnd, text, caption, type = MB_OK)
messagebox = Win32API.new ( 'user32' , 'MessageBox' , %w( p p p i) , 'i' )
messagebox.call ( wnd, text, caption, type)
end
def Win32API.MessageBoxEx ( wnd, text, caption, type = MB_OK, languageid = 0 )
messagebox = Win32API.new ( 'user32' , 'MessageBoxEx' , %w( p p p i i) , 'i' )
messagebox.call ( wnd, text, caption, type, languageid)
end
end
p Win32API.MessageBox ( 0 , "test message" , "test caption" )
p Win32API.MessageBoxEx ( 0 , "test message" , "test caption" )
p Win32API.MessageBox ( 0 , "てすと" , "テスト" )
p Win32API.MessageBoxEx ( 0 , "てすと" , "テスト" )
require 'Win32API'
# require 'dl/win32'
class Win32API
# type flag
MB_OK = 0
MB_OKCANCEL = 1
MB_ABORTRETRYIGNORE = 2
MB_YESNOCANCEL = 3
MB_YESNO = 4
MB_RETRYCANCEL = 5
# return values
IDOK = 1
IDCANCEL = 2
IDABORT = 3
IDRETRY = 4
IDIGNORE = 5
IDYES = 6
IDNO = 7
def Win32API.MessageBox ( wnd, text, caption, type = MB_OK)
messagebox = Win32API.new ( 'user32' , 'MessageBox' , %w( p p p i) , 'i' )
messagebox.call ( wnd, text, caption, type)
end
def Win32API.MessageBoxEx ( wnd, text, caption, type = MB_OK, languageid = 0 )
messagebox = Win32API.new ( 'user32' , 'MessageBoxEx' , %w( p p p i i) , 'i' )
messagebox.call ( wnd, text, caption, type, languageid)
end
end
p Win32API.MessageBox ( 0 , "test message" , "test caption" )
p Win32API.MessageBoxEx ( 0 , "test message" , "test caption" )
p Win32API.MessageBox ( 0 , "てすと" , "テスト" )
p Win32API.MessageBoxEx ( 0 , "てすと" , "テスト" )
(在RM里用的话需要注释掉第一行)
因为MessageBox可以很容易实现,我想能不能同样轻松地调用InputBox。
于是折腾半天一直都反复报错:Script '' line 42: RuntimeError occurred.
GetProcAddress: InputBox or InputBoxA 复制代码 inputbox = Win32API.new ( 'user32' , 'InputBox' , %w( p p i i p) , 'p' )
inputbox = Win32API.new ( 'user32' , 'InputBox' , %w( p p i i p) , 'p' )
倒地不起……谁帮我解决下 233
2.控制台
因为Ace新加入了一个控制台(类似Windows系统的cmd么……)
通过 gets 可以获取控制台输入,而控制台可以支持输入法……所以不失为一种解决方法。
但是怎样在需要的时候打开/关闭控制台,设置控制台窗口的大小、位置又成了难点 = = b
3.自己写个程序读取并写入某个文本文档,然后再在RM中读取
流程如下:
① RM调用脚本,将一些参数写入文本 =>
② 由RM启动自写程序挂起游戏并等待自写程序结束后继续执行 =>
③ 自写程序读取文本文档中的内容,根据文本文档中的内容设置窗口标题、提示文本、文本框默认文本、
窗口大小、位置、按钮文本、是否回显为"*"号(密码输入用)等一系列参数,并生成输入窗口等待玩家输入 =>
④ 玩家输入完成后通过确定按钮或会车键结束,自写程序将输入内容写入到文本文档并关闭自身 =>
⑤ RM检测到自写程序已结束,从文本文档相应行数读取输入文本
(好麻烦 = = b 能不能写个DLL把中间的文本操作换成内存操作……咱是做不到了 OTL)
目前自己只想到这三种方法……请各位补充。
作者: 凌依约 时间: 2012-2-7 18:52
先Mark:
然后下面是个人拙见.....
1.API的思路
亲,InputBox是VB中的函数,不是API的哟,并且W32API中也貌似没有类似功能的API(貌似貌似)
不过可以预先用其它的语言(C啦D啦还有易什么的)写一个包含输入框的DLL,然后用API调用,不过在全屏的时候真的大丈夫?
2.控制台的思路
打开控制台的话看看这段:比如ifconfig.exe这个控制台的程序(windows下的一个显示ip的控制台程序)
使用IO管道
创建ipconfig.exe进程,同时与之建立管道连接
ipcon=IO.popen("ipconfig.exe","r")
res=ipcon.read
ipcon.close
res里面存的就是ipconfig.exe控制台输出的结果了。
用ipcon.write也可以向该控制台程序发送指令,这就形成了交互(当然此时popen参数里的"r"改成"r+"。 复制代码 这个原理可以用到Game.exe程序里,不过现在在外面,手头上没有ACE,就没法试
然后之前看了下那个光的圆周率大大的控制台脚本,发现他在打开控制台的情况下,通过调用API函数来进行打开和隐藏,不知道可不可以在游戏开始时就打开控制台并隐藏
需要的时候才调出来.
ACE的控制台貌似就是基于Windows的控制台显示的,修改大小的话可能可以用API修改,然后再把边框去掉,不过这样做好像很不稳定,稍一不慎就Down掉了...
3.自己做程序来传输
这个思路MS可行,不过看起来就和1.API的那个差不多,用文件传太不安全了,不如用API反调回游戏还比较好
个人觉得的话用封装了输入对话框的DLL + API通过指针传给游戏比较可行...
作者: IamI 时间: 2012-2-7 19:01
常规方法是用 API 造一个窗口,里面放个 Textbox 的真货,伪造成就是这个窗体的。这样常常伴有焦点问题。
开创者:神思
夏娜写过一个DLL输入脚本,瑕疵有,总体问题不大。
最后请允许我吐个槽:挂起程序时间长了不被系统终止么?虽然这年头没有 10s 了……
作者: 各种压力的猫君 时间: 2012-2-7 20:13
本帖最后由 各种压力的猫君 于 2012-2-7 20:14 编辑
IamI 发表于 2012-2-7 19:01
常规方法是用 API 造一个窗口,里面放个 Textbox 的真货,伪造成就是这个窗体的。这样常常伴有焦点问题。
...
刚试了神思的,发现左右键移动光标/选中时光标不会移动(只是显示不动,实际上有移动没错)
用日文输入法会出现一个超难看的输入窗 = = b 是我输入法的问题么(度娘的日文输入……试了M$的也一样)
除了那个光标没发现什么BUG啊……有什么问题的话还望明示……
作者: yangff 时间: 2012-2-7 21:05
本帖最后由 yangff 于 2012-2-7 21:08 编辑
建议使用IMM API,这是最棒的,兼容全屏亲~
下面两个不支持全屏 = =
其次,CreateWindow+Clip消息
最后可以考虑http://rpg.blue/thread-121929-1-1.html ,这个脚本我也写过,连vbs都咔嚓掉了,手绘InputBox= =
作者: orzfly 时间: 2012-2-8 00:20
immapi需要回调函数的吧
作者: IamI 时间: 2012-2-8 17:56
XP里,只用一个,那啥问题都没,光标慢是因为缓冲字节少了一,补上即可。
如果你想在其他 Rb 环境里用来做奇怪的事情,麻烦就比较大……
作者: dant 时间: 2012-2-10 08:53
本帖最后由 dant 于 2012-2-10 08:54 编辑
控制台不要想了,这货不支持Unicode
虽然知道显示隐藏可以用AllocConsole /FreeConsole
调整大小可以用SetConsoleScreenBufferSize
[line]2[/line]
不用外部窗口的话,唯一的实现方法是处理WM_CHAR 和使用IMM API
作者: 杂兵天下 时间: 2012-2-10 14:53
本帖最后由 杂兵天下 于 2012-2-10 14:58 编辑
LZ明晃晃的版猪字样瞎了我的钛合金狗眼。。。。class Game_Interpreter
def command_303
return if $game_party .in_battle
$game_console .run ( "p \" 角色原名:\" +$game_actors[param[0]].name
p \" 请输入角色新名字\"
gnm=s2u(gets)
gnm=gnm[0..gnm.length-3]
$game_actors[param[0]].name=gnm
terminate" ,@params)
wait( 50 )
end
end
#==============================================================================
# ■ [RMVA]基于控制台的Debugger
#------------------------------------------------------------------------------
# 版本:1.00b
# 作者:光的圆周率
# 许可协议: FSL - NAM
#
# 已经被我改的面目全非了。
#------------------------------------------------------------------------------
# 脚本来自66RPG.com 转载请保留版权信息
#==============================================================================
class Game_Console
SetWindowText = Win32API.new ( "user32" , "SetWindowTextA" , "LP" , "L" )
SetFocus = Win32API.new ( "user32" , "SetForegroundWindow" , "L" , "L" )
GetWindowRect = Win32API.new ( "user32" , "ShowWindow" , "LL" , "L" )
def terminate#毁尸灭迹。一段toeval代码的最后必须加上terminate。
system ( "cls" )
GetWindowRect.call ( @Con_hWnd,0 )
SetFocus.call ( @Mai_hWnd)
end
def initialize
@Con_hWnd = get_ChWnd
@Mai_hWnd = get_hWnd
terminate
end
def run( toeval="" ,param=nil )
SetFocus.call ( @Con_hWnd)
SetWindowText.call ( @Con_hWnd,"Console" )
GetWindowRect.call ( @Con_hWnd,4 )
eval toeval
end
end
#==============================================================================
# ■ Kernel
#------------------------------------------------------------------------------
# 获取游戏窗口及控制台窗口的脚本
# 作者 : 紫苏
#------------------------------------------------------------------------------
# 脚本来自66RPG.com 转载请保留版权信息
#==============================================================================
module Kernel
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
threadID = GetCurrentThreadId.call
hWnd = GetWindow.call ( GetForegroundWindow.call , 0 )
while hWnd != 0
if threadID == GetWindowThreadProcessId.call ( hWnd, 0 )
className = " " * 11
GetClassName.call ( hWnd, className, 12 )
break if className == "RGSS Player"
end
hWnd = GetWindow.call ( hWnd, 2 )
end
return hWnd
end
def get_ChWnd
threadID = GetCurrentThreadId.call
hWnd = GetWindow.call ( GetForegroundWindow.call , 0 )
while hWnd != 0
if threadID == GetWindowThreadProcessId.call ( hWnd, 0 )
className = " " * 18
GetClassName.call ( hWnd, className, 19 )
break if className == "ConsoleWindowClass"
end
hWnd = GetWindow.call ( hWnd, 2 )
end
return hWnd
end
end
class Game_Interpreter
def command_303
return if $game_party .in_battle
$game_console .run ( "p \" 角色原名:\" +$game_actors[param[0]].name
p \" 请输入角色新名字\"
gnm=s2u(gets)
gnm=gnm[0..gnm.length-3]
$game_actors[param[0]].name=gnm
terminate" ,@params)
wait( 50 )
end
end
#==============================================================================
# ■ [RMVA]基于控制台的Debugger
#------------------------------------------------------------------------------
# 版本:1.00b
# 作者:光的圆周率
# 许可协议: FSL - NAM
#
# 已经被我改的面目全非了。
#------------------------------------------------------------------------------
# 脚本来自66RPG.com 转载请保留版权信息
#==============================================================================
class Game_Console
SetWindowText = Win32API.new ( "user32" , "SetWindowTextA" , "LP" , "L" )
SetFocus = Win32API.new ( "user32" , "SetForegroundWindow" , "L" , "L" )
GetWindowRect = Win32API.new ( "user32" , "ShowWindow" , "LL" , "L" )
def terminate#毁尸灭迹。一段toeval代码的最后必须加上terminate。
system ( "cls" )
GetWindowRect.call ( @Con_hWnd,0 )
SetFocus.call ( @Mai_hWnd)
end
def initialize
@Con_hWnd = get_ChWnd
@Mai_hWnd = get_hWnd
terminate
end
def run( toeval="" ,param=nil )
SetFocus.call ( @Con_hWnd)
SetWindowText.call ( @Con_hWnd,"Console" )
GetWindowRect.call ( @Con_hWnd,4 )
eval toeval
end
end
#==============================================================================
# ■ Kernel
#------------------------------------------------------------------------------
# 获取游戏窗口及控制台窗口的脚本
# 作者 : 紫苏
#------------------------------------------------------------------------------
# 脚本来自66RPG.com 转载请保留版权信息
#==============================================================================
module Kernel
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
threadID = GetCurrentThreadId.call
hWnd = GetWindow.call ( GetForegroundWindow.call , 0 )
while hWnd != 0
if threadID == GetWindowThreadProcessId.call ( hWnd, 0 )
className = " " * 11
GetClassName.call ( hWnd, className, 12 )
break if className == "RGSS Player"
end
hWnd = GetWindow.call ( hWnd, 2 )
end
return hWnd
end
def get_ChWnd
threadID = GetCurrentThreadId.call
hWnd = GetWindow.call ( GetForegroundWindow.call , 0 )
while hWnd != 0
if threadID == GetWindowThreadProcessId.call ( hWnd, 0 )
className = " " * 18
GetClassName.call ( hWnd, className, 19 )
break if className == "ConsoleWindowClass"
end
hWnd = GetWindow.call ( hWnd, 2 )
end
return hWnd
end
end
奥,我忘记了。
要真正用这个东西必须在Main上写$game_console =Game_Console.new
rgss_main { SceneManager.run }
$game_console =Game_Console.new
rgss_main { SceneManager.run }
然后必须用game console命令打开带命令提示符的RGSS Interpreter。
如此麻烦的东西。。。LZ还是不要研究了
作者: chd114 时间: 2012-5-28 13:37
RMXP的可以用?
欢迎光临 Project1 (https://rpg.blue/)
Powered by Discuz! X3.1