項(xiàng)目需要在觸摸屏上增加一個(gè)虛擬鍵盤。記錄下過程中遇到的問題及解決方法。
1.模擬按鍵
網(wǎng)上找到如下3種方法
1)SendKeys.Send
測(cè)試單獨(dú)的shift不好用,所以最終未采納此方法
SendKeys.Send("^{E}");//shift+e SendKeys.Send("{Enter}");
2)keybd_event
最終選擇了這個(gè)方法,簡(jiǎn)單有效。
虛擬按鍵對(duì)照表:https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
[DllImport("user32.dll", EntryPoint = "keybd_event", SetLastError = true)] public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo); [DllImport("user32.dll", EntryPoint = "keybd_event", SetLastError = true)]
public static extern void keybd_event(Keys bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
public static uint KEYEVENTF_KEYDOWN = 0;// 鍵按下 KEYEVENTF_KEYDOWN = 0
public static uint KEYEVENTF_KEYUP = 2;//鍵彈起 KEYEVENTF_KEYUP = 2
keybd_event(0x14, 0, KEYEVENTF_KEYDOWN, 0); //鍵按下 KEYEVENTF_KEYDOWN = 0
keybd_event(0x14, 0, KEYEVENTF_KEYUP, 0); //鍵彈起 KEYEVENTF_KEYUP = 2
3)PostMessage
這個(gè)方法也是簡(jiǎn)單有效,但是據(jù)說(shuō)有些其他問題,沒有仔細(xì)研究,有興趣的可以自己研究。
[DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)] public static extern int PostMessage(IntPtr hWnd, int Msg, Keys wParam, int lParam); PostMessage(textBox2.Handle, 256, Keys.D, 2);//模擬按下2次 Keys.D
2.各種類型鍵的處理
微軟對(duì)鍵盤輸入有進(jìn)行了分類,可以參考這個(gè)。
https://learn.microsoft.com/zh-cn/windows/win32/learnwin32/keyboard-input
1)CapsLock鍵/NumLock鍵
想要實(shí)現(xiàn)鍵盤按下抬起與界面效果相同,就需要捕獲鍵盤操作。我使用了Hook
以下這篇博客寫的很清晰明了,就不贅述了。
https://www.cnblogs.com/chorm590/p/14199978.html
在hook回調(diào)函數(shù)中做了如下處理
private int keyboardHookCallback(int code, IntPtr wParam, IntPtr lParam) { if (code < 0) { return User32.CallNextHookEx(IntPtr.Zero, code, wParam, lParam); } else { Keyboard_LL_Hook_Data khd = (Keyboard_LL_Hook_Data)Marshal.PtrToStructure(lParam, typeof(Keyboard_LL_Hook_Data)); System.Diagnostics.Debug.WriteLine($"key event:{wParam}, key code:{khd.vkCode}, event time:{khd.time}"); if ((int)wParam == 256 && khd.vkCode == 0x14) { IsCapsLockDown = !IsCapsLockDown; } return User32.CallNextHookEx(IntPtr.Zero, code, wParam, lParam); } } private bool isCapsLockDown; private bool IsCapsLockDown { get { return isCapsLockDown; } set { isCapsLockDown = value; this.buttonCapsLock.BackColor = value ? Color.Gray : Control.DefaultBackColor; } } private void buttonCapsLock_Click(object sender, EventArgs e) { User32.keybd_event(VirtualKeyCode.CAPS_LOCK, 0, 0, 0); //鍵按下 KEYEVENTF_KEYDOWN = 0 User32.keybd_event(VirtualKeyCode.CAPS_LOCK, 0, 2, 0); //鍵彈起 KEYEVENTF_KEYUP = 2 }
初始化時(shí)同步鍵盤CapsLock/NumLock狀態(tài),使用user32.GetKeyState.返回值等于1則按下狀態(tài)
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] public static extern short GetKeyState(int keyCode); public static bool GetState(byte VKeyCode) { return (User32.GetKeyState(VKeyCode) == 1); }
2)其他組合鍵處理
ctrl+shift切換輸入法,只響應(yīng)這一種功能鍵+功能鍵。其他小伙伴有好的方法可以分享一下。
3)輸入鍵+組合鍵
如ctrl+c,ctrl+v,ctrl+a,ctrl+z等等。
此方法不是最優(yōu)方式,可以改進(jìn)功能鍵存放在Queue中,遍歷功能鍵,按順序響應(yīng)。
private void HandleKeysCombin(byte VKCode) { //設(shè)置焦點(diǎn)控件 this.ActiveControl = this.m_CustomActiveControl; lock (this) { if (IsCtrlDown) { keybd_event(VirtualKeyCode.CTRL, 0, KEYEVENTF_KEYDOWN, 0); //鍵按下 KEYEVENTF_KEYDOWN = 0 } if (IsShiftDown) { keybd_event(VirtualKeyCode.SHIFT, 0, KEYEVENTF_KEYDOWN, 0); //鍵按下 KEYEVENTF_KEYDOWN = 0 } if (IsAltDown) { keybd_event(VirtualKeyCode.ALT, 0, KEYEVENTF_KEYDOWN, 0); //鍵按下 KEYEVENTF_KEYDOWN = 0 } keybd_event(VKCode, VKCode, User32.KEYEVENTF_KEYDOWN, 0); //鍵按下 KEYEVENTF_KEYDOWN = 0 keybd_event(VKCode, VKCode, User32.KEYEVENTF_KEYUP, 0); //鍵彈起 KEYEVENTF_KEYUP = 2 if (IsCtrlDown) { keybd_event(VirtualKeyCode.CTRL, 0, KEYEVENTF_KEYUP, 0); //鍵彈起 KEYEVENTF_KEYUP = 2 IsCtrlDown = false; } if (IsShiftDown) { keybd_event(VirtualKeyCode.SHIFT, 0, KEYEVENTF_KEYUP, 0); //鍵彈起 KEYEVENTF_KEYUP = 2 IsShiftDown = false; } if (IsAltDown) { keybd_event(VirtualKeyCode.ALT, 0, KEYEVENTF_KEYUP, 0); //鍵彈起 KEYEVENTF_KEYUP = 2 IsAltDown = false; } } }
3.窗體/UserControl焦點(diǎn)的處理
這篇里面方法簡(jiǎn)單好用,不贅述文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-456196.html
?https://blog.csdn.net/accomp/article/details/7209052文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-456196.html
到了這里,關(guān)于Winform虛擬/模擬鍵盤的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!