本文来告诉大家如何使用 WPF 来写一个输入法,使用的方式是钩子。
实际上本文是在使用一个好用的软件 希沃白板 的时候发现在里面很难输入拼音来做课堂活动。
因为现在没有找到一个软件可以用来输入拼音的,快速的输入。输入音调是比较难的,所以我就重新做了一个输入法。
在yswenli的帮助,使用了yswenli/Wenli.IEM 方法做了一个输入法。
键盘
如果要做一个输入法,可以使用很多方法,本文使用的是全局 hook 的方式,需要注意,这个方式很容易让 360 杀掉。
注册钩子的方法很简单,只需要一个函数
关于 HookProc 请看代码
所以简单的注册一个钩子只需要三行代码
那么拿到了 hook 可以如何使用,下面来告诉大家如何解析信息
解析键盘
解析的方式微软有说到,因为很简单,只需要定义一个结构,请看代码。定义的结构需要是这样的,不要去优化。
从参数就可以拿到,因为参数是指针,需要Marshal.PtrToStructure
来拿到
现在通过这个方法就可以拿到键盘的输入。
获得按键
虽然已经解析了,但是现在还是不知道用户按键是哪个。需要通过下面的方法转换,首先引用 WinForm ,因为定义在 WinForm 有,而且下面发送消息也是需要通过。
右击引用,点击程序集、框架,就可以看到 System.Windows.Forms ,请看图片
引用了之后就可以使用下面的方法拿到按键
尝试点一下,是不是就可以看到对应的值?
有了按键,那么下面如何写一个输入法就是需要使用了对应的算法了,如果想使用微软提供的算法,请看C# 输入法,我是需要用来输入拼音。所以下面来告诉大家如何从用户按键拿到用户想要的输入。
输入流向
虽然已经拿到了按键,但是拿到的按键还是需要转换字符串才可以处理
现在的 key 就是一个字符串,在输入拼音,用户想的是快速的输入,而不是不停复制粘贴,对于普通的字符输入是可以直接输入,但是对于āáǎ
的输入就无法直接输入的。
我看到一位老师是在记事本写了下面代码
需要哪个就去复制哪个,如写 yùn
就需要输入 y
然后复制一下ù
,然后写 n
,这样想输入连续的拼音是很慢的。
所以对于a,e,i,o,u,v
才需要输入法转换,对于其他的就直接输入就好了。
那么如何让用户的按键无法直接输入到对应的程序,就需要使用下面的函数
使用这个函数就可以通过信息钩子继续下一个钩子,在 private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
大家也看到有一个返回值,通过这个返回值可以告诉系统,是不是要把这个消息传给下一个程序。
如果返回的是 0 那么就是告诉系统,这个 hook 不处理,你需要把消息发给其他的程序。如果返回不是0 ,那么就是告诉系统,这个我处理了,其他的程序不能收到。
输入法判断用户输入的是 [a,z] [0,9] 告诉系统,不要发给其他的程序。
那么如果用户输入的不是 a,e,i,o,u,v
也就是可以直接给其他程序,这时怎么做?
实际上不管用户输入的是什么,只要发给其他程序都需要使用这个方法
通过这个方法就会把 str 发送给当前用户输入的程序。
算法
现在可以拿到了全部的输入,而且知道了如何把转换的值发送给用户,大概一个输入法就是需要这两个。
如果从用户的输入知道用户需要的什么就是算法,下面使用的方法很简单。
判断用户输入的是不是a,e,i,o,u,v
,发现不是就直接发送输入。如果是就不发送任何输入,让用户选需要的是哪个
这是我把它显示出来,代码还需要一个属性,表示当前是不是存在用户没有选的字符。如果存在,下一次输入的是[0,9]就是用户选的字符,因为只要5个可以选,对于大于5和0的就直接发送输入。当前对于现在很多输入法,都是按空格选第一个,这里也是需要判断用户输入的是不是空格。
在开发的时候发现还有很多的细节,不过这些我就不在这里告诉大家,我把代码放在下面,大家看一下。
我把程序放在论坛,可以点击 快速在课堂活动输入拼音 下载
源代码请看
参见:C# 输入法
原文链接: http://blog.lindexi.com/post/WPF-%E6%8B%BC%E9%9F%B3%E8%BE%93%E5%85%A5%E6%B3%95
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。
欢迎转载、使用、重新发布,但务必保留文章署名 林德熙 (包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我 联系。