原文:通通WPF随笔(4)——通通手写输入法(基于Tablet pc实现)


从我在博客园写第一篇博客到现在已经有1年半了,我的第一篇博客写的就是手写识别,当时,客户需求在应用中加入手写输入功能,由于第三方的手写输入法都无法定制界面,所以领导决定自主开发,所以我就很简单地基于Tablet pc写了一个WPF控件,由于几个瓶颈问题,导致这个输入功能只能在我们的UI框架里使用,而无法做到像输入法那样可以输入到任意窗口。

  时隔1年半,随着各种项目的磨练,知识的积累几个问题得以解决,于是就产生了这个手写输入法。

ICO:

UI:

  

符号识别:

  

识别率还是比较高的

  

界面风格是1年半前设计的,当时觉得《创世纪》的视觉效果挺牛X的。

因为是针对于触摸设备设计的,所以没有做退出按钮,由应用来控制关闭。PC上的话,在空白处左键可以拖动,点击右键关闭窗口。

一、瓶颈问题


  由于本人C#出身,实在不想去研究什么IME等等底层的输入法机制,所以就写个exe实现输入法的功能。就面临下面几个问题:

  1、如何向其他窗口发送输入消息呢?

  2、如何知道当前键盘焦点所在窗口呢?

  3、如何在操作输入法窗体的时候不让目标窗口丢失焦点呢?

  这几个问题读起来就比较纠结......有句话说得好啊,“当做一件事时越来越难,就说明方向错了”。所以就绕开这几个问题呗。

二、解决问题


  C#里有个模拟键盘按键的方法 

模拟按键: 

System.Windows.Forms.SendKeys.SendWait("{DEL}");

而且可以发送字符:

System.Windows.Forms.SendKeys.SendWait("你好,美女~!");

  通过这个方法就模拟了键盘上的del键和发送字符串输入消息,而这个方法并没有需要窗口句柄,所以我猜想应该是模拟了底层的按键消息等等,而消息的去向肯定就是键盘焦点所在的窗口咯,这样就绕开了1、2两个问题。关于SendWait()参数的详细说明可以参看:http://msdn.microsoft.com/zh-cn/library/system.windows.forms.sendkeys.aspx

  接下来就需要解决的就只有3号问题了。

  一开始我很单纯的以为只要把窗口里面的所有控件都设置为不能获取焦点就行了

.Focusable = false;

  但这只是第一步,当一个窗口被激活时所有焦点都会跑到新激活的窗体上,所以,还得寻找其他方法。无意中在逛codeproject的时候发现了一段代码:  

[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong); [DllImport("user32.dll", SetLastError = true)]
public static extern UInt32 GetWindowLong(IntPtr hWnd, int nIndex); // style of window?
int GWL_EXSTYLE = (-);
// get - retrieves information about a specified window
GetWindowLong(HWND, GWL_EXSTYLE);
// set - changes the attribute of a specified window - I think this stops it being focused on
SetWindowLong(HWND, GWL_EXSTYLE, (IntPtr)(0x8000000));

  Windows API的参数就是高端啊,完全看不懂是在干嘛,不过能达到目标就行。这样HWND窗口句柄对应的窗口就变得不会获取键盘焦点了。

  这样就解决了3个瓶颈问题。

三、手写识别


  已经实现了如何把字符串输出到其他窗口,剩下的就是识别手写墨迹了,核心在于InkAnalyzer这个类。通过WPF的InkCanvas控件来收集墨迹,然后通过theInkAnalyer.Analyze();方法就可以解析出来,十分方便。代码如下:(需要引用IACore.dll、IALoader.dll、IAWinFX.dll这3个动态库)

 InkAnalyzer theInkAnalyer;
AnalysisHintNode hint;
private void Grid_Loaded(object sender, RoutedEventArgs e)
{// style of window?
int GWL_EXSTYLE = (-);
// get - retrieves information about a specified window
GetWindowLong(HWND, GWL_EXSTYLE);
// set - changes the attribute of a specified window - I think this stops it being focused on
SetWindowLong(HWND, GWL_EXSTYLE, (IntPtr)(0x8000000)); theInkAnalyer = new InkAnalyzer();
hint = theInkAnalyer.CreateAnalysisHint();
hint.Guide.Columns = ;
hint.Guide.Rows = ;
hint.WordMode = true;
hint.TopInkBreaksOnly = true; } private void inkCanvs_MouseUp(object sender, MouseButtonEventArgs e)
{
hint.Location.MakeInfinite();
theInkAnalyer.RemoveStrokes(inkCanvs.Strokes);
theInkAnalyer.AddStrokes(inkCanvs.Strokes);
theInkAnalyer.SetStrokesLanguageId(inkCanvs.Strokes, 0x0804); theInkAnalyer.SetStrokesType(inkCanvs.Strokes, StrokeType.Writing);
AnalysisStatus status = theInkAnalyer.Analyze();
if (status.Successful)
{
for (int i = ; i < theInkAnalyer.GetAlternates().Count; i++)
{
Button thisButton = this.FindName("b" + i.ToString()) as Button;
string resultStr = theInkAnalyer.GetAlternates()[i].RecognizedString;
if (resultStr.Length==)
{
thisButton.Content = resultStr;
} } }
else
{
//MessageBox.Show("识别失败");
}
}

