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

Project1

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

[已发主站] 【已通用】超级免DLL输入法

[复制链接]

Lv1.梦旅人

路人党员

梦石
0
星屑
52
在线时间
2276 小时
注册时间
2010-12-30
帖子
3225
跳转到指定楼层
1
发表于 2012-7-24 21:41:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

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

x
本帖最后由 英顺的马甲 于 2015-8-17 10:41 编辑

脚本已经加强,支持文本选择并且已经通用(其实本来就不难通用 =.=||)


最近研究API研究的起劲,对着MSDN几天后,
拟定了一个输入法的方案便开始写起脚本来了,
写着写着,突然!怎么感觉似曾相识?!
原来有人写过了~囧
http://rpg.blue/thread-93059-1-1.html
仔细看了一下,虽然脚本很相像,
但是总觉得我的方案好多了,
至少我的功能完整,至少~囧


经过一系列的研究,要不调用DLL把输入条直接镶在RGSS Player内至少凭我的程度是办不到的
(就算用dll我也办不到~囧),在我的方案内解决了一个上述地址中脚本的一个bug,
要获取输入中光标的位置和限制字数除了取SendMessage的返回值别无他法==

这个输入法用到了三个脚本

获取窗口句柄(已经有了可不必)
  1. #==============================================================================
  2. # ■ Kernel
  3. #------------------------------------------------------------------------------
  4. #  该模块中定义了可供所有类使用的方法。Object 类中包含了该模块。
  5. #==============================================================================
  6. module Kernel
  7.   #--------------------------------------------------------------------------
  8.   # ● 需要的 Windows API 函数
  9.   #--------------------------------------------------------------------------
  10.   GetWindowThreadProcessId = Win32API.new("user32", "GetWindowThreadProcessId", "LP", "L")
  11.   GetWindow = Win32API.new("user32", "GetWindow", "LL", "L")
  12.   GetClassName = Win32API.new("user32", "GetClassName", "LPL", "L")
  13.   GetCurrentThreadId = Win32API.new("kernel32", "GetCurrentThreadId", "V", "L")
  14.   GetForegroundWindow = Win32API.new("user32", "GetForegroundWindow", "V", "L")
  15.   #--------------------------------------------------------------------------
  16.   # ● 获取窗口句柄
  17.   #--------------------------------------------------------------------------
  18.   def get_hWnd
  19.     # 获取调用线程(RM 的主线程)的进程标识
  20.     threadID = GetCurrentThreadId.call
  21.     # 获取 Z 次序中最靠前的窗口
  22.     hWnd = GetWindow.call(GetForegroundWindow.call, 0)
  23.     # 枚举所有窗口
  24.     while hWnd != 0
  25.       # 如果创建该窗口的线程标识匹配本线程标识
  26.       if threadID == GetWindowThreadProcessId.call(hWnd, 0)
  27.         # 分配一个 11 个字节的缓冲区
  28.         className = " " * 11
  29.         # 获取该窗口的类名
  30.         GetClassName.call(hWnd, className, 12)
  31.         # 如果匹配 RGSS Player 则跳出循环
  32.         break if className == "RGSS Player"
  33.       end
  34.       # 获取下一个窗口
  35.       hWnd = GetWindow.call(hWnd, 2)
  36.     end
  37.     return hWnd
  38.   end
  39. end
