SendKeys alternative that works on Citrix

后端 未结 4 1386
萌比男神i
萌比男神i 2020-12-05 08:29

I recently developed a virtual keyboard application for a customer. The program is working fine with almost all programs, but certain commands like {ENTER} or <

4条回答
  •  爱一瞬间的悲伤
    2020-12-05 08:54

    For the windows input simulator solution, you can modify the source code directly so that the built in functions will send scan codes with the virtual keys.

    InputBuilder.cs:

    using System.Runtime.InteropServices;
    .
    .
    .
    [DllImport("user32.dll")]
    static extern uint MapVirtualKeyEx(uint uCode, uint uMapType, IntPtr dwhkl);
    
    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    static extern short VkKeyScanEx(char ch, IntPtr dwhkl);
    .
    .
    .
    public InputBuilder AddKeyDown(VirtualKeyCode keyCode)
    {
        var down =
            new INPUT
            {
                Type = (UInt32)InputType.Keyboard,
                Data =
                        {
                            Keyboard =
                                new KEYBDINPUT
                                    {
                                        KeyCode = (UInt16) keyCode,
                                        Scan = (UInt16)MapVirtualKeyEx((UInt16)keyCode, 0, IntPtr.Zero),
                                        Flags = IsExtendedKey(keyCode) ? (UInt32) KeyboardFlag.ExtendedKey : (UInt32) KeyboardFlag.ScanCode,
                                        Time = 0,
                                        ExtraInfo = IntPtr.Zero
                                    }
                        }
                };
    
        _inputList.Add(down);
        return this;
    }
    .
    .
    .
    public InputBuilder AddKeyUp(VirtualKeyCode keyCode)
    {
        var up =
            new INPUT
                {
                    Type = (UInt32) InputType.Keyboard,
                    Data =
                        {
                            Keyboard =
                                new KEYBDINPUT
                                    {
                                        KeyCode = (UInt16) keyCode,
                                        Scan = (UInt16)MapVirtualKeyEx((UInt16)keyCode, 0,IntPtr.Zero),
                                        Flags = (UInt32) (IsExtendedKey(keyCode)
                                                              ? KeyboardFlag.KeyUp | KeyboardFlag.ExtendedKey
                                                              : KeyboardFlag.KeyUp | KeyboardFlag.ScanCode),
                                        Time = 0,
                                        ExtraInfo = IntPtr.Zero
                                    }
                        }
                };
    
        _inputList.Add(up);
        return this;
    }
    .
    .
    .
    public InputBuilder AddCharacter(char character)
    {
        bool shiftChr = ((UInt16)VkKeyScanEx(character, IntPtr.Zero) >> 8).Equals(1);
        if (shiftChr)
        {
            AddKeyDown(VirtualKeyCode.VK_SHIFT);
        }
    
        UInt16 scanCode = shiftChr ? (UInt16)MapVirtualKeyEx((UInt16)(VkKeyScanEx(character, IntPtr.Zero) & 0xff),0,IntPtr.Zero) : (UInt16)MapVirtualKeyEx((UInt16)VkKeyScanEx(character, IntPtr.Zero), 0, IntPtr.Zero);
    
        var down = new INPUT
                       {
                           Type = (UInt32)InputType.Keyboard,
                           Data =
                               {
                                   Keyboard =
                                       new KEYBDINPUT
                                           {
                                               KeyCode = 0,
                                               Scan = scanCode,
                                               Flags = (UInt32)KeyboardFlag.ScanCode,
                                               Time = 0,
                                               ExtraInfo = IntPtr.Zero
                                           }
                               }
                       };
    
        var up = new INPUT
                     {
                         Type = (UInt32)InputType.Keyboard,
                         Data =
                             {
                                 Keyboard =
                                     new KEYBDINPUT
                                         {
                                             KeyCode = 0,
                                             Scan = scanCode,
                                             Flags =
                                                 (UInt32)(KeyboardFlag.KeyUp | KeyboardFlag.ScanCode),
                                             Time = 0,
                                             ExtraInfo = IntPtr.Zero
                                         }
                             }
                     };
    
        _inputList.Add(down);
        _inputList.Add(up);
    
        if (shiftChr)
        {
            AddKeyUp(VirtualKeyCode.VK_SHIFT);
        }
    
        return this;
    }
    

    With these changes TextEntry, KeyPress, and ModifiedKeyStroke will send the scan codes associated with the virtual keys passed in.

提交回复
热议问题