Simulating SHIFT + END (or HOME) Does Not Appear To Work

Nov 24, 2010 at 9:36 PM

Hi,

First of all let me say thank you for writing this wrapper, we're using it as part of an automation project.

We've run into issues when trying to Simulate pressing SHIFT + END (in order to select all text) for example in any edit field in order to select all text we simulate hitting HOME then Holding SHIFT and pressing END:

InputSimulator.SimulateKeyPress(VirtualKeyCode.HOME);
InputSimulator.SimulateKeyDown(VirtualKeyCode.SHIFT);
InputSimulator.SimulateKeyPress(VirtualKeyCode.END);
InputSimulator.SimulateKeyUp(VirtualKeyCode.SHIFT);

The HOME and END Keys seem to be simulated, but the Holding of the SHIFT does not work. We've also tried using the 'SimulateModifiedKeyStroke' and does not work either (expected as its just a convenience method for the above logic):

InputSimulator.SimulateKeyPress(VirtualKeyCode.HOME);
InputSimulator.SimulateModifiedKeyStroke(VirtualKeyCode.SHIFT, VirtualKeyCode.END);

Any Ideas?

Thanks in advance!

 

Coordinator
Nov 24, 2010 at 10:17 PM
Hi,

I did have a sample of this, but I used simulated a CTRL+A... Would that work for you?

I'm not sure why the shift isn't latching for you since I used the same concept for capital letters in another sample project once... Once idea might be to try the LSHIFT or RSHIFT. Sorry I can't repro it at the moment, I'm flat-out on another project.

HTH,
Mike

On Thu, Nov 25, 2010 at 8:36 AM, aolszowka <notifications@codeplex.com> wrote:

From: aolszowka

Hi,

First of all let me say thank you for writing this wrapper, we're using it as part of an automation project.

We've run into issues when trying to Simulate pressing SHIFT + END (in order to select all text) for example in any edit field in order to select all text we simulate hitting HOME then Holding SHIFT and pressing END:

InputSimulator.SimulateKeyPress(VirtualKeyCode.HOME);
InputSimulator.SimulateKeyDown(VirtualKeyCode.SHIFT);
InputSimulator.SimulateKeyPress(VirtualKeyCode.END);
InputSimulator.SimulateKeyUp(VirtualKeyCode.SHIFT);

The HOME and END Keys seem to be simulated, but the Holding of the SHIFT does not work. We've also tried using the 'SimulateModifiedKeyStroke' and does not work either (expected as its just a convenience method for the above logic):

InputSimulator.SimulateKeyPress(VirtualKeyCode.HOME);
InputSimulator.SimulateModifiedKeyStroke(VirtualKeyCode.SHIFT, VirtualKeyCode.END);

Any Ideas?

Thanks in advance!

Read the full discussion online.

To add a post to this discussion, reply to this email (inputsimulator@discussions.codeplex.com@discussions.codeplex.com)

To start a new discussion for this project, email inputsimulator@discussions.codeplex.com@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


Dec 2, 2010 at 4:27 PM
michaelnoonan wrote:
Hi,
I did have a sample of this, but I used simulated a CTRL+A... Would that work for you?
I'm not sure why the shift isn't latching for you since I used the same concept for capital letters in another sample project once... Once idea might be to try the LSHIFT or RSHIFT. Sorry I can't repro it at the moment, I'm flat-out on another project.
HTH,
Mike

 

Hi Mike,

CTRL+A works great for us! I don't know why I didn't think of that before (a 'duh' moment for us).

I actually had tried using the LSHIFT and RSHIFT as well before posting with the same results. I apologize for not mentioning that in my first post. We too are a little perplexed as to why the SHIFT doesn't latch on for certain keys. It works for Numerics and Alpha's but attempting to use these 'special' keys seem to fail. Looking at the code doesn't seem to show anything out of the ordinary that might be causing this, but my understanding of WinAPI is still pretty weak.

Thank you once again for your project here, it has saved us countless hours of rolling our own. The work around works well enough for us!

Thanks

 

Apr 22, 2011 at 5:53 PM