复制代码
输入框核心脚本:
RUBY 代码复制
  1. #==============================================================================
  2. # ■ TextBox  by EngShun
  3. #------------------------------------------------------------------------------
  4. #  输入框的类。
  5. #==============================================================================
  6. class TextBox
  7.   #--------------------------------------------------------------------------
  8.   # ● 设置API
  9.   #--------------------------------------------------------------------------
  10.   CreateWindow = Win32API.new('user32','CreateWindowExW','lpplllllllll','l')
  11.   ShowWindow = Win32API.new('user32','ShowWindow','ll','l')
  12.   DestroyWindow = Win32API.new('user32','DestroyWindow','l','l')
  13.   GetWindowText = Win32API.new('user32','GetWindowTextW','lpl','l')
  14.   SetWindowText = Win32API.new("user32", "SetWindowTextW", "lp", "l")
  15.   SetWindowPos = Win32API.new("user32", "SetWindowPos", "lliiiii", "i")
  16.   GetWindowTextLength = Win32API.new('user32','GetWindowTextLengthW','l','l')
  17.   UpdateWindow = Win32API.new('user32','UpdateWindow','l','i')
  18.   SetFocus = Win32API.new('user32','SetFocus','l','l')
  19.   SendMessage = Win32API.new('user32','SendMessageW','llll','l')
  20.   GetKeyState = Win32API.new("user32","GetAsyncKeyState",'I','I')
  21.   #--------------------------------------------------------------------------
  22.   # ● 定义实例变量
  23.   #--------------------------------------------------------------------------
  24.   attr_accessor :focus
  25.   #--------------------------------------------------------------------------
  26.   # ● 初始化
  27.   #--------------------------------------------------------------------------
  28.   def initialize(text = "",limit = 8,number=false, x = 0, y = 458)
  29.     c = 0x40011000
  30.     c = (c|0x00001000) if number
  31.     @window = CreateWindow.call(0, mb2wc('EDIT'), mb2wc(text), c, x, y, 240, 22, get_hWnd, 0, 0, 0)
  32.     SendMessage.call(@window,0xC5,limit,0)
  33.     @focus = true
  34.     @disposed = false
  35.   end
  36.   #--------------------------------------------------------------------------
  37.   # ● 释放
  38.   #--------------------------------------------------------------------------
  39.   def dispose
  40.     @disposed = true
  41.     DestroyWindow.call(@window)
  42.   end
  43.   #--------------------------------------------------------------------------
  44.   # ● 刷新
  45.   #--------------------------------------------------------------------------
  46.   def update
  47.     return if !@focus or @disposed
  48.     UpdateWindow.call(@window)
  49.     SetFocus.call(@window)
  50.   end
  51.   #--------------------------------------------------------------------------
  52.   # ● 获取内容
  53.   #--------------------------------------------------------------------------
  54.   def text
  55.     return if @disposed
  56.     l = GetWindowTextLength.call(@window)
  57.     str = [0].pack('S') * (l + 1)
  58.     GetWindowText.call(@window, str, l+1)
  59.     return wc2mb(str)
  60.   end
  61.   #--------------------------------------------------------------------------
  62.   # ● 更改内容
  63.   #--------------------------------------------------------------------------
  64.   def text=(str)
  65.     SetWindowText.call(@window, mb2wc(str))
  66.     return if @disposed
  67.   end
  68.   #--------------------------------------------------------------------------
  69.   # ● 设定位置
  70.   #--------------------------------------------------------------------------
  71.   def set_pos(x, y)
  72.     SetWindowPos.call(@window, 0, x, y, 240, 22, 0x80)
  73.   end
  74.   #--------------------------------------------------------------------------
  75.   # ● 获取光标位置
  76.   #--------------------------------------------------------------------------
  77.   def selection
  78.     return if @disposed
  79.     pos = SendMessage.call(@window,0xB0,0,0)
  80.     return loword(pos),hiword(pos)
  81.   end
  82.   #--------------------------------------------------------------------------
  83.   # ● 设置光标位置
  84.   #--------------------------------------------------------------------------
  85.   def select(*i)
  86.     return if @disposed
  87.     i[1] = i[0] if i.size == 1
  88.     SendMessage.call(@window,0xB1,i[0],i[1])
  89.   end
  90.   #--------------------------------------------------------------------------
  91.   # ● 获取限制
  92.   #--------------------------------------------------------------------------
  93.   def limit
  94.     return if @disposed
  95.     return SendMessage.call(@window,0xD5,0,0)
  96.   end
  97.   #--------------------------------------------------------------------------
  98.   # ● 设置限制
  99.   #--------------------------------------------------------------------------
  100.   def limit=(i)
  101.     return if @disposed
  102.     SendMessage.call(@window,0xC5,i,0)
  103.   end
  104.   #--------------------------------------------------------------------------
  105.   # ● 是否按下回车键
  106.   #--------------------------------------------------------------------------
  107.   def press_enter?
  108.     return if @disposed
  109.     return (@focus and Input.trigger?(Input::C) and (GetKeyState.call(13) != 0))
  110.   end
  111.   #--------------------------------------------------------------------------
  112.   # ● 处理消息用
  113.   #--------------------------------------------------------------------------
  114.   def hiword(dword)
  115.     return [dword].pack('L').unpack('SS')[1]
  116.   end
  117.   #--------------------------------------------------------------------------
  118.   # ● 处理消息用
  119.   #--------------------------------------------------------------------------
  120.   def loword(dword)
  121.     return [dword].pack('L').unpack('SS')[0]
  122.   end
  123.   #--------------------------------------------------------------------------
  124.   # ● wchar -> char
  125.   #--------------------------------------------------------------------------
  126.   def wc2mb(text)
  127.     ary = text.unpack('S*')
  128.     ary.delete_at(-1)
  129.     return ary.pack('U*')
  130.   end
  131.   #--------------------------------------------------------------------------
  132.   # ● char -> wchar
  133.   #--------------------------------------------------------------------------
  134.   def mb2wc(text)
  135.     return (text.unpack('U*') + [0]).pack('S*')
  136.   end
  137.   private :mb2wc ,:wc2mb ,:hiword ,:loword # 定义私有功能
  138. end
