请教大家如何用C#实现T9输入法的功能

zjfgavin 2011-04-21 09:07:58
T9输入法应该不用多说,传统的手机都是这样,用过的应该知道

只要求设计数字输入模式和abc英文输入

举个例子,一般T9键盘的数字2键,按一下输入一个2,按两下输入两个2,以此类推

如果切换到abc英文输入模式,按一下屏幕显示a,如果连续按2下,屏幕先显示a,再变成b

如果不是连续按,而是按一下之后过一会儿再按一下,那第一个a保留,继续显示第二个a,并等待是否有连续按键,如果等待过程中按了其它键,那当前a保留,显示其它按键内容

我自己用Timer尝试了一下,但逻辑比较乱,理不过来

希望知道的大侠,不吝赐教
...全文
417 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
joyanhui 2013-05-17
  • 打赏
  • 举报
回复
关注! 正在搞输入法
zhaochanglong 2011-06-07
  • 打赏
  • 举报
回复
关注。。。。。
xiaoshu666 2011-06-07
  • 打赏
  • 举报
回复

/// <summary>
/// 输入数字处理函数
/// </summary>
/// <param name="e"></param>
private void InputNumb(KeyPressEventArgs e)
{
System.Windows.Forms.KeyPressEventArgs ex = null;
try
{
switch (e.KeyChar)
{
case '1':
case '@':
e.Handled = true;
SendText("1");
break;
case '2':
case 'A':
case 'B':
case 'C':
case 'a':
case 'b':
case 'c':
e.Handled = true;
SendText("2");
break;
case '3':
case 'D':
case 'E':
case 'F':
case 'd':
case 'e':
case 'f':
e.Handled = true;
SendText("3");
break;

case '4':
case 'G':
case 'H':
case 'I':
case 'g':
case 'h':
case 'i':
e.Handled = true;
SendText("4");
break;

case '5':
case 'J':
case 'K':
case 'L':
case 'j':
case 'k':
case 'l':
e.Handled = true;
SendText("5");
break;

case '6':
case 'M':
case 'N':
case 'O':
case 'm':
case 'n':
case 'o':
e.Handled = true;
SendText("6");
break;

case '7':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'p':
case 'q':
case 'r':
case 's':
e.Handled = true;
SendText("7");
break;

case '8':
case 'T':
case 'U':
case 'V':
case 't':
case 'u':
case 'v':
e.Handled = true;
SendText("8");
break;

case '9':
case 'W':
case 'X':
case 'Y':
case 'Z':
case 'w':
case 'x':
case 'y':
case 'z':
e.Handled = true;
SendText("9");
break;

case '0':
case '+':
e.Handled = true;
SendText("0");
break;

case '.':
case '*':
e.Handled = true;
SendText(".");
break;

}
base.OnKeyPress(e);
}
catch (Exception ee)
{

}
}

/// <summary>
/// 输入中文处理
/// </summary>
/// <param name="e"></param>
private void InPutUniCode()
{

if (currentInput == null)
{
currentInput = new InputPanel();
}

foreach (InputMethod im in currentInput.InputMethods)
{
if (im.Clsid == new Guid("4a5af224-05b8-41bc-8ed3-0df0432a326b"))
{
currentInput.CurrentInputMethod = im;
break;
}
// Clsid = {4a5af224-05b8-41bc-8ed3-0df0432a326b} // 手写输入
}

currentInput.Enabled = true;
}

#endregion

#region 获得输入内容
private void SendText(string s)
{
if (_inputType == MaskType.Number)
{
this.Text += s;
}
if (_inputType == MaskType.Char)
{
string val = this.Text;
if (string.IsNullOrEmpty(val))
{
this.Text = s;
}
else
{
if (seriesHit)
{
this.Text = val.Remove(val.Length - 1, 1) + s;
}
else
{
this.Text += s;
}
}
}

this.SelectionStart = this.Text.Length;
}

private void SendText(int n)
{

}

private void SendText(char c)
{

}
#endregion

}

