国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

香港云服务器
服務器之家 - 編程語言 - C# - C#實現輸入法功能詳解

C#實現輸入法功能詳解

2021-12-29 13:27YSWALLE C#

本文主要介紹了C#實現輸入法的相關知識。具有很好的參考價值。下面跟著小編一起來看下吧

雖說輸入法不是什么新事物,各種語言版本都有,不過在c#不常見;這就會給人一種誤會:c#不能做!其實c#能不能做呢,答案是肯定的——三種方式都行:imm、tsf以及外掛式。imm這種就是調windows的一些底層api,不過在新版本的windows中基本上已經不能用了,屬于一種過時的操作方式。tsf是微軟推薦的一種新方式,不過相對c#資料太少;線上主要的一些都是針對c++的版本資料,當然可以作為借鑒來實現c#版的。我這里主要介紹一種外掛式的(天啦擼,c#可以寫外掛?),對于高手來說肯定不值一提,不過也算是實現了外掛及輸入法!題外話——c#可以做外掛么?答案是可以的,c#針對windows的api編程資料還是很多的,下面就簡單的介紹一下面可能要使用到的api:

安裝了一個鉤子,截取鼠標鍵盤等信號

?
1
public static extern int setwindowshookex(int idhook, hookproc lpfn, intptr hinstance, int threadid);

停止使用鉤子

public static extern bool unhookwindowshookex(int idhook);

通過信息鉤子繼續下一個鉤子

public static extern int callnexthookex(int idhook, int ncode, int32 wparam, intptr lparam);

線程鉤子需要用到

static extern int getcurrentthreadid();

使用windows api函數代替獲取當前實例的函數,防止鉤子失效

public static extern intptr getmodulehandle(string name);

轉換指定的虛擬鍵碼和鍵盤狀態的相應字符或字符

?
1
2
3
4
5
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基本上就可能實現鼠標鍵盤的監控或者鎖定等;那么首先要安裝鉤子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 安裝鍵盤鉤子
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.安裝完后就要對獲取到鉤子進行處理:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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
2
3
4
5
6
7
8
9
10
11
public void stop()
  {
   bool retkeyboard = true;
   if (hkeyboardhook != 0)
   {
    retkeyboard = unhookwindowshookex(hkeyboardhook);
    hkeyboardhook = 0;
   }
   if (!(retkeyboard))
    throw new exception("卸載鉤子失敗!");
  }

4.注冊事件

?
1
2
3
4
5
6
private void wordboard_load(object sender, eventargs e)
  {
   program.keybordhook.keyupevent += keybordhook_keyupevent;
   program.keybordhook.onspaced += keybordhook_onspaced;
   program.keybordhook.onbacked += keybordhook_onbacked;
  }

5.根據輸入內容顯示并進行轉換

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private void showcharatar()
  {
   this.listview1.begininvoke(new action(() =>
   {
    label1.text = keys;
    try
    {
     this.listview1.items.clear();
     var arr = cachehelper.get(keys);
     if (arr != null)
      for (int i = 0; i < (arr.length > 10 ? 9 : arr.length); i++)
      {
       this.listview1.items.add((i + 1) + "、" + arr[i]);
      }
    }
    catch
    {
     label1.text = keys = "";
    }
   }));
  }

6.顯示輸入

?
1
2
3
4
5
private void keybordhook_keyupevent(object sender, keyeventargs e)
  {
   keys += e.keycode.tostring().tolower();
   this.showcharatar();
  }

7.空格上屏

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private void keybordhook_onspaced(int choose)
  {
   try
   {
    if (cachehelper.containskey(keys))
    {
     if (choose > 0)
     {
      choose = choose - 1;
     }
     program.keybordhook.send(cachehelper.get(keys)[choose]);
     label1.text = "";
     this.listview1.clear();
    }
   }
   catch
   {
   }
   keys = "";
  }

8.將數據發送到激活的輸入框中

?
1
2
3
4
5
6
7
8
9
public void send(string msg)
  {
   if (!string.isnullorempty(msg))
   {
    stop();
    sendkeys.send("{right}" + msg);
    start();
   }
  }

9.back鍵回退

?
1
2
3
4
5
6
7
8
private void keybordhook_onbacked()
  {
   if (!string.isnullorempty(keys))
   {
    keys = keys.substring(0, keys.length - 1);
   }
   this.showcharatar();
  }

當然這里還可以使其他鍵來完善更多的功能,例如拼音的分頁處理等

