Maison développement back-end Tutoriel C#.Net C# Introduction aux méthodes de saisie

C# Introduction aux méthodes de saisie

Apr 24, 2017 am 11:46 AM

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);
Copier après la connexion

停止使用钩子

publicstatic extern bool UnhookWindowsHookEx(intidHook);
Copier après la connexion

通过信息钩子继续下一个钩子

publicstatic extern int CallNextHookEx(intidHook, int nCode, Int32 wParam, IntPtr lParam);
Copier après la connexion

线程钩子需要用到

static extern int GetCurrentThreadId();
Copier après la connexion

使用WINDOWS API函数代替获取当前实例的函数,防止钩子失效

publicstatic extern IntPtr GetModuleHandle(stringname);
Copier après la connexion

转换指定的虚拟键码和键盘状态的相应字符或字符

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("安装键盘钩子失败");
                }
            }
        }
Copier après la connexion

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);
        }
Copier après la connexion

上面一些数字,对于刚入门的同学来说也不是什么问题,一看就明白是对哪些键做的操作。

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         }
Copier après la connexion

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         }
Copier après la connexion

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         }
Copier après la connexion

6.显示输入

1 private void KeyBordHook_KeyUpEvent(object sender, KeyEventArgs e)2         {3             keys += e.KeyCode.ToString().ToLower();4             this.ShowCharatar();5         }
Copier après la connexion

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         }
Copier après la connexion

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         }
Copier après la connexion

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         }
Copier après la connexion

当然这里还可以使其他键来完善更多的功能,例如拼音的分页处理等

至于什么五笔、拼音就要使用词库来解决了;其中五笔比较简单,拼音就非常复杂了,各种分词、联想等...这里以五笔为主,拼音为单拼来实现基本的输入功能;所以不需要什么高深算法,简单使用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 }
Copier après la connexion

到此一个基本型的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!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

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

Active Directory avec C# Active Directory avec C# Sep 03, 2024 pm 03:33 PM

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.

Générateur de nombres aléatoires en C# Générateur de nombres aléatoires en C# Sep 03, 2024 pm 03:34 PM

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.

Vue Grille de données C# Vue Grille de données C# Sep 03, 2024 pm 03:32 PM

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.

Modificateurs d'accès en C# Modificateurs d'accès en C# Sep 03, 2024 pm 03:24 PM

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.

Sérialisation C# Sérialisation C# Sep 03, 2024 pm 03:30 PM

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.

Nombres premiers en C# Nombres premiers en C# Sep 03, 2024 pm 03:35 PM

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.

Modèles en C# Modèles en C# Sep 03, 2024 pm 03:33 PM

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.

Factorielle en C# Factorielle en C# Sep 03, 2024 pm 03:34 PM

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.

See all articles