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

Project1

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

[已经解决] 完美输入法~最终修正版出错

[复制链接]

Lv1.梦旅人

梦石
0
星屑
50
在线时间
163 小时
注册时间
2012-1-15
帖子
67
跳转到指定楼层
1
发表于 2014-2-20 22:12:32 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

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

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

x
本帖最后由 q6625765 于 2014-2-25 22:12 编辑



=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(255,255,255))
    # active
    @active = true
    # 视口
    rect = v.rect
    @v = Viewport.new(rect.x,rect.y,rect.width,rect.height)
    @v.z = 9999999
    @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.name ="黑体","宋体"
    @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)
    @v1.z = 9999999
    @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(250,250,250))
    @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
    $shufa = @text.to_s
    $shufa_zu = @text
    @cts.bitmap.draw_text(0,0,@w,@h,@text.to_s)
  end
  def qingkong
      @cts.bitmap.clear
      @text = []
      @caret_pos = 0
      
      
  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 键的情况自己定义怎么处理
      #  case @active
       # when true
      #  @active = false
      #  when false
       # @active = true
      #  end
      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
   # ● 清空光标闪烁
  #--------------------------------------------------------------------------
  def qingkong_biao
      @caret_sp.visible = false
     
  end
  # ● 复位光标闪烁
  #--------------------------------------------------------------------------
  def fuwei_biao
   
      @caret_sp.x = self.get_width(@text[0,0].to_s)
      @caret_pos = 0
  end
end



视口rect = v.rect出错看一下是为什么呀
  
   

Lv1.梦旅人

匿·蹤

梦石
0
星屑
65
在线时间
99 小时
注册时间
2006-3-19
帖子
456
2
发表于 2014-2-21 10:28:51 | 只看该作者
Type_Field 在初始化的时候,貌似需要传入一个v参数,参数类型是Window……
猜测是这样子,很久没玩RMXP了,忘光了都……
还是神招夏娜大大吧
@灼眼的夏娜  
卐忍 → 解忍 → 元忍 → 隐忍 → 卍忍 → 匿踪(最终)
完全退步到了卐忍阶段
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (管理员)

老黄鸡

梦石
0
星屑
42453
在线时间
7605 小时
注册时间
2009-7-6
帖子
13506

开拓者贵宾

3
发表于 2014-2-21 17:23:53 | 只看该作者
个人感觉纯粹使用的话,这个输入法更完美。
http://rpg.blue/thread-243422-1-1.html
RGDirect - DirectX驱动的RGSS,点我了解.
RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
163 小时
注册时间
2012-1-15
帖子
67
4
 楼主| 发表于 2014-2-21 20:31:24 | 只看该作者
fux2 发表于 2014-2-21 17:23
个人感觉纯粹使用的话,这个输入法更完美。
http://rpg.blue/thread-243422-1-1.html ...

我用 完美输入法是因为有一个脚本里面有下面
  @v = Viewport.new(0,313,220,29)
    @v.color.set(0,0,0,0)
    $game_temp.name_max_char = 6
    @tf = Type_Field.new($game_temp.name_max_char*3-4)
但是用了完美输入法却出现视口rect = v.rect出错无语
回复 支持 反对

使用道具 举报

Lv1.梦旅人

匿·蹤

梦石
0
星屑
65
在线时间
99 小时
注册时间
2006-3-19
帖子
456
5
发表于 2014-2-23 10:08:18 | 只看该作者
q6625765 发表于 2014-2-21 20:31
我用 完美输入法是因为有一个脚本里面有下面
  @v = Viewport.new(0,313,220,29)
    @v.color.set(0,0,0 ...

果然是传入的参数有问题:
  1. Type_Field.new(@v,"",16)
复制代码
这是教程中的用法,@v的来源是:
  1. @v = Viewport.new(120,120,320,20)
复制代码
由此可知,@v是个窗口……
所以,你需要将代码改为:
  1. @tf = Type_Field.new(@v,"",$game_temp.name_max_char*3-4)
复制代码
卐忍 → 解忍 → 元忍 → 隐忍 → 卍忍 → 匿踪(最终)
完全退步到了卐忍阶段
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
163 小时
注册时间
2012-1-15
帖子
67
6
 楼主| 发表于 2014-2-23 14:19:55 | 只看该作者
OCTSJimmy 发表于 2014-2-23 10:08
果然是传入的参数有问题:这是教程中的用法,@v的来源是:由此可知,@v是个窗口……
所以,你需要将代码 ...

多谢大哥问题得到了解决{:2_275:}
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-11-29 06:16

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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