/// <summary>
/// 键盘数字和字母对应关系标识
/// </summary>
public class KeyMap
{
private static Dictionary<int, char[]> keyMapDic = null;

public static Dictionary<int, char[]> KeyMapDic
{
get
{
if (keyMapDic == null)
{
keyMapDic = new Dictionary<int, char[]>();
InitDic();

}
return KeyMap.keyMapDic;
}
}

private static void InitDic()
{
keyMapDic.Add(0, new char[] { '+' });
keyMapDic.Add(1, new char[] { '@' });
keyMapDic.Add(2, new char[] { 'a', 'b', 'c' });
keyMapDic.Add(3, new char[] { 'd', 'e', 'f' });
keyMapDic.Add(4, new char[] { 'g', 'h', 'i' });
keyMapDic.Add(5, new char[] { 'j', 'k', 'l' });
keyMapDic.Add(6, new char[] { 'm', 'n', 'o' });
keyMapDic.Add(7, new char[] { 'p', 'q', 'r', 's' });
keyMapDic.Add(8, new char[] { 't', 'u', 'v' });
keyMapDic.Add(9, new char[] { 'w', 'x', 'y', 'z' });
}
}

/// <summary>
/// 输入类型
/// </summary>
public enum MaskType
{
/// <summary>
/// 字符型
/// </summary>
Char,
/// <summary>
/// 数字和字符
/// </summary>
CharAndNum,
/// <summary>
/// 数字型
/// </summary>
Number,
/// <summary>
/// 密码格式
/// </summary>
PassWordChar,
/// <summary>
/// 中文等
/// </summary>
Unicode
}
}

xiaoshu666 2011-06-07
  • 打赏
  • 举报
回复

#region 输入方式处理
/// <summary>
/// 输入字母处理函数
/// </summary>
/// <param name="e"></param>
private void InPutChar(System.Windows.Forms.KeyPressEventArgs e)
{
e.Handled = true;

try
{
switch (e.KeyChar)
{
case '0':
SendText("+");
break;
case '1':
case '@':
SendText("@");
break;

case '2':
if (!seriesHit) seriesCount = 0;
CharSelect(2);
break;
case 'a':
CharSelect(2);
break;
case 'b':
CharSelect(2);
break;
case 'c':
CharSelect(2);
break;

case '3':
if (!seriesHit) seriesCount = 0;
CharSelect(3);
break;
case 'd':
CharSelect(3);
break;
case 'e':
CharSelect(3);
break;
case 'f':
CharSelect(3);
break;

case '4':
if (!seriesHit) seriesCount = 0;
CharSelect(4);
break;
case 'g':
CharSelect(4);
break;
case 'h':
CharSelect(4);
break;
case 'i':
CharSelect(4);
break;

case '5':
if (!seriesHit) seriesCount = 0;
CharSelect(5);
break;
case 'j':
CharSelect(5);
break;
case 'k':
CharSelect(5);
break;
case 'l':
CharSelect(5);
break;


case '6':
if (!seriesHit) seriesCount = 0;
CharSelect(6);
break;
case 'm':
CharSelect(6);
break;
case 'n':
CharSelect(6);
break;
case 'o':
CharSelect(6);
break;


case '7':
if (!seriesHit) seriesCount = 0;
CharSelect(7);
break;
case 'p':
CharSelect(7);
break;
case 'q':
CharSelect(7);
break;
case 'r':
CharSelect(7);
break;
case 's':
CharSelect(7);
break;


case '8':
if (!seriesHit) seriesCount = 0;
CharSelect(8);
break;
case 't':
CharSelect(8);
break;
case 'u':
CharSelect(8);
break;
case 'v':
CharSelect(8);
break;

case '9':
if (!seriesHit) seriesCount = 0;
CharSelect(9);
break;
case 'w':
CharSelect(9);
break;
case 'x':
CharSelect(9);
break;
case 'y':
CharSelect(9);
break;
case 'z':
CharSelect(9);
break;
}
base.OnKeyPress(e);
}
catch (Exception ee)
{

}
}