I've had some time to dig into this issue more (we ran into situations where CTRL + A did not work), and I believe I have narrowed down the issue. Apparently we need to send the KEYEVENTF_EXTENDEDKEY in the dwFlags in order to make this work. It seems like there needs to be additional logic in InputSimulator to determine if the key is an Extended Key or not, however I am not sure when you would want to pass the Extended Key flag. At very least it seems like you'd want INSERT, DELETE, HOME, END, PAGE UP, PAGE DOWN, but I'm sure there are more. If anyone could find some MSDN documentation that'd be awesome. I'd be happy to make the necessary changes as a patch if we knew the exact cases where we needed KEYEVENTIF_EXTENDEDKEY.

Here is a small test program that shows this working with Interop; to test open up notepad type in a garbage line, then run this program and set focus to notepad so that it receives the keys. The expected result is for the text to be selected at the end of execution:

 

using System;
using System.Runtime.InteropServices;

namespace SendInputFix
{
    class Program
    {
        static void Main(string[] args)
        {
            //Make sure the Window is Focused Before this timeout is up
            System.Threading.Thread.Sleep(2000);

            // Home Key Press Down
            INPUT homedown = new INPUT();
            homedown.Type = INPUT_KEYBOARD;
            homedown.Data.Keyboard = new KEYBDINPUT();
            homedown.Data.Keyboard.wVk = VK_HOME;
            homedown.Data.Keyboard.wScan = 0;
            homedown.Data.Keyboard.dwFlags = KEYEVENTF_EXTENDEDKEY;
            homedown.Data.Keyboard.time = 0;
            homedown.Data.Keyboard.dwExtraInfo = IntPtr.Zero;

            // Home Key Press Up
            INPUT homeup = new INPUT();
            homeup.Type = INPUT_KEYBOARD;
            homeup.Data.Keyboard = new KEYBDINPUT();
            homeup.Data.Keyboard.wVk = VK_HOME;
            homeup.Data.Keyboard.wScan = 0;
            homeup.Data.Keyboard.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP;
            homeup.Data.Keyboard.time = 0;
            homeup.Data.Keyboard.dwExtraInfo = IntPtr.Zero;

            // Shift Key Press Down
            INPUT shiftdown = new INPUT();
            shiftdown.Type = INPUT_KEYBOARD;
            shiftdown.Data.Keyboard = new KEYBDINPUT();
            shiftdown.Data.Keyboard.wVk = VK_SHIFT;
            shiftdown.Data.Keyboard.wScan = 0;
            shiftdown.Data.Keyboard.time = 0;
            shiftdown.Data.Keyboard.dwExtraInfo = IntPtr.Zero;

            // End Key Press Down
            INPUT enddown = new INPUT();
            enddown.Type = INPUT_KEYBOARD;
            enddown.Data.Keyboard = new KEYBDINPUT();
            enddown.Data.Keyboard.wVk = VK_END;
            enddown.Data.Keyboard.wScan = 0;
            enddown.Data.Keyboard.dwFlags = KEYEVENTF_EXTENDEDKEY;
            enddown.Data.Keyboard.time = 0;
            enddown.Data.Keyboard.dwExtraInfo = IntPtr.Zero;

            // End Key Press Up
            INPUT endup = new INPUT();
            endup.Type = INPUT_KEYBOARD;
            endup.Data.Keyboard = new KEYBDINPUT();
            endup.Data.Keyboard.wVk = VK_END;
            endup.Data.Keyboard.wScan = 0;
            endup.Data.Keyboard.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP;
            endup.Data.Keyboard.time = 0;
            endup.Data.Keyboard.dwExtraInfo = IntPtr.Zero;

            // Shift Key Press Up
            INPUT shiftup = new INPUT();
            shiftup.Type = INPUT_KEYBOARD;
            shiftup.Data.Keyboard = new KEYBDINPUT();
            shiftup.Data.Keyboard.wVk = VK_SHIFT;
            shiftup.Data.Keyboard.wScan = 0;
            shiftup.Data.Keyboard.dwFlags = KEYEVENTF_KEYUP;
            shiftup.Data.Keyboard.time = 0;
            shiftup.Data.Keyboard.dwExtraInfo = IntPtr.Zero;

            // Declare the Input
            INPUT[] inputList = new INPUT[] { homedown, homeup, shiftdown, enddown, endup, shiftup };

            // Ensure that all inputs were entered
            uint sentkeys = SendInput(6, inputList, Marshal.SizeOf(typeof(INPUT)));
            if (sentkeys != 6)
            {
                throw new ArgumentException("FAIL");
            }
        }

