C#:小工具專案-軟鍵盤實現
阿新 • • 發佈:2018-12-30
0.
之前有篇文章是講鍵盤改鍵,即把一個鍵盤鍵的功能改成另一種功能或組合功能。https://blog.csdn.net/qq_38261174/article/details/84952878
這篇文章主要是講在沒有物理鍵盤的情況下,如何用軟體替代物理鍵盤的功能,從而實現軟鍵盤。
Windows提供了一個模擬鍵盤API函式Keybd_event(),該函式能觸發一個按鍵事件,也就是說會產生一個WM_KEYDOWN或WM_KEYUP訊息。 [DllImport("user32.dll", EntryPoint = "keybd_event")] public static extern void keybd_event( byte bVk, //虛擬鍵值 byte bScan,// 一般為0 int dwFlags, //這裡是整數型別 0 為按下,2為釋放 int dwExtraInfo //這裡是整數型別 一般情況下設成為 0 );
介面設計如下:
程式碼如下:
using System; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; namespace SoftKeyBoard { public partial class Form1 : Form { #region 把當前窗體設定為浮動工具條。不會影響其它程序的窗體的游標焦點。雖然這個窗體現在為當前啟用的前臺窗體,但游標仍然停在其他程序的窗體上 private const int WS_EX_TOOLWINDOW = 0x00000080; private const int WS_EX_NOACTIVATE = 0x08000000; //重寫該方法實現窗體變為浮動工具條,不獲取游標焦點 protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= (WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW); cp.Parent = IntPtr.Zero; return cp; } } #endregion public Form1() { this.TopMost = true; InitializeComponent(); } //模擬鍵盤API 鍵值用byte最準確 [DllImport("user32.dll", EntryPoint = "keybd_event", SetLastError = true)] public static extern void keybd_event1(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo); #region 系統全域性 大小寫按鍵 bool isCapitalization = false; //是否大寫,預設小寫 private void 大小寫_Click(object sender, EventArgs e) { const int KEYEVENTF_EXTENDEDKEY = 0x1; const int KEYEVENTF_KEYUP = 0x2; keybd_event1(0x14, 0x45, KEYEVENTF_EXTENDEDKEY, 0); keybd_event1(0x14, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); if (!isCapitalization) { this.label1.Text = "目前:大寫"; isCapitalization = true; this.大小寫.BackColor = Color.Blue; } else { this.label1.Text = "目前:小寫"; isCapitalization = false; this.大小寫.BackColor = Color.White; } } #endregion //模擬鍵盤API 和上面的API引數型別有區別 鍵值用Keys,大部分準確 [DllImport("user32.dll", EntryPoint = "keybd_event", SetLastError = true)] public static extern void keybd_event(Keys bVk, byte bScan, uint dwFlags, uint dwExtraInfo); #region 系統全域性 windows鍵 private void Windows_Click(object sender, EventArgs e) { keybd_event(Keys.LWin, 0, 0, 0); keybd_event(Keys.LWin, 0, 2, 0); //注意點:一定要按下,再釋放,有些功能才會有果(ctrl shift 等)。 0代表按下,2代表釋放 //下面2行程式碼同樣可以做到 系統全域性-大小寫 //keybd_event(Keys.CapsLock,0,0,0); //keybd_event(Keys.CapsLock, 0, 2, 0); } #endregion #region Ctrl 是否按下 bool isCtrl = false; private void CtrlClick(object sender, EventArgs e) { if (!isCtrl) { isCtrl = true; this.label2.Text = "ctrl已按下"; this.button80.BackColor = Color.Blue; } else { isCtrl = false; this.label2.Text = "ctrl未按下"; this.button80.BackColor = Color.White; } } #endregion #region 數字鍵 多個虛擬數字鍵按鈕-統一監聽 private void NUmberClick(object sender, EventArgs e) { int number = Convert.ToInt32(((Button)sender).Text); //0 1 2 3 4 5 6 7 8 9 switch (number) { case 0: keybd_event(Keys.D0, 0, 0, 0); break; case 1: keybd_event(Keys.D1, 0, 0, 0); break; case 2: keybd_event(Keys.D2, 0, 0, 0); break; case 3: keybd_event(Keys.D3, 0, 0, 0); break; case 4: keybd_event(Keys.D4, 0, 0, 0); break; case 5: keybd_event(Keys.D5, 0, 0, 0); break; case 6: keybd_event(Keys.D6, 0, 0, 0); break; case 7: keybd_event(Keys.D7, 0, 0, 0); break; case 8: keybd_event(Keys.D8, 0, 0, 0); break; case 9: keybd_event(Keys.D9, 0, 0, 0); break; } } #endregion #region 字母鍵,組合鍵 多個虛擬字母鍵按鈕-統一監聽 private void CharClick(object sender, EventArgs e) { String cr = ((Button)sender).Text; switch (cr) { case "a": if (isCtrl) { //組合鍵 ctrl + a 示例:其它組合鍵,自行摸索 keybd_event(Keys.ControlKey, 0, 0, 0); keybd_event(Keys.A, 0, 0, 0); keybd_event(Keys.ControlKey, 0, 2, 0); keybd_event(Keys.A, 0, 2, 0); } else { keybd_event(Keys.A, 0, 0, 0); } break; case "b": keybd_event(Keys.B, 0, 0, 0); break; case "c": keybd_event(Keys.C, 0, 0, 0); break; case "d": keybd_event(Keys.D, 0, 0, 0); break; case "e": keybd_event(Keys.E, 0, 0, 0); break; case "f": keybd_event(Keys.F, 0, 0, 0); break; case "g": keybd_event(Keys.G, 0, 0, 0); break; case "h": keybd_event(Keys.H, 0, 0, 0); break; case "i": keybd_event(Keys.I, 0, 0, 0); break; case "j": keybd_event(Keys.J, 0, 0, 0); break; case "k": keybd_event(Keys.K, 0, 0, 0); break; case "l": keybd_event(Keys.L, 0, 0, 0); break; case "m": keybd_event(Keys.M, 0, 0, 0); break; case "n": keybd_event(Keys.N, 0, 0, 0); break; case "o": keybd_event(Keys.O, 0, 0, 0); break; case "p": keybd_event(Keys.P, 0, 0, 0); break; case "q": keybd_event(Keys.Q, 0, 0, 0); break; case "r": keybd_event(Keys.R, 0, 0, 0); break; case "s": keybd_event(Keys.S, 0, 0, 0); break; case "t": keybd_event(Keys.T, 0, 0, 0); break; case "u": keybd_event(Keys.U, 0, 0, 0); break; case "v": keybd_event(Keys.V, 0, 0, 0); break; case "w": keybd_event(Keys.W, 0, 0, 0); break; case "x": keybd_event(Keys.X, 0, 0, 0); break; case "y": keybd_event(Keys.Y, 0, 0, 0); break; case "z": keybd_event(Keys.Z, 0, 0, 0); break; } } #endregion #region F1-F12 虛擬鍵統一監聽 private void FnClick(object sender, EventArgs e) { String fn = ((Button)sender).Text; switch (fn) { case "F1": keybd_event(Keys.F1, 0, 0, 0); break; case "F2": keybd_event(Keys.F2, 0, 0, 0); break; case "F3": keybd_event(Keys.F3, 0, 0, 0); break; case "F4": keybd_event(Keys.F4, 0, 0, 0); break; case "F5": keybd_event(Keys.F5, 0, 0, 0); break; case "F6": keybd_event(Keys.F6, 0, 0, 0); break; case "F7": keybd_event(Keys.F7, 0, 0, 0); break; case "F8": keybd_event(Keys.F8, 0, 0, 0); break; case "F9": keybd_event(Keys.F9, 0, 0, 0); break; case "F10": keybd_event(Keys.F10, 0, 0, 0); break; case "F11": keybd_event(Keys.F11, 0, 0, 0); break; case "F12": keybd_event(Keys.F12, 0, 0, 0); break; } } #endregion #region 右邊符號鍵 統一監聽 未完成全部程式碼 private void LeftOtherClick(object sender, EventArgs e) { String otherChar = ((Button)sender).Text; switch (otherChar) { case "BackSpace": keybd_event(Keys.Back, 0, 0, 0); break; case "Enter": keybd_event(Keys.Enter, 0, 0, 0); break; case " ": keybd_event(Keys.Space, 0, 0, 0); break; //case "#": // break; //case "$": // break; //case "%": // break; //case "^": // break; //case "&&": // break; //case "*": // break; //case "(": // break; //case ")": // break; //case "": // break; //case "": // break; //todo other } } #endregion //除了呼叫 user32.dll 實現模擬按鍵外,還有另外一種 SendKeys //組合鍵:Ctrl = ^ Shift = + Alt = % private void button1_Click(object sender, EventArgs e) { //括號中的內容就是虛擬按鍵的內容,可以有如下值: //ENTER BACKSPACE END HOME DELETE + - * / \\ 等... SendKeys.Send("^+"); //ctrl + shift 由於用上面的user32.dll 我沒解決 ctrl +shift組合鍵的問題,所以這裡可以解決 //SendKeys.Send("a"); //a 區分大小寫 //SendKeys.Send("^{A}"); //ctrl + A } } }
實現軟鍵盤,有幾個需要注意的地方:
- 窗體要設定為浮動工具條,不獲取其它窗體的游標焦點。不然的話,虛擬按鍵不知道在哪裡輸出
- 有一些特殊的鍵用user32.dll方法模擬時一定要 按下(0)和釋放(2)兩行程式碼才起作用。
完!
對應下載:https://github.com/520xchly/C-