是否有可能捕获KeyDown事件并在C#中取消此事件?

时间:2014-02-04 09:13:54

标签: c# winapi keyboard-events

我想将拉丁语键盘翻译成另一个键盘,如维吾尔语等。有一个维吾尔语键盘,但键的编码是如此复杂,以至于普通PC用户不能轻易键入维吾尔语。

所以我的目标是为这个问题创建一个软件解决方案,例如中文输入系统。在该系统中,您可以从各种键盘输入中文字符。这是一种聪明的解决方案,所以每个人都可以毫无问题地使用它。

所以我的目标是我想编写一个Windows服务应用程序,它捕获每个KeyDown-Strike(仅字母表)并将按下的键转换为目标(Unicode)字母并再次使用此翻译的字母模拟键击。结果,目标字母表将显示在光标点中。在结束时,我的应用程序从KEYDOWN按下

中丢弃/停止原始密钥

这样就不会再显示了。

例如:

  1. K
  2. 捕获 K 并将其翻译为Unicode,如0xFEBD,然后发送回光标点。
  3. 取消或放弃 K 的按键事件。不应在光标处看到此字符。
  4. 到目前为止,第1步和第2步工作正常。我的问题是,在我捕获按键事件后,我无法丢弃/取消/停止此次击键的最后一次按键事件。

    我不确定我的想法是否良好/有效,足以实现我的想法。现在我只是在尝试。也许你有更好的想法,你可以建议我。这是我的代码:

    public class Simulate
    {
        [DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
        static extern UInt32 SendInput(UInt32 numberOfInputs, INPUT[] input, Int32 sizeOfInputStructure);
    
        [StructLayout(LayoutKind.Sequential, Size = 24)]
        struct KEYBDINPUT
        {
            public UInt16 Vk;
            public UInt16 Scan;
            public UInt32 Flags;
            public UInt32 Time;
            public UInt32 ExtraInfo;
        }
    
        [StructLayout(LayoutKind.Explicit)]
        private struct INPUT
        {
            [FieldOffset(0)]
            public int Type;
            [FieldOffset(4)]
            public KEYBDINPUT ki;
        }
        public static void UnicodeInput(UInt16 unicode)
        { 
                INPUT down = new INPUT();
                down.Type = 1; //INPUT_KEYBOARD
                down.ki.Vk = 0;
                down.ki.Scan = unicode;
                down.ki.Time = 0;
                down.ki.Flags = 0x0004; //KEYEVENTF_UNICODE
                down.ki.ExtraInfo = 0;
    
                INPUT up = new INPUT();
                up.Type = 1; //INPUT_KEYBOARD
                up.ki.Vk = 0;
                up.ki.Scan = unicode;
                up.ki.Time = 0;
                up.ki.Flags = 0x0004; //KEYEVENTF_UNICODE
                up.ki.ExtraInfo = 0;
    
                INPUT[] input = new INPUT[2];
                input[0] = down;
                input[1] = up;
                SendInput(1, input, Marshal.SizeOf(typeof(INPUT))); 
        }
    
    }    
    
    /// Capture any window key
    /// 
    public static class WinKeyCapture
    {
        private const int WH_KEYBOARD_LL = 13;
        private const int WH_CALLWNDPROC = 4;
        private const int WM_KEYDOWN = 0x0100;
        private const int WM_CHAR = 0x0102;
        const int VK_A = 0x08;// 0x41; //up key
        const int VK_DOWN = 0x28;  //down key
        const int VK_LEFT = 0x25;
        const int VK_RIGHT = 0x27;
        const uint KEYEVENTF_KEYUP = 0x0002;
        const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
    
        const uint KEYEVENTF_CTRL = 0x11;
        const uint KEYEVENTF_ADD = 0x6B;
        const uint VK_LWIN = 0x5b;
        private static LowLevelKeyboardProc _proc = WinKeyCapture.HookCallback; 
        [DllImport("user32.dll")]
        public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook,
            LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
    
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);
    
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
            IntPtr wParam, IntPtr lParam);
    
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);
        [DllImport("user32.dll", SetLastError = true)]
        private static extern uint SendInput(uint numberOfInputs, INPUT[] inputs, int sizeOfInputStructure);
    
        public static void SetHook()
        {
    
            SetHook(_proc);
        }
    
        public static void UnHook()
        {
            UnhookWindowsHookEx(_hookID);
        }
    
        private static IntPtr SetHook(LowLevelKeyboardProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            { 
                return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0); 
            }
        }
        private static IntPtr _hookID = IntPtr.Zero;       
    
        public static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            int vkCode = Marshal.ReadInt32(lParam); 
    
            if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) 
            {         
                // TODO: identify only Alphabets then fire     
               VKcode(vkCode);                  
            }
            //wParam |=   0x4000;
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }
    
        private static void VKcode(int code)
        { 
            switch (code) // TODO: Complete all other Alphabet-Tranylations
            {  
                case 0x4B:
                     Simulate.UnicodeInput(0xFEDB);
                    break;  
                case 0x54:
                      Simulate.UnicodeInput(0xFEAD);
                    break;
                case 0x55:
                     Simulate.UnicodeInput(0xFBE7);
                    break;
                case 0x56:    
                     Simulate.UnicodeInput(0xFEE9); 
    
                    break;
                case 0x59:
                    Simulate.UnicodeInput(0xFEE1);
                    break;
                case 0x5a: 
                    break; 
            }  
        }        
    
    
        /// <summary>
        /// simulate key press
        /// </summary>
        /// <param name="keyCode"></param>
        public static void SendKeyPress(KeyCode keyCode)
        {
            INPUT input = new INPUT {
                Type = 1
            };
            input.Data.Keyboard = new KEYBDINPUT() {
                Vk = (ushort)keyCode,
                Scan = 0,
                Flags = 0,
                Time = 0,
                ExtraInfo = IntPtr.Zero,
            };
    
            INPUT input2 = new INPUT {
                Type = 1
            };
            input2.Data.Keyboard = new KEYBDINPUT() {
                Vk = (ushort)keyCode,
                Scan = 0,
                Flags = 2,
                Time = 0,
                ExtraInfo = IntPtr.Zero
            };
            INPUT[] inputs = new INPUT[] { input, input2 };
            if (SendInput(2, inputs, Marshal.SizeOf(typeof(INPUT))) == 0)
                throw new Exception();            
        } 
            /// <summary>
        /// simulate key press
        /// </summary>
        /// <param name="keyCode"></param>
        public static void SendUnicodePress(KeyCode keyCode)
        {
            INPUT input = new INPUT {
                Type = 1
            };
            input.Data.Keyboard = new KEYBDINPUT() {
                Vk = (ushort)keyCode,
                Scan = 0,
                Flags = 0,
                Time = 0,
                ExtraInfo = IntPtr.Zero,
            };
    
            INPUT input2 = new INPUT {
                Type = 1
            };
            input2.Data.Keyboard = new KEYBDINPUT() {
                Vk = (ushort)keyCode,
                Scan = 0,
                Flags = 2,
                Time = 0,
                ExtraInfo = IntPtr.Zero
            };
            INPUT[] inputs = new INPUT[] { input, input2 };
            if (SendInput(2, inputs, Marshal.SizeOf(typeof(INPUT))) == 0)
                throw new Exception();            
        } 
        [StructLayout(LayoutKind.Sequential)]
        internal struct INPUT
        {
            public uint Type;
            public MOUSEKEYBDHARDWAREINPUT Data;
        } 
        [StructLayout(LayoutKind.Explicit)]
        internal struct MOUSEKEYBDHARDWAREINPUT
        {
            [FieldOffset(0)]
            public HARDWAREINPUT Hardware;
            [FieldOffset(0)]
            public KEYBDINPUT Keyboard;
            [FieldOffset(0)]
            public MOUSEINPUT Mouse;
        }
        [StructLayout(LayoutKind.Sequential)]
        internal struct HARDWAREINPUT
        {
            public uint Msg;
            public ushort ParamL;
            public ushort ParamH;
        } 
        [StructLayout(LayoutKind.Sequential)]
        internal struct KEYBDINPUT
        {
            public ushort Vk;
            public ushort Scan;
            public uint Flags;
            public uint Time;
            public IntPtr ExtraInfo;
        } 
        [StructLayout(LayoutKind.Sequential)]
        internal struct MOUSEINPUT
        {
            public int X;
            public int Y;
            public uint MouseData;
            public uint Flags;
            public uint Time;
            public IntPtr ExtraInfo;
        }
    }
    

0 个答案:

没有答案