至于什么五筆、拼音就要使用詞庫來解決了;其中五筆比較簡單,拼音就非常復雜了,各種分詞、聯想等...這里以五筆為主,拼音為單拼來實現基本的輸入功能;所以不需要什么高深算法,簡單使用memorycache就輕松高效搞定(有興趣的可以來https://github.com/yswenli/wenli.iem 上完善)

10.鍵詞轉換

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*****************************************************************************************************
 * 本代碼版權歸@wenli所有,all rights reserved (c) 2015-2017
*****************************************************************************************************
 * clr版本:4.0.30319.42000
 * 唯一標識:8ebc884b-ee5f-45de-8638-c054b832e0ce
 * 機器名稱:wenli-pc
 * 聯系人郵箱:wenguoli_520@qq.com
*****************************************************************************************************
 * 項目名稱:$projectname$
 * 命名空間:wenli.iem
 * 類名稱:cachehelper
 * 創建時間:2017/3/3 16:18:14
 * 創建人:wenli
 * 創建說明:
*****************************************************************************************************/
using system;
using system.collections.generic;
using system.io;
using system.linq;
using system.runtime.caching;
using system.text;
using system.windows.forms;
namespace wenli.iem.helper
{
 public static class cachehelper
 {
  static memorycache _wubicache = new memorycache("wubi");
  static memorycache _pinyincache = new memorycache("pinyin");
  static cachehelper()
  {
   var path = application.startuppath + "\\win32\\world.dll";
   var arr = file.readalllines(path);
   foreach (string item in arr)
   {
    var key = item.substring(0, item.indexof(" "));
    var value = item.substring(item.indexof(" ") + 1);
    _wubicache.add(key, (object)value, datetimeoffset.maxvalue);
   }
   //
   path = application.startuppath + "\\win32\\pinyin.dll";
   arr = file.readalllines(path);
   foreach (string item in arr)
   {
    var key = item.substring(0, item.indexof(" "));
    var value = item.substring(item.indexof(" ") + 1);
    _pinyincache.add(key, (object)value, datetimeoffset.maxvalue);
   }
  }
  public static string[] get(string key)
  {
   if (!string.isnullorempty(key))
   {
    var str = string.empty;
    try
    {
     if (_wubicache.contains(key))
      str = _wubicache[key].tostring();
    }
    catch { }
    try
    {
     if (_pinyincache.contains(key))
      str += " " + _pinyincache[key].tostring();
    }
    catch { }
    if (!string.isnullorempty(str))
    {
     var arr = str.split(new string[] { " " }, stringsplitoptions.removeemptyentries);
     for (int i = 0; i < arr.length; i++)
     {
      if (arr[i].indexof("*") > -1)
      {
       arr[i] = arr[i].substring(0, arr[i].indexof("*"));
      }
     }
     return arr;
    }
   }
   return null;
  }
  public static bool containskey(string key)
  {
   if (_wubicache.contains(key))
    return true;
   if (_pinyincache.contains(key))
    return true;
   return false;
  }
  public static void clear()
  {
   _wubicache.dispose();
   gc.collect(-1);
  }
 }
}

到此一個基本型的c#版外掛輸入法就成功完成了,源碼地址:https://github.com/yswenli/wenli.iem

C#實現輸入法功能詳解

C#實現輸入法功能詳解

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持服務器之家!

原文鏈接:http://www.cnblogs.com/yswenli/p/6528447.html

延伸 · 閱讀

精彩推薦
  • C#C#裁剪,縮放,清晰度,水印處理操作示例

    C#裁剪,縮放,清晰度,水印處理操作示例

    這篇文章主要為大家詳細介紹了C#裁剪,縮放,清晰度,水印處理操作示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    吳 劍8332021-12-08
  • C#WPF 自定義雷達圖開發實例教程

    WPF 自定義雷達圖開發實例教程

    這篇文章主要介紹了WPF 自定義雷達圖開發實例教程,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下...

    WinterFish13112021-12-06
  • C#C#實現XML文件讀取

    C#實現XML文件讀取

    這篇文章主要為大家詳細介紹了C#實現XML文件讀取的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Just_for_Myself6702022-02-22
  • C#C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    這篇文章主要介紹了C# 實現對PPT文檔加密、解密及重置密碼的操作方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下...

    E-iceblue5012022-02-12
  • C#Unity3D實現虛擬按鈕控制人物移動效果

    Unity3D實現虛擬按鈕控制人物移動效果

    這篇文章主要為大家詳細介紹了Unity3D實現虛擬按鈕控制人物移動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一...

    shenqingyu060520232410972022-03-11
  • C#C#通過KD樹進行距離最近點的查找

    C#通過KD樹進行距離最近點的查找

    這篇文章主要為大家詳細介紹了C#通過KD樹進行距離最近點的查找,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    帆帆帆6112022-01-22
  • C#C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    這篇文章主要介紹了C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題,簡單描述了訪問者模式的定義并結合具體實例形式分析了C#使用訪問者模式解決長...

    GhostRider9502022-01-21
  • C#深入解析C#中的交錯數組與隱式類型的數組

    深入解析C#中的交錯數組與隱式類型的數組

    這篇文章主要介紹了深入解析C#中的交錯數組與隱式類型的數組,隱式類型的數組通常與匿名類型以及對象初始值設定項和集合初始值設定項一起使用,需要的...

    C#教程網6172021-11-09
1462
主站蜘蛛池模板: 欧美国产精品一区二区 | 国产欧美一区二区精品性色 | 欧美亚洲天堂 | 激情视频综合网 | 国产免费一区二区三区 | 免费看一区二区三区 | 亚洲在线一区 | 久久草在线视频 | 国产精品久久久久久久美男 | 午夜成人免费电影 | 国产精品久久久久久久久久久久冷 | 好吊在线观看 | 在线中文字幕视频 | 国产精品网站在线观看 | 中文字幕在线免费视频 | 欧美日韩中文国产一区发布 | 日韩av在线免费 | 久久男人 | 欧美精品欧美极品欧美激情 | 看国产黄色片 | 中文字幕一区二区三区乱码在线 | 亚洲精品日韩综合观看成人91 | 久久99精品久久久久蜜臀 | 日本三级中文在线电影 | 成年人在线免费观看网站 | 欧美一级二级视频 | 精品久久伊人 | 91精品国产乱码久久久久久久久 | 免费黄色小视频 | 亚洲一区二区中文字幕 | 99国产精品99久久久久久 | 久草一区 | 综合久 | 久久91精品 | 日韩欧美一区二区三区久久婷婷 | 国产精品一区在线观看 | 色婷婷综合久久久中字幕精品久久 | 日本黄色激情片 | 欧美日韩成人网 | 亚洲精品中文字幕 | 无码一区二区三区视频 |