输入框精灵类
RUBY 代码复制
  1. #==============================================================================
  2. # ■ Sprite_TextBox  by EngShun
  3. #------------------------------------------------------------------------------
  4. #  显示输入框用的活动块。
  5. #==============================================================================
  6. class Sprite_TextBox < Sprite
  7.   #--------------------------------------------------------------------------
  8.   # ● 设置缓存的类
  9.   #--------------------------------------------------------------------------
  10.   Cache = Struct.new(:bc ,:fc ,:sbc ,:sfc ,:fs ,:text ,:selection )
  11.   #--------------------------------------------------------------------------
  12.   # ● 定义实例变量
  13.   #--------------------------------------------------------------------------
  14.   attr_accessor :textbox
  15.   attr_accessor :back_color
  16.   attr_accessor :sel_back_color
  17.   attr_accessor :sel_font_color
  18.   attr_reader   :width
  19.   attr_reader   :height
  20.   #--------------------------------------------------------------------------
  21.   # ● 初始化
  22.   #--------------------------------------------------------------------------
  23.   def initialize(x = 0,y = 0,w = 128,h = 32,bc = Color.new(255,255,255),fc = Color.new(0,0,0),sbc=Color.new(0,0,255),sfc=Color.new(255,255,255),tb = TextBox.new)
  24.     super(nil)
  25.     self.x = x
  26.     self.y = y
  27.     self.bitmap = Bitmap.new(4096,512)
  28.     self.bitmap.font.color = fc
  29.     @width = w
  30.     @height = h
  31.     self.src_rect.width = w
  32.     self.src_rect.height = h
  33.     if self.bitmap.font.methods.include?(:shadow)
  34.       self.bitmap.font.shadow = false
  35.       if self.bitmap.font.methods.include?(:outline)
  36.         self.bitmap.font.outline = false
  37.       end
  38.     end
  39.     @sel_back_color = sbc
  40.     @sel_font_color = sfc
  41.     @back_color = bc
  42.     @textbox = tb
  43.     tb.set_pos(x, y)
  44.     @cache = Cache.new
  45.     self.src_rect.set(0,0,w,h)
  46.     refresh
  47.   end
  48.   #--------------------------------------------------------------------------
  49.   # ● 刷新
  50.   #--------------------------------------------------------------------------
  51.   def update
  52.     super
  53.     return unless @textbox.focus
  54.     @textbox.update
  55.     if (self.bitmap.font.color != @cache.fc) or
  56.        (self.bitmap.font.size != @cache.fs) or
  57.        (@textbox.selection != @cache.selection) or
  58.        (@sel_back_color != @cache.sbc) or
  59.        (@sel_font_color != @cache.sfc) or
  60.        (@textbox.text != @cache.text) or
  61.        (@back_color != @cache.bc)
  62.       refresh
  63.     end
  64.   end
  65.   #--------------------------------------------------------------------------
  66.   # ● 释放
  67.   #--------------------------------------------------------------------------
  68.   def dispose
  69.     self.bitmap.dispose
  70.     @textbox.dispose
  71.     super
  72.   end
  73.   def width=(v)
  74.     @width = v
  75.     self.src_rect.width = v
  76.     refresh
  77.   end
  78.   def height=(v)
  79.     @height = v
  80.     self.src_rect.height = v
  81.     refresh
  82.   end
  83.   #--------------------------------------------------------------------------
  84.   # ● 内容刷新
  85.   #--------------------------------------------------------------------------
  86.   def refresh
  87.     @cache.fc = self.bitmap.font.color
  88.     @cache.fs = self.bitmap.font.size
  89.     @cache.sbc = @sel_back_color
  90.     @cache.sfc = @sel_font_color
  91.     @cache.text = @textbox.text
  92.     @cache.bc = @back_color
  93.     w = 4096
  94.     h = @height
  95.     self.bitmap.fill_rect(0,0,w,h,@back_color)
  96.     self.bitmap.draw_text(4,0,w-4,h,@textbox.text)
  97.     start = @textbox.selection.min
  98.     _end = @textbox.selection.max
  99.     length = _end - start
  100.     t = @cache.text.scan(/./)[0,start].join("")
  101.     s = self.bitmap.text_size(t).width
  102.     if length == 0
  103.       self.bitmap.fill_rect(s + 4, 2, 1, h-4, self.bitmap.font.color)
  104.       if s > self.src_rect.x + @width
  105.         self.src_rect.x = s - @width + 8
  106.       elsif s < self.src_rect.x
  107.         self.src_rect.x = s
  108.       end
  109.     else
  110.       t2 = @cache.text.scan(/./)[start,length].join("")
  111.       s2 = self.bitmap.text_size(t2).width
  112.       @cache.fc = @cache.fc.clone
  113.       self.bitmap.fill_rect(4+s,2,s2,h-4,@sel_back_color)
  114.       self.bitmap.font.color = @sel_font_color.clone
  115.       self.bitmap.draw_text((4 + s),0,s2,h,t2)
  116.       self.bitmap.font.color = @cache.fc
  117.       if start < @cache.selection.min and s < self.src_rect.x
  118.         self.src_rect.x = s
  119.       elsif _end > @cache.selection.max and (s + s2) > self.src_rect.x + @width
  120.         self.src_rect.x = (s + s2) - @width + 8
  121.       end
  122.     end
  123.     @cache.selection = @textbox.selection
  124.   end
  125.   private :refresh # 设置私有功能
  126. end
