Example #1
0
            /// <summary>
            /// Sends key.
            /// Not used for keys whose scancode can depend on keyboard layout. To get scancode, uses keyboard layout of current thread.
            /// </summary>
            /// <param name="k"></param>
            /// <param name="downUp">1 down, 2 up, 0 down-up.</param>
            internal static void SendKey(KKey k, int downUp = 0)
            {
                uint f = 0;

                if (KeyTypes_.IsExtended(k))
                {
                    f |= Api.KEYEVENTF_EXTENDEDKEY;
                }
                ushort scan = VkToSc(k);

                if (0 == (downUp & 2))
                {
                    SendKeyEventRaw(k, scan, f);
                }
                if (0 == (downUp & 1))
                {
                    SendKeyEventRaw(k, scan, f | Api.KEYEVENTF_KEYUP);
                }
            }
Example #2
0
        /// <summary>
        /// Adds single key, specified as <see cref="KKey"/>, to the internal collection. It will be sent by <see cref="Send"/>.
        /// Returns self.
        /// </summary>
        /// <param name="key">Virtual-key code, as <see cref="KKey"/> or int like <c>(KKey)200</c>. Valid values are 1-255.</param>
        /// <param name="down">true - key down; false - key up; null (default) - key down-up.</param>
        /// <exception cref="ArgumentException">Invalid <i>key</i> (0).</exception>
        public AKeys AddKey(KKey key, bool?down = null)
        {
            _ThrowIfSending();
            if (key == 0)
            {
                throw new ArgumentException("Invalid value.", nameof(key));
            }

            bool isPair; _KFlags f = 0;

            if (!(isPair = (down == null)) && !down.GetValueOrDefault())
            {
                f |= _KFlags.Up;
            }
            if (KeyTypes_.IsExtended(key))
            {
                f |= _KFlags.Extended;
            }

            return(_AddKey(new _KEvent(isPair, key, f)));
        }
Example #3
0
        //Caller should set k.scan; this func doesn't.
        unsafe static void _SendKey2(_KEvent k, _KEvent kNext, bool isLast, OptKey opt)
        {
            var ki = new Api.INPUTK(k.vk, k.scan, (uint)k.SIFlags);

            int count = 1, sleep = opt.KeySpeed;

            if (isLast)
            {
                if (!k.IsPair)
                {
                    sleep = Internal_.LimitSleepTime(sleep) - opt.SleepFinally;
                }
            }
            else
            {
                if (kNext.IsRepeat)
                {
                    count = kNext.repeat;
                }
                else if (!k.IsPair)
                {
                    //If this is pair, sleep between down and up, and don't sleep after up.
                    //Else if repeat, sleep always.
                    //Else in most cases don't need to sleep. In some cases need, but can limit the time.
                    //	For example, in Ctrl+C normally would not need to sleep after Ctrl down and Ctrl up.
                    //	However some apps/controls then may not work. Maybe they process mod and nonmod keys somehow async.
                    //	For example, Ctrl+C in IE address bar often does not work if there is no sleep after Ctrl down. Always works if 1 ms.

                    sleep = Internal_.LimitSleepTime(sleep);
                    if (kNext.IsKey)
                    {
                        bool thisMod = KeyTypes_.IsMod(k.vk), nextMod = KeyTypes_.IsMod(kNext.vk);
                        if (!k.IsUp)
                        {
                            if (kNext.IsUp)
                            {
                                sleep = opt.KeySpeed;
                            }
                            else if (thisMod == nextMod)
                            {
                                sleep = 0;
                            }
                        }
                        else
                        {
                            if (!thisMod || nextMod)
                            {
                                sleep = 0;
                            }
                        }
                    }
                    else if (kNext.IsSleep)
                    {
                        sleep = sleep - kNext.sleep;
                    }
                }
            }
            if (sleep < 0)
            {
                sleep = 0;
            }

            //var s = (k.vk).ToString();
            //if(k.IsPair) AOutput.Write($"{s}<{sleep}>");
            //else { var ud = k.IsUp ? '-' : '+'; if(sleep > 0) AOutput.Write($"{s}{ud} {sleep}"); else AOutput.Write($"{s}{ud}"); }

            for (int r = 0; r < count; r++)
            {
                //APerf.First();
                Api.SendInput(&ki);
                //APerf.Next();
                if (sleep > 0)
                {
                    Internal_.Sleep(sleep);
                }
                if (k.IsPair)
                {
                    ki.dwFlags |= Api.KEYEVENTF_KEYUP;
                    Api.SendInput(&ki);
                    ki.dwFlags &= ~Api.KEYEVENTF_KEYUP;
                }
                //APerf.NW();
                //speed: min 400 mcs for each event. Often > 1000. Does not depend on whether all events sent by single SendInput call.
            }
        }