/// <summary>
/// 输入字母选择
/// </summary>
/// <param name="n"></param>
private void CharSelect(int n)
{
int a = 0;

a = seriesCount % KeyMap.KeyMapDic[n].Length;
if (a == 0 && a / KeyMap.KeyMapDic[n].Length != 0)
a = KeyMap.KeyMapDic[n].Length - 1;
SendText(KeyMap.KeyMapDic[n][a].ToString());

seriesCount++;
}


xiaoshu666 2011-06-07
  • 打赏
  • 举报
回复

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using OpenNETCF.Windows.Forms;
using Microsoft.WindowsCE.Forms;
using System.ComponentModel;

namespace WinCETextBox
{
// [ToolboxItem(false)]
public class WinCETextBox : System.Windows.Forms.TextBox
{
// /// <summary>
// /// 文本框输入内容类型
// /// </summary>
// [Browsable(true)]
public MaskType InputType
{
get { return _inputType; }
set { _inputType = value; }
}

#region 私有变量
private MaskType _inputType = MaskType.CharAndNum;

/// <summary>
/// 检测按键间隔的钩子
/// </summary>
private static OpenNETCF.Windows.Forms.KeyboardHook _keyHook = null;

/// <summary>
/// 键盘按下的系统时间点
/// </summary>
private long keydowntick = 0;

/// <summary>
/// 连续按键最大间隔时间
/// </summary>
private long timediff = 500;

/// <summary>
/// 键盘连续点击时间间隔
/// </summary>
[DefaultValueAttribute(500)]
public long Timediff
{
get { return timediff; }
set { timediff = value; }
}

/// <summary>
/// 连续点击按键
/// </summary>
private bool seriesHit = false;

/// <summary>
/// 连续按键次数
/// </summary>
private int seriesCount = 0;

private InputPanel currentInput = null;

#endregion

#region 判断键盘是否连续按下

public WinCETextBox()
: base()
{
if (_keyHook == null)
{
_keyHook = new KeyboardHook();
}
_keyHook.KeyDetected += new KeyHookEventHandler(_keyHook_KeyDetected);
_keyHook.Enabled = true;

}

void _keyHook_KeyDetected(OpenNETCF.Win32.WM keyMessage, OpenNETCF.Windows.Forms.KeyData keyData)
{
if (keyMessage == OpenNETCF.Win32.WM.KEYDOWN)
{
if ((keyData.TimeStamp - this.keydowntick) < timediff)
{
seriesHit = true;
}
else
{
seriesHit = false;
}

this.keydowntick = keyData.TimeStamp;
}

//throw new NotImplementedException();
}
#endregion

#region 重写键盘 OnKeyPress 事件

protected override void OnGotFocus(EventArgs e)
{
if (_inputType == MaskType.Unicode)
{
if (currentInput != null)
currentInput.Enabled = true;
else
{
InPutUniCode();
}
}

base.OnGotFocus(e);
}

protected override void OnLostFocus(EventArgs e)
{
if (currentInput != null)
currentInput.Enabled = false;

base.OnLostFocus(e);
}

protected override void OnKeyPress(System.Windows.Forms.KeyPressEventArgs e)
{
switch (InputType)
{
case MaskType.Char:
InPutChar(e);
break;
case MaskType.Number:
InputNumb(e);
break;
case MaskType.CharAndNum:
break;
case MaskType.Unicode:
break;
}
}

#endregion

ycproc 2011-04-27
  • 打赏
  • 举报
回复
这不是timer能判读的

应当是有逻辑调用的

独立的方法
telancs 2011-04-27
  • 打赏
  • 举报
回复
朱建锋同学 我顶你一下 哈哈
wangyeee 2011-04-27
  • 打赏
  • 举报
回复
ASC码里面a加1就是b了,可以这样试试
zjfgavin 2011-04-27
  • 打赏
  • 举报
回复
老师 - -不能随便透露个人信息的
wang__hui1982 2011-04-27
  • 打赏
  • 举报
回复
朱建锋同学,我的人机交互实验作业是找不到答案的,要自己多动脑筋。记得你了,加油同学~回头发个邮件给我wanghui198218@yahoo.cn
Hamber_Bao 2011-04-21
  • 打赏
  • 举报
回复
利用timer控件不合适吧

这个东西理清思路,应该很容易的。

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