具体就到这边了,请之前写过此类脚本的@神思来给个评语吧==
p/s:脚本整理得有些乱,请多多包涵<(_ _)>



以下提供了一个已经改好了的人物取名脚本(RMXP):
  1. #==============================================================================
  2. # ■ Scene_Name
  3. #------------------------------------------------------------------------------
  4. #  处理名称输入画面的类。
  5. #==============================================================================
  6. class Scene_Name
  7.   #--------------------------------------------------------------------------
  8.   # ● 主处理
  9.   #--------------------------------------------------------------------------
  10.   def main
  11.     @actor = $game_actors[$game_temp.name_actor_id]
  12.     @Window = Window_Base.new(0,176,640,128)
  13.     @window.contents = Bitmap.new(576,96)
  14.     @window.draw_actor_graphic(@actor, 64, 80)
  15.     @window.contents.draw_text(128,0,480,32,"请输入名称:")
  16.     @sprite_tb = Sprite_TextBox.new(144,240,464)
  17.     @sprite_tb.z = 500
  18.     @sprite_tb.textbox.limit = $game_temp.name_max_char
  19.     @sprite_tb.textbox.text = @actor.name
  20.     @sprite_tb.textbox.sel_pos = @actor.name.length
  21.     Graphics.transition
  22.     loop do
  23.       Graphics.update
  24.       Input.update
  25.       update
  26.       break if $scene != self
  27.     end
  28.     Graphics.freeze
  29.     @sprite_tb.dispose
  30.     @window.dispose
  31.   end
  32.   #--------------------------------------------------------------------------
  33.   # ● 刷新画面
  34.   #--------------------------------------------------------------------------
  35.   def update
  36.     @sprite_tb.update
  37.     if @sprite_tb.textbox.press_enter?
  38.       if @sprite_tb.textbox.text == ""
  39.         $game_system.se_play($data_system.buzzer_se)
  40.         return
  41.       end
  42.       @actor.name = @sprite_tb.textbox.text
  43.       $scene = Scene_Map.new
  44.     end
  45.   end
  46. end
