=begin 脚本:【完美输入法修正】 功能:输入法。 说明: 直接用Type_Field创建输入域即可进行输入,在此可根据Type_Field域对象 的活动标记active来自定义刷新等,在Type_Field中需要自己处理特殊按键 的处理方法。具体不明白之处请参考范例工程。 作者:灼眼的夏娜 补充: 至于以前那个版本也许很多人都注意到那个烦人的问题了吧,按Enter和Tab那 些会出现不爽的声音,这个版本解决了那个问题,并简化添加了Type_Field类 来方便创建输入域。 =end #============================================================================== # ■ RInput #------------------------------------------------------------------------------ # 全键盘处理的模块。 #============================================================================== module RInput #-------------------------------------------------------------------------- # ● 常量定义 #-------------------------------------------------------------------------- ENTER = 0x0D SPACE = 0x20 UP = 0x26 DOWN = 0x28 LEFT = 0x25 RIGHT = 0x27 LCTRL = 0xA2 LALT = 0xA4 #-------------------------------------------------------------------------- # ● 临时Hash #-------------------------------------------------------------------------- @R_Key_Hash = {} @R_Key_Repeat = {} #-------------------------------------------------------------------------- # ● 唯一API #-------------------------------------------------------------------------- GetKeyState = Win32API.new("user32","GetAsyncKeyState",['I'],'I') #-------------------------------------------------------------------------- # ● 单键处理 #-------------------------------------------------------------------------- def self.trigger?(rkey) result = GetKeyState.call(rkey) if @R_Key_Hash[rkey] == 1 and result != 0 return false end if result != 0 @R_Key_Hash[rkey] = 1 return true else @R_Key_Hash[rkey] = 0 return false end end end #============================================================================== # ■ EasyConv #------------------------------------------------------------------------------ # 转码模块。 #============================================================================== module EasyConv #-------------------------------------------------------------------------- # ● 常量定义 #-------------------------------------------------------------------------- CP_ACP = 0 CP_UTF8 = 65001 #-------------------------------------------------------------------------- # ● 模块函数 #-------------------------------------------------------------------------- module_function #-------------------------------------------------------------------------- # ● 转码 #-------------------------------------------------------------------------- def s2u(text) m2w = Win32API.new('kernel32', 'MultiByteToWideChar', 'ilpipi', 'i') w2m = Win32API.new('kernel32', 'WideCharToMultiByte', 'ilpipipp', 'i') len = m2w.call(CP_ACP, 0, text, -1, nil, 0) buf = "\0" * (len*2) m2w.call(CP_ACP, 0, text, -1, buf, buf.size/2) len = w2m.call(CP_UTF8, 0, buf, -1, nil, 0, nil, nil) ret = "\0" * len w2m.call(CP_UTF8, 0, buf, -1, ret, ret.size, nil, nil) ret[-1] = "" return ret end #-------------------------------------------------------------------------- # ● 转码 #-------------------------------------------------------------------------- def u2s(text) m2w = Win32API.new('kernel32', 'MultiByteToWideChar', 'ilpipi', 'i') w2m = Win32API.new('kernel32', 'WideCharToMultiByte', 'ilpipipp', 'i') len = m2w.call(CP_UTF8, 0, text, -1, nil, 0) buf = "\0" * (len*2) m2w.call(CP_UTF8, 0, text, -1, buf, buf.size/2) len = w2m.call(CP_ACP, 0, buf, -1, nil, 0, nil, nil) ret = "\0" * len w2m.call(CP_ACP, 0, buf, -1, ret, ret.size, nil, nil) return ret end end #============================================================================== # ■ TypeAPI #------------------------------------------------------------------------------ # 输入法相关API模块。 #============================================================================== module TypeAPI #-------------------------------------------------------------------------- # ● API定义 #-------------------------------------------------------------------------- GPPS = Win32API.new("kernel32","GetPrivateProfileString",'pppplp','l') FindWindow = Win32API.new("user32", "FindWindow", 'pp', 'i') CreateWindow = Win32API.new("NetGame","CreatWnd",'l','l') SetHK = Win32API.new("NetGame","SetHK",'v','v') GetText = Win32API.new("NetGame","GetWndText",'l','p') SetFocus = Win32API.new("user32","SetFocus",'l','l') IfBack = Win32API.new("NetGame","If_Back",'v','i') StartType = Win32API.new("NetGame","StartType",'v','v') EndType = Win32API.new("NetGame","EndType",'v','v') GetKeyInfos = Win32API.new("NetGame","GetKeyInfo",'v','i') #-------------------------------------------------------------------------- # ● 模块函数 #-------------------------------------------------------------------------- module_function #-------------------------------------------------------------------------- # ● 获取参数 #-------------------------------------------------------------------------- def getParam val = "\0" * 256 GPPS.call("Game","Title","",val,256,"./Game.ini") val.delete!("\0") return val end #-------------------------------------------------------------------------- # ● 获取窗口 #-------------------------------------------------------------------------- def findWindow return FindWindow.call("RGSS Player",self.getParam) end #-------------------------------------------------------------------------- # ● 创建窗口 #-------------------------------------------------------------------------- def createWindow(hwnd) return CreateWindow.call(hwnd) end #-------------------------------------------------------------------------- # ● 设置HK #-------------------------------------------------------------------------- def setHK SetHK.call end #-------------------------------------------------------------------------- # ● 获取文字 #-------------------------------------------------------------------------- def getText return EasyConv.s2u(GetText.call(@subhwnd)) end #-------------------------------------------------------------------------- # ● 设置焦点 #-------------------------------------------------------------------------- def setFocus SetFocus.call(@subhwnd) end #-------------------------------------------------------------------------- # ● 转换焦点 #-------------------------------------------------------------------------- def lostFocus SetFocus.call(@hwnd) end #-------------------------------------------------------------------------- # ● 退格判定 #-------------------------------------------------------------------------- def ifBack return IfBack.call end #-------------------------------------------------------------------------- # ● 开始输入 #-------------------------------------------------------------------------- def startType StartType.call end #-------------------------------------------------------------------------- # ● 结束输入 #-------------------------------------------------------------------------- def endType EndType.call end #-------------------------------------------------------------------------- # ● 输入中特殊按键处理 #-------------------------------------------------------------------------- def getKeyInfos return GetKeyInfos.call end #-------------------------------------------------------------------------- # ● 获取句柄 #-------------------------------------------------------------------------- @hwnd = self.findWindow @subhwnd = self.createWindow(@hwnd) #-------------------------------------------------------------------------- # ● 设置HK应用 #-------------------------------------------------------------------------- self.setHK end #============================================================================== # ■ Type_Field #------------------------------------------------------------------------------ # 处理输入域的类。 #============================================================================== class Type_Field #-------------------------------------------------------------------------- # ● 定义实例变量 #-------------------------------------------------------------------------- attr(:active) #-------------------------------------------------------------------------- # ● 初始化 #-------------------------------------------------------------------------- def initialize(v,default_text = "",default_careth = nil,default_fonts = 16,\ default_fontc = Color.new(0,0,0)) # active @active = true # 视口 rect = v.rect @v = Viewport.new(rect.x,rect.y,rect.width,rect.height) @w = rect.width @h = rect.height # 属性 @caret_h = default_careth.nil? ? @h : [@h,default_careth].min @caret_y = rect.y + (@h - @caret_h) / 2 @font_size = [default_fonts,@h].min # 描绘contents @cts = Sprite.new(@v) @cts.bitmap = Bitmap.new(@w - 3,@h) @cts.bitmap.font.size = @font_size @cts.bitmap.font.color = default_fontc # 辅助属性 @bk_count = 0 @text = default_text.scan(/./) @max_width = @w - 3 @caret_pos = @text.size @save_pos = @caret_pos # 光标Caret @v1 = Viewport.new(rect.x,@caret_y,@w + 3,@caret_h) @caret_sp = Sprite.new(@v1) @caret_bitmap = Bitmap.new(3,@caret_h) @caret_bitmap.fill_rect(0,0,1,@caret_h,Color.new(0,0,0,180)) @caret_bitmap.fill_rect(1,0,1,@caret_h,Color.new(0,0,0)) @caret_bitmap.fill_rect(2,0,1,@caret_h,Color.new(120,120,120)) @caret_sp.bitmap = @caret_bitmap @caret_sp.x = self.get_width(@text[0,@caret_pos].to_s) @caret_sp.y = 0 @caret_sp.visible = false @caret_flash_count = 0 # 刷新 refresh # 设置焦点 TypeAPI.setFocus # 开始输入 TypeAPI.startType end #-------------------------------------------------------------------------- # ● 设置活动标记 #-------------------------------------------------------------------------- def active=(value) if value != true and value != false return end @active = value @caret_sp.visible = @active end #-------------------------------------------------------------------------- # ● 释放 #-------------------------------------------------------------------------- def dispose @caret_bitmap.dispose @caret_sp.bitmap.dispose @caret_sp.dispose @cts.bitmap.dispose @cts.dispose @v.dispose @v1.dispose end #-------------------------------------------------------------------------- # ● 刷新 #-------------------------------------------------------------------------- def refresh @cts.bitmap.clear @cts.bitmap.draw_text(0,0,@w,@h,@text.to_s) end #-------------------------------------------------------------------------- # ● 获取文字 #-------------------------------------------------------------------------- def get_text return @text.to_s end #-------------------------------------------------------------------------- # ● 取得字符宽度 #-------------------------------------------------------------------------- def get_width(str) return @cts.bitmap.text_size(str).width end #-------------------------------------------------------------------------- # ● 更新 #-------------------------------------------------------------------------- def update # 非激活状态则返回 unless @active return end # 获取按键信息 key_info = TypeAPI.getKeyInfos case key_info when 0x09 # Tab # 按下 Tab 键的情况自己定义怎么处理 return when 0x0d # Enter # 按下 Enter 键的情况自己定义怎么处理 return when 0x1B # Esc # 按下 Esc 键的情况自己定义怎么处理 return end self.update_text self.update_lrb self.update_back self.update_caret end #-------------------------------------------------------------------------- # ● 更新文字 #-------------------------------------------------------------------------- def update_text # 文字刷新 TypeAPI.setFocus text = TypeAPI.getText if text != "" for char in text.scan(/./) if self.get_width(@text.to_s + char) <= @max_width @text[@caret_pos,0] = char @caret_pos += 1 else break end end refresh end end #-------------------------------------------------------------------------- # ● 更新左右按键 #-------------------------------------------------------------------------- def update_lrb if RInput.trigger?(RInput::LEFT) and @caret_pos > 0 @caret_pos -= 1 return end if RInput.trigger?(RInput::RIGHT) and @caret_pos < @text.size @caret_pos += 1 return end end #-------------------------------------------------------------------------- # ● 更新退格 #-------------------------------------------------------------------------- def update_back # 前退格处理 @bk_count += TypeAPI.ifBack if @bk_count > 0 @bk_count -= 1 if @caret_pos > 0 @text.delete_at(@caret_pos - 1);@caret_pos -= 1;refresh end end end #-------------------------------------------------------------------------- # ● 更新光标闪烁 #-------------------------------------------------------------------------- def update_caret # 闪烁计时 @caret_flash_count += 1 if @caret_flash_count == 20 @caret_sp.visible = !@caret_sp.visible @caret_flash_count = 0 end # Caret位置刷新 if @save_pos != @caret_pos @save_pos = @caret_pos @caret_sp.x = self.get_width(@text[0,@save_pos].to_s) end end end |