C# Input method
Although input method is not a new thing, it is available in various languages, but it is not common in C# ;This will give people a misunderstanding: C# can't do it! In fact, whether C# can do it, the answer is yes - all three methods will work: IMM, TSF and plug-in. IMM is to adjust some of the underlying api of Windows, but it is basically no longer available in new versions of Windows, and it is an outdated operation method. TSF is a new method recommended by Microsoft, but there is too little information compared to C#; the main ones online are version information for C++, which can of course be used as a reference to implement the C# version. Here I mainly introduce a kind of plug-in (Oh my god, can C# write plug-ins?), which is definitely not worth mentioning for experts, but it can be regarded as a plug-in and input method! Off topic - Can C# be used as a plug-in? The answer is yes, there is still a lot of information on C# APIProgramming for Windows. Here is a brief introduction to the APIs that may be used:
InstallA hook is installed to intercept mouse and keyboard signals
public static extern int SetWindowsHookEx (int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
##Stop using hooks
public static extern bool UnhookWindowsHookEx(int idHook);
# #Continue to next hook via message hook
##public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam); Thread hooks need to be used
static
extern intGet
CurrentThreadId();
instead of the function that obtains the current instance to prevent hook failurepublic static extern IntPtr GetModuleHandle(string name); 转换指定的虚拟键码和键盘状态的相应字符或字符 public static extern int ToAscii(int uVirtKey, //[in] 指定虚拟关键代码进行翻译。 1.有了以上的这些api基本上就可能实现鼠标键盘的监控或者锁定等;那么首先要安装钩子: 2.安装完后就要对获取到钩子进行处理: 上面一些数字,对于刚入门的同学来说也不是什么问题,一看就明白是对哪些键做的操作。 3.停止钩子 4.注册事件 5.根据输入内容显示并进行转换 6.显示输入 7.空格上屏 8.将数据发送到激活的输入框中 9.back键回退 当然这里还可以使其他键来完善更多的功能,例如拼音的分页处理等 至于什么五笔、拼音就要使用词库来解决了;其中五笔比较简单,拼音就非常复杂了,各种分词、联想等...这里以五笔为主,拼音为单拼来实现基本的输入功能;所以不需要什么高深算法,简单使用MemoryCache就轻松高效搞定(有兴趣的可以来//m.sbmmt.com/ 上完善) 10.键词转换 到此一个基本型的C#版外挂输入法就成功完成了,源码地址://m.sbmmt.com/
int uScanCode, // [in] 指定的硬件扫描码的关键须翻译成英文。高阶位的这个值设定的关键,如果是(不压)
byte[] lpbKeyState, // [in] 指针,以256字节数组,包含当前键盘的状态。每个元素(字节)的数组包含状态的一个关键。如果高阶位的字节是一套,关键是下跌(按下)。在低比特,如果设置表明,关键是对切换。在此功能,只有肘位的CAPS LOCK键是相关的。在切换状态的NUM个锁和滚动锁定键被忽略。
byte[] lpwTransKey, // [out] 指针的缓冲区收到翻译字符或字符。
int fuState); // 安装键盘钩子 public void Start()
{
if (hKeyboardHook == 0)
{
KeyboardHookProcedure = new HookProc(KeyboardHookProc);
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0); //如果SetWindowsHookEx失败
if (hKeyboardHook == 0)
{
Stop(); throw new Exception("安装键盘钩子失败");
}
}
}
private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{ // 侦听键盘事件
if (nCode >= 0 && wParam == 0x0100)
{
KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct)); #region 开关 if (MyKeyboardHookStruct.vkCode == 20 || MyKeyboardHookStruct.vkCode == 160 || MyKeyboardHookStruct.vkCode == 161)
{
isLocked = isLocked ? false : true;
} #endregion
#region
if (isLocked)
{ if (isStarted && MyKeyboardHookStruct.vkCode >= 48 && MyKeyboardHookStruct.vkCode <= 57)
{ var c = int.Parse(((char)MyKeyboardHookStruct.vkCode).ToString());
OnSpaced(c);
isStarted = false; return 1;
} if (isStarted && MyKeyboardHookStruct.vkCode == 8)
{
OnBacked(); return 1;
} if ((MyKeyboardHookStruct.vkCode >= 65 && MyKeyboardHookStruct.vkCode <= 90) || MyKeyboardHookStruct.vkCode == 32)
{ if (MyKeyboardHookStruct.vkCode >= 65 && MyKeyboardHookStruct.vkCode <= 90)
{
Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgs e = new KeyEventArgs(keyData);
KeyUpEvent(this, e);
isStarted = true;
} if (MyKeyboardHookStruct.vkCode == 32)
{
OnSpaced(0);
isStarted = false;
} return 1;
} else
return 0;
} #endregion
} return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
1 public void Stop() 2 { 3 bool retKeyboard = true; 4 5 6 if (hKeyboardHook != 0) 7 { 8 retKeyboard = UnhookWindowsHookEx(hKeyboardHook); 9 hKeyboardHook = 0;10 }11 12 if (!(retKeyboard))13 throw new Exception("卸载钩子失败!");14 }
1 private void WordBoard_Load(object sender, EventArgs e)2 {3 Program.keyBordHook.KeyUpEvent += KeyBordHook_KeyUpEvent;4 Program.keyBordHook.OnSpaced += KeyBordHook_OnSpaced;5 Program.keyBordHook.OnBacked += KeyBordHook_OnBacked;6 }
1 private void ShowCharatar() 2 { 3 this.listView1.BeginInvoke(new Action(() => 4 { 5 label1.Text = keys; 6 7 try 8 { 9 this.listView1.Items.Clear();10 var arr = CacheHelper.Get(keys);11 if (arr != null)12 for (int i = 0; i < (arr.Length > 10 ? 9 : arr.Length); i++)13 {14 this.listView1.Items.Add((i + 1) + "、" + arr[i]);15 }16 }17 catch18 {19 label1.Text = keys = "";20 }21 }));22 }
1 private void KeyBordHook_KeyUpEvent(object sender, KeyEventArgs e)2 {3 keys += e.KeyCode.ToString().ToLower();4 this.ShowCharatar();5 }
1 private void KeyBordHook_OnSpaced(int choose) 2 { 3 try 4 { 5 if (CacheHelper.ContainsKey(keys)) 6 { 7 if (choose > 0) 8 { 9 choose = choose - 1;10 }11 12 Program.keyBordHook.Send(CacheHelper.Get(keys)[choose]);13 label1.Text = "";14 this.listView1.Clear();15 }16 }17 catch18 {19 20 }21 keys = "";22 }
1 public void Send(string msg)2 {3 if (!string.IsNullOrEmpty(msg))4 {5 Stop();6 SendKeys.Send("{RIGHT}" + msg);7 Start();8 }9 }
1 private void KeyBordHook_OnBacked()2 {3 if (!string.IsNullOrEmpty(keys))4 {5 keys = keys.Substring(0, keys.Length - 1);6 }7 this.ShowCharatar();8 }
1 /***************************************************************************************************** 2 * 本代码版权归@wenli所有,All Rights Reserved (C) 2015-2017 3 ***************************************************************************************************** 4 * CLR版本:4.0.30319.42000 5 * 唯一标识:8ebc884b-ee5f-45de-8638-c054b832e0ce 6 * 机器名称:WENLI-PC 7 * 联系人邮箱:wenguoli_520@qq.com 8 ***************************************************************************************************** 9 * 项目名称:$projectname$ 10 * 命名空间:Wenli.IEM 11 * 类名称:CacheHelper 12 * 创建时间:2017/3/3 16:18:14 13 * 创建人:wenli 14 * 创建说明: 15 *****************************************************************************************************/ 16 using System; 17 using System.Collections.Generic; 18 using System.IO; 19 using System.Linq; 20 using System.Runtime.Caching; 21 using System.Text; 22 using System.Windows.Forms; 23 24 namespace Wenli.IEM.Helper 25 { 26 public static class CacheHelper 27 { 28 static MemoryCache _wubiCache = new MemoryCache("wubi"); 29 30 static MemoryCache _pinyinCache = new MemoryCache("pinyin"); 31 32 static CacheHelper() 33 { 34 var path = Application.StartupPath + "\\Win32\\world.dll"; 35 var arr = File.ReadAllLines(path); 36 foreach (string item in arr) 37 { 38 var key = item.Substring(0, item.IndexOf(" ")); 39 var value = item.Substring(item.IndexOf(" ") + 1); 40 _wubiCache.Add(key, (object)value, DateTimeOffset.MaxValue); 41 } 42 43 // 44 45 path = Application.StartupPath + "\\Win32\\pinyin.dll"; 46 arr = File.ReadAllLines(path); 47 foreach (string item in arr) 48 { 49 var key = item.Substring(0, item.IndexOf(" ")); 50 var value = item.Substring(item.IndexOf(" ") + 1); 51 _pinyinCache.Add(key, (object)value, DateTimeOffset.MaxValue); 52 } 53 } 54 55 public static string[] Get(string key) 56 { 57 if (!string.IsNullOrEmpty(key)) 58 { 59 var str = string.Empty; 60 61 try 62 { 63 if (_wubiCache.Contains(key)) 64 str = _wubiCache[key].ToString(); 65 } 66 catch { } 67 try 68 { 69 if (_pinyinCache.Contains(key)) 70 str += " " + _pinyinCache[key].ToString(); 71 } 72 catch { } 73 74 if (!string.IsNullOrEmpty(str)) 75 { 76 var arr = str.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); 77 for (int i = 0; i < arr.Length; i++) 78 { 79 if (arr[i].IndexOf("*") > -1) 80 { 81 arr[i] = arr[i].Substring(0, arr[i].IndexOf("*")); 82 } 83 } 84 return arr; 85 } 86 } 87 88 return null; 89 } 90 91 92 public static bool ContainsKey(string key) 93 { 94 if (_wubiCache.Contains(key)) 95 return true; 96 if (_pinyinCache.Contains(key)) 97 return true; 98 return false; 99 }100 101 public static void Clear()102 {103 _wubiCache.Dispose();104 GC.Collect(-1);105 }106 }107 }
The above is the detailed content of C# input method. For more information, please follow other related articles on the PHP Chinese website!