最终效果

  

  要在已安装了Tablet pc组件的Win7以上的系统才可以手写识别哦,win7完整版默认安装,但有的精简版把这个组件丢掉了,win8下完美运行。xp下的话得改一些系统文件,相关方法可以查看本人的第一篇博客 http://www.cnblogs.com/tong-tong/archive/2011/10/22/2220446.html

IACore等动态库下载:(包含XML注释文档)

http://files.cnblogs.com/tong-tong/IADLL.zip

demo下载:

http://files.cnblogs.com/tong-tong/TTHandwriting.zip

后记


  最近各种事情还要出钱啊、各种副省长还来参观啊、各种项目还没结束啊......

通通WPF随笔(4)——通通手写输入法(基于Tablet pc实现)的更多相关文章

  1. 通通WPF随笔(1)——基于lucene.NET让ComboBox拥有强大的下拉联想功能

    原文:通通WPF随笔(1)--基于lucene.NET让ComboBox拥有强大的下拉联想功能 我一直很疑惑百度.谷哥搜索框的下拉联想功能是怎么实现的?是不断地查询数据库吗?其实到现在我也不知道,他们 ...

  2. 通通WPF随笔(3)——艺术二维码素材生成器

    原文:通通WPF随笔(3)--艺术二维码素材生成器 最近公司让我开发一个条形码的生成控件,花了半天时间搞定觉得不过瘾,什么年代了该用二维码了吧.于是wiki了一下二维码的资料. 比较常见的就是QR码( ...

  3. 通通WPF随笔(2)——自己制作轻量级asp.net网站服务

    原文:通通WPF随笔(2)--自己制作轻量级asp.net网站服务 大学玩asp.net时就发现VS在Debug时会起一个web服务,这东西也太神奇了服务起得这么快,而相对于IIS又这么渺小. 前几个 ...

  4. c#基于Tablet pc实现的手写输入

    需要安装Tablet pc,win7的话 直接在控制面板>程序和应用>添加组建里面勾选上添加 然后就是下面的程序了,看代码 设计文件 namespace 手写识别 { partial cl ...

  5. WPF随笔(九)--使用路径动画模拟管道流体流向

    原文:WPF随笔(九)--使用路径动画模拟管道流体流向 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/lordwish/article/detail ...

  6. wpf随笔

    因项目需要查找wpf.DataGrid的Binding方法, 由于其属于Dev框架体系内,偏向于winform并无Binding 1.且线程外更改UI控件还需要委托或者action,而Wpf控件仅需要 ...

  7. 循环移位法和数据拼接法基于led

    功能描述 让led每隔0.5s从两边向中间闪烁,然后在从中间向两边闪烁,不断循环 项目实现 开发板 晶振为50M,那么达到0.5s时计数器count1需要达到24_999_999这么多次数 计数器代码 ...

  8. 商米D1S一体机设置搜狗手写输入法图解

    按照下图步骤,一步步设置即可,询问全新的时候需要点击允许. 商米应用市场搜索下载搜狗输入法,并安装 安装完成后,点击桌面搜狗输入法,选择启用搜狗输入法,如图 点击启用后,在虚拟键盘中选择搜狗输入法,并 ...

  9. iOS 手写输入法奔溃,替换隐藏键盘方法

    {   UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:se ...

随机推荐

  1. 【u110】灾后重建

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前, ...

  2. 【hdu 2594】Simpsons’ Hidden Talents

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...

  3. 【23.33%】【codeforces 664C】International Olympiad

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  4. No USB devices or running emulators detected”

    每次重装系统之后,安装andorid studio后,使用真机调试代码,就会出现"No USB devices or running emulators detected"的错误, ...

  5. Lettcode_104_Maximum Depth of Binary Tree

    本文研究的总结,欢迎转载,但请注明出处:http://blog.csdn.net/pistolove/article/details/41964475 Maximum Depth of Binary ...

  6. 浏览器加载js文件顺序

    在默认情况下,下载和执行js都会阻塞页面的渲染,当然现在浏览器支持并行下载,但仍然会阻塞图片等的下载和渲染,所以通常建议把js文件放body底.对于执行顺序,不管是外部js还是内部,只要 遇到< ...

  7. handsontable前端excel学习笔记

    暂时没有好的中文资料,大概找了三遍随便看看,之后重点研究其github 1.Handsontable 学习笔记-Methods 2. Handsontable通用方法 3.handsontable的核 ...

  8. java开发环境配置(windows下JDK7+tomcat7)

    參考原文:http://www.cnblogs.com/goto/archive/2012/11/16/2772683.html http://www.cnblogs.com/feilong35407 ...

  9. HDU 1143 Tri Tiling (递推)

    Tri Tiling Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  10. vue 使用jquery (全局)

    1 全局配置jquery , 个人习惯 , 离不开jquery了 然后重启项目 就 完事