C# Introduction aux méthodes de saisie
C# 输入法
虽说输入法不是什么新事物,各种语言版本都有,不过在C#不常见;这就会给人一种误会:C#不能做!其实C#能不能做呢,答案是肯定的——三种方式都行:IMM、TSF以及外挂式。IMM这种就是调windows的一些底层api,不过在新版本的windows中基本上已经不能用了,属于一种过时的操作方式。TSF是微软推荐的一种新方式,不过相对C#资料太少;线上主要的一些都是针对C++的版本资料,当然可以作为借鉴来实现C#版的。我这里主要介绍一种外挂式的(天啦撸,C#可以写外挂?),对于高手来说肯定不值一提,不过也算是实现了外挂及输入法!题外话——C#可以做外挂么?答案是可以的,C#针对windows的api编程资料还是很多的,下面就简单的介绍一下面可能要使用到的api:
安装了一个钩子,截取鼠标键盘等信号
public static extern int SetWindowsHookEx( int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
停止使用钩子
publicstatic extern bool UnhookWindowsHookEx(intidHook);
通过信息钩子继续下一个钩子
publicstatic extern int CallNextHookEx(intidHook, int nCode, Int32 wParam, IntPtr lParam);
线程钩子需要用到
static extern int GetCurrentThreadId();
使用WINDOWS API函数代替获取当前实例的函数,防止钩子失效
publicstatic extern IntPtr GetModuleHandle(stringname);
转换指定的虚拟键码和键盘状态的相应字符或字符
public static extern int ToAscii(int uVirtKey, //[in] 指定虚拟关键代码进行翻译。
int uScanCode, // [in] 指定的硬件扫描码的关键须翻译成英文。高阶位的这个值设定的关键,如果是(不压)
byte[] lpbKeyState, // [in] 指针,以256字节数组,包含当前键盘的状态。每个元素(字节)的数组包含状态的一个关键。如果高阶位的字节是一套,关键是下跌(按下)。在低比特,如果设置表明,关键是对切换。在此功能,只有肘位的CAPS LOCK键是相关的。在切换状态的NUM个锁和滚动锁定键被忽略。
byte[] lpwTransKey, // [out] 指针的缓冲区收到翻译字符或字符。
int fuState);
1.有了以上的这些api基本上就可能实现鼠标键盘的监控或者锁定等;那么首先要安装钩子:
// 安装键盘钩子 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("安装键盘钩子失败"); } } }
2.安装完后就要对获取到钩子进行处理:
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); }
上面一些数字,对于刚入门的同学来说也不是什么问题,一看就明白是对哪些键做的操作。
3.停止钩子
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 }
4.注册事件
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 }
5.根据输入内容显示并进行转换
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 }
6.显示输入
1 private void KeyBordHook_KeyUpEvent(object sender, KeyEventArgs e)2 {3 keys += e.KeyCode.ToString().ToLower();4 this.ShowCharatar();5 }
7.空格上屏
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 }
8.将数据发送到激活的输入框中
1 public void Send(string msg)2 {3 if (!string.IsNullOrEmpty(msg))4 {5 Stop();6 SendKeys.Send("{RIGHT}" + msg);7 Start();8 }9 }
9.back键回退
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 }
当然这里还可以使其他键来完善更多的功能,例如拼音的分页处理等
至于什么五笔、拼音就要使用词库来解决了;其中五笔比较简单,拼音就非常复杂了,各种分词、联想等...这里以五笔为主,拼音为单拼来实现基本的输入功能;所以不需要什么高深算法,简单使用MemoryCache就轻松高效搞定
10.键词转换
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 }
到此一个基本型的C#版外挂输入法就成功完成了
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Guide d'Active Directory avec C#. Nous discutons ici de l'introduction et du fonctionnement d'Active Directory en C# ainsi que de la syntaxe et de l'exemple.

Guide du générateur de nombres aléatoires en C#. Nous discutons ici du fonctionnement du générateur de nombres aléatoires, du concept de nombres pseudo-aléatoires et sécurisés.

Guide de la vue Grille de données C#. Nous discutons ici des exemples de la façon dont une vue de grille de données peut être chargée et exportée à partir de la base de données SQL ou d'un fichier Excel.

Guide des modificateurs d'accès en C#. Nous avons discuté de l'introduction Types de modificateurs d'accès en C# ainsi que d'exemples et de résultats.

Guide de sérialisation C#. Nous discutons ici de l'introduction, des étapes de l'objet de sérialisation C#, du fonctionnement et de l'exemple respectivement.

Guide des nombres premiers en C#. Nous discutons ici de l'introduction et des exemples de nombres premiers en c# ainsi que de l'implémentation du code.

Guide des modèles en C#. Nous discutons ici de l'introduction et des 3 principaux types de modèles en C# ainsi que de ses exemples et de l'implémentation du code.

Guide de Factorial en C#. Nous discutons ici de l'introduction de factorial en c# ainsi que de différents exemples et de l'implémentation du code.