复制代码
忘了最重要的==,无图无真相:

<=即使全屏输入法照样显示
   

超级免DLL输入法.zip

202.82 KB, 下载次数: 2472

评分

参与人数 4星屑 +615 +12 收起 理由
yang1zhi + 8 塞糖
欧买歌 + 7 塞糖
Shy07 + 12 主站收录
Kimu + 600 发布奖励

查看全部评分

本人擅长XP,如果有脚本或者Ruby方面的问题欢迎发电邮到[email protected]咨询,本人很少检查电邮所以不一定会及时回复,本人不会直接出手解决问题只会提供一个方向,所以谢绝伸手党

Lv1.梦旅人

梦石
0
星屑
60
在线时间
72 小时
注册时间
2012-1-15
帖子
189
2
发表于 2012-7-29 15:57:05 | 只看该作者
想问下LZ  这个脚本确定是VA的么? 还有我不愿意中枪
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (暗夜天使)

名侦探小柯

梦石
0
星屑
3299
在线时间
3619 小时
注册时间
2006-9-6
帖子
37400

开拓者贵宾第3届短篇游戏大赛主流游戏组亚军第5届短篇游戏比赛亚军

3
发表于 2012-7-29 16:42:45 | 只看该作者
效果很自然,就是实在想不出多少RM关于打字的需求……不包括网络聊天的话。
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
212 小时
注册时间
2012-3-5
帖子
228
4
发表于 2012-7-29 17:31:30 | 只看该作者
求VA版~~
回复 支持 反对

使用道具 举报

Lv1.梦旅人

水星地球侵略

梦石
0
星屑
53
在线时间
757 小时
注册时间
2011-8-23
帖子
5295
5
发表于 2012-7-29 17:42:16 | 只看该作者
然后在下一直没想明白RubyRGSS输入法和MSDN之间有何关联……难不成MSDN上还有关于Ruby的技术文章……
回复 支持 反对

使用道具 举报

Lv2.观梦者


  • 更新完成啦

梦石
0
星屑
799
在线时间
6267 小时
注册时间
2006-6-7
帖子
8462
6
发表于 2012-7-29 17:51:36 | 只看该作者
据说用dll都是偷懒的人@灼眼的夏娜
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
60
在线时间
565 小时
注册时间
2010-10-30
帖子
167
7
发表于 2012-7-29 18:13:51 | 只看该作者
看着还行吧,支持楼主下。
(ARPG)赵云突围: http://rpg.blue/thread-303844-1-1.html
(剧情向战斗)命运赌局: http://rpg.blue/thread-257144-1-1.html
(ARPG)三英战吕布: http://rpg.blue/thread-220451-1-1.html
(R剧)秋风五丈原: http://rpg.blue/thread-211306-1-1.html
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
60
在线时间
156 小时
注册时间
2011-12-13
帖子
133
8
发表于 2012-7-30 14:55:35 | 只看该作者
直接把Edit窗口显示出来不是更好?

评分

参与人数 1星屑 +120 收起 理由
英顺的马甲 + 120 非常感谢

查看全部评分

回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
188
在线时间
3 小时
注册时间
2012-8-17
帖子
2
9
发表于 2012-8-18 12:00:33 | 只看该作者
...............
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
120
在线时间
68 小时
注册时间
2007-12-16
帖子
75
10
发表于 2012-8-20 00:00:45 | 只看该作者
這腳本還是有些小瑕疵~~~
首先文字指標對多字元的反應不大正確(RUBY和WIN對雙字元判定的差異)...
除此之外如果輸入法用ENTER確認的話就...

第一個小問題咱解決了
第二個問題研究中~~~
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

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

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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