        #region Win32API

        const int INPUT_MOUSE = 0;
        const int INPUT_KEYBOARD = 1;
        const int INPUT_HARDWARE = 3;

        const byte VK_HOME = 0X24;
        const byte VK_SHIFT = 0XA1;
        const byte VK_END = 0x23;

        const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
        const uint KEYEVENTF_KEYUP = 0x0002;

        [DllImport("user32.dll", SetLastError = true)]
        private static extern uint SendInput(uint numberOfInputs, INPUT[] inputs, int sizeOfInputStructure);

        [StructLayout(LayoutKind.Sequential)]
        internal struct INPUT
        {
            public uint Type;
            public MOUSEKEYBDHARDWAREINPUT Data;
        }

        [StructLayout(LayoutKind.Explicit)]
        internal struct MOUSEKEYBDHARDWAREINPUT
        {
            // Fields
            [FieldOffset(0)]
            public HARDWAREINPUT Hardware;
            [FieldOffset(0)]
            public KEYBDINPUT Keyboard;
            [FieldOffset(0)]
            public MOUSEINPUT Mouse;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct KEYBDINPUT
        {
            public ushort wVk;
            public ushort wScan;
            public uint dwFlags;
            public uint time;
            public IntPtr dwExtraInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct MOUSEINPUT
        {
            public int X;
            public int Y;
            public uint MouseData;
            public uint Flags;
            public uint Time;
            public IntPtr ExtraInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct HARDWAREINPUT
        {
            public uint Msg;
            public ushort ParamL;
            public ushort ParamH;
        }

        #endregion
    }
}

 

 

Jun 20, 2012 at 4:36 PM

Wow has it really been over a year? I finally got back around to this issue and have submitted a fix:

I have located some documentation on MSDN that outlines which keys are considered 'Extended Keys' here http://msdn.microsoft.com

/en-us/library/ms646267(v=vs.85).aspx Section "Extended-Key Flag". From the linked documentation:
"The extended-key flag indicates whether the keystroke message originated from one of the additional keys on the enhanced keyboard. The extended keys consist of the ALT and CTRL keys on the right-hand side of the keyboard; the INS, DEL, HOME, END, PAGE UP, PAGE DOWN, and arrow keys in the clusters to the left of the numeric keypad; the NUM LOCK key; the BREAK (CTRL+PAUSE) key; the PRINT SCRN key; and the divide (/) and ENTER keys in the numeric keypad. The extended-key flag is set if the key is an extended key."

I have modified the version 0.1.0.0 of the Input Simulation Library (which is the version we use, and the version that is still available on the download page).

I created a work item here http://inputsimulator.codeplex.com/workitem/13002 and submitted a .patch. If you have any questions please feel free to contact me via CodePlex.

Sep 23, 2012 at 1:33 AM

Thank you, aolszowka, for the the patch.
I'm using your IsExtendedKey() function with the the newer repository source for InputSimulator.

Coordinator
Feb 22, 2013 at 2:17 AM
Hey All,

Thanks for helping out make the project better. I've (finally) got a bit of white space to get the project rolling a little. Plans are to push to github to make forking/pull-requests easier, put together a testing strategy, and release v1 + nuget.

Any other ideas?

Cheers,
Mike
Feb 22, 2013 at 1:48 PM
Hey Mike,

If you plan on moving the Project to GitHub can you please make sure to normalize the line endings throughout the Project and not rely on Git to try and be helpful about autofixing them? There was another Open Source Project which I contribute which moved to GitHub that did not normalize line endings and has made it extremely frustrating to attempt to submit patches as the Git Client attempts to be continually helpful despite every attempt to disable the functionality.

Thanks,
Ace