StrokesPlus.net
Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

Options
Go to last post Go to first unread
soooulp  
#1 Posted : Wednesday, February 24, 2021 11:20:24 AM(UTC)
soooulp

Rank: Advanced Member

Reputation:

Groups: Approved
Joined: 4/23/2020(UTC)
Posts: 67
China

Thanks: 14 times
Was thanked: 3 time(s) in 2 post(s)
I want to set shift key single to a hotkey to change the keyboard, how to do this?
Rob  
#2 Posted : Thursday, February 25, 2021 2:59:03 PM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 912
United States
Location: Tampa, FL

Thanks: 21 times
Was thanked: 255 time(s) in 222 post(s)
You would have to utilize the keyboard hook to watch for and manually handle just the Shift key. The details about using the mouse and keyboard hooks are outlined in the post below:

https://forum.strokesplus.net/posts/t7209-Mouse---Keyboard-Event-Subscriptions
thanks 1 user thanked Rob for this useful post.
soooulp on 2/25/2021(UTC)
soooulp  
#3 Posted : Thursday, February 25, 2021 3:27:27 PM(UTC)
soooulp

Rank: Advanced Member

Reputation:

Groups: Approved
Joined: 4/23/2020(UTC)
Posts: 67
China

Thanks: 14 times
Was thanked: 3 time(s) in 2 post(s)
Originally Posted by: Rob Go to Quoted Post
You would have to utilize the keyboard hook to watch for and manually handle just the Shift key. The details about using the mouse and keyboard hooks are outlined in the post below:

https://forum.strokesplus.net/posts/t7209-Mouse---Keyboard-Event-Subscriptions



Aha, I put this in the Global Actions > Load/Unload > Load it works, 'Shft' as a hotkey to execute Win+Space to change the input.

But how to forbid the single hotkey action when Shift as a modify key with other keys to execute another shortcut, such as Shft+'+/='?

Code:

if(__spEngineWrapper.Engine.Name == sp.EngineList().Last().Engine.Name)
{
    var keyboardEventObj = sp.GetStoredObject("keyboardEvent");
    if(!keyboardEventObj.GetType().FullName.includes('EventConnection'))
    {
        //Bind to the synchronous event
        var keyboardEvent = KeyboardHook.OnKeyboardHookEvent.connect(
            function (sender, keyboardHookEvent) {
                //Wrap all code in try/catch, exceptions will crash S+, such as calling clip.SetText with a null value
                try
                {
                    if(keyboardHookEvent.Key == vk.LSHIFT)
                    {
                        if(keyboardHookEvent.KeyState == KeyState.Up)
                        {
                            sp.SendKeys("+^");
                        }
                        //Consume the event, so Windows/apps do not see the keypress
                        keyboardHookEvent.Consume = true;
                    }
                }
                catch {}
            });
        sp.StoreObject("keyboardEvent", keyboardEvent);
    }
}

Rob  
#4 Posted : Thursday, February 25, 2021 7:02:05 PM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 912
United States
Location: Tampa, FL

Thanks: 21 times
Was thanked: 255 time(s) in 222 post(s)
This worked for me, but I didn't do a lot of testing.
Code:
if(__spEngineWrapper.Engine.Name == sp.EngineList().Last().Engine.Name)
{
    var keyboardEventObj = sp.GetStoredObject("keyboardEvent");
    if(!keyboardEventObj.GetType().FullName.includes('EventConnection'))
    {
        //Bind to the synchronous event
        var keyboardEvent = KeyboardHook.OnKeyboardHookEvent.connect(
            function (sender, keyboardHookEvent) {
                //Wrap all code in try/catch, exceptions will crash S+, such as calling clip.SetText with a null value
                try
                {
                    if(keyboardHookEvent.Key == vk.LSHIFT)
                    {
                        if(keyboardHookEvent.KeyState == KeyState.Up)
                        {
                            if(!sp.GetStoredBool("SuppressHotkey")) {
                                // Shift only, no other keypresses since shift down
                                sp.SendKeys("+^");
                            }
                            //removed consume, no reason to leave shift in the down state
                        } else {
                            // Shift down, reset variable
                            sp.StoreBool("SuppressHotkey", false)
                        }
                    } else {
                        // If any other key pressed down while Shift is pressed, set var to ignore hotkey 
                        if(keyboardHookEvent.KeyState == KeyState.Down && sp.GetKeyState(vk.LSHIFT) & 0x8000) {
                            sp.StoreBool("SuppressHotkey", true);
                        }
                    }
                }
                catch {}
            });
        sp.StoreObject("keyboardEvent", keyboardEvent);
    }
}
thanks 1 user thanked Rob for this useful post.
soooulp on 2/26/2021(UTC)
soooulp  
#5 Posted : Friday, February 26, 2021 7:37:46 AM(UTC)
soooulp

Rank: Advanced Member

Reputation:

Groups: Approved
Joined: 4/23/2020(UTC)
Posts: 67
China

Thanks: 14 times
Was thanked: 3 time(s) in 2 post(s)
Originally Posted by: Rob Go to Quoted Post
This worked for me, but I didn't do a lot of testing.



Thank you, Rob.

Eventually, I solve it that use Shift to change the input and send a message on the screen by distinguishing between US and Chinese(simple) keyboards.

The Shift key as a hotkey or the other key pressed down while Shift is pressed is all normal.



And there is another new problem.

I use Ctrl+tab to switch the Chrome tab, it sometimes will be a stop, and S+net is broken down, the gesture will be recover if I press Ctrl once again.

I try the following code to except for the Ctrl and the other key shortcuts, it will be OK if I press Ctrl+tab on the keyboard.

But if I use a gesture to execute sp.SendKeys("^{TAB}"); it also will be a stop sometimes.

Code:

if(__spEngineWrapper.Engine.Name == sp.EngineList().Last().Engine.Name)
{
    var keyboardEventObj = sp.GetStoredObject("keyboardEvent");
    if(!keyboardEventObj.GetType().FullName.includes('EventConnection'))
    {
        //Bind to the synchronous event
        var keyboardEvent = KeyboardHook.OnKeyboardHookEvent.connect(
            function (sender, keyboardHookEvent) {
                //Wrap all code in try/catch, exceptions will crash S+, such as calling clip.SetText with a null value
                try
                {
                    if(keyboardHookEvent.Key == vk.LSHIFT || keyboardHookEvent.Key == vk.RSHIFT || keyboardHookEvent.Key == vk.SHIFT)
                    {
                        if(keyboardHookEvent.KeyState == KeyState.Up)
                        {
                            if(!sp.GetStoredBool("SuppressHotkey")) {
                                // Shift only, no other keypresses since shift down
                                sp.SendKeys("+^");
                            }
                            //removed consume, no reason to leave shift in the down state
                        } else {
                            // Shift down, reset variable
                            sp.StoreBool("SuppressHotkey", false)
                        }
                    } else {
                        // If any other key pressed down while Shift is pressed, set var to ignore hotkey 
                        if(keyboardHookEvent.KeyState == KeyState.Down && sp.GetKeyState(vk.LSHIFT) & 0x8000) {
                            sp.StoreBool("SuppressHotkey", true);
                        } 
                    } 
                }
                catch {}
            });
        sp.StoreObject("keyboardEvent", keyboardEvent);
    } else if(sp.GetKeyState(vk.CONTROL) & 0x8000 || sp.SendKeys("^{Tab}")) {
        keyboardEventObj.disconnect();
        sp.DeleteStoredObject("keyboardEvent");
    }
}








soooulp  
#6 Posted : Friday, February 26, 2021 11:48:07 AM(UTC)
soooulp

Rank: Advanced Member

Reputation:

Groups: Approved
Joined: 4/23/2020(UTC)
Posts: 67
China

Thanks: 14 times
Was thanked: 3 time(s) in 2 post(s)
And maybe not the Ctrl key problem, if the gesture stops, it will also recover when Minimize the Chrome then active again.
Rob  
#7 Posted : Friday, February 26, 2021 2:40:15 PM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 912
United States
Location: Tampa, FL

Thanks: 21 times
Was thanked: 255 time(s) in 222 post(s)
You should probably be using the asynchronous event instead of the synchronous one.

The difference is that the synchronous event (OnKeyboardHookEvent, from previous posts) processes each keystroke and waits for the script to return before any apps or Windows will see the key. This event allows you to consume (prevent) the keystroke. If you're pressing keys very quickly, it can start to queue up as all the scripts are still being processed.

The asynchronous event (OnKeyboardHookEventAsync) is more of a notification, but doesn't interrupt the input. You are not able to prevent the keystroke in this event.

For your purposes, you're not trying to stop any keystrokes, simply react to certain events so it should be fine and not interfere with keyboard input. See if this works better.

Code:
if(__spEngineWrapper.Engine.Name == sp.EngineList().Last().Engine.Name)
{
    var keyboardEventObj = sp.GetStoredObject("keyboardEvent");
    if(!keyboardEventObj.GetType().FullName.includes('EventConnection'))
    {
        //Bind to the synchronous event
        var keyboardEvent = KeyboardHook.OnKeyboardHookEventAsync.connect(
            function (sender, keyboardHookEvent) {
                //Wrap all code in try/catch, exceptions will crash S+, such as calling clip.SetText with a null value
                try
                {
                    if(keyboardHookEvent.Key == vk.LSHIFT)
                    {
                        if(keyboardHookEvent.KeyState == KeyState.Up)
                        {
                            if(!sp.GetStoredBool("SuppressHotkey")) {
                                // Shift only, no other keypresses since shift down
                                //YOU SHIFT ONLY CODE HERE
                            }
                            //removed consume, no reason to leave shift in the down state
                        } else {
                            // Shift down, reset variable
                            sp.StoreBool("SuppressHotkey", false)
                        }
                    } else {
                        // If any other key pressed down while Shift is pressed, set var to ignore hotkey 
                        if(keyboardHookEvent.KeyState == KeyState.Down && sp.GetKeyState(vk.LSHIFT) & 0x8000) {
                            sp.StoreBool("SuppressHotkey", true);
                        }
                    }
                }
                catch {}
            });
        sp.StoreObject("keyboardEvent", keyboardEvent);
    }
}
thanks 1 user thanked Rob for this useful post.
soooulp on 2/26/2021(UTC)
soooulp  
#8 Posted : Friday, February 26, 2021 3:08:13 PM(UTC)
soooulp

Rank: Advanced Member

Reputation:

Groups: Approved
Joined: 4/23/2020(UTC)
Posts: 67
China

Thanks: 14 times
Was thanked: 3 time(s) in 2 post(s)
Originally Posted by: Rob Go to Quoted Post
You should probably be using the asynchronous event instead of the synchronous one.

The difference is that the synchronous event (OnKeyboardHookEvent, from previous posts) processes each keystroke and waits for the script to return before any apps or Windows will see the key. This event allows you to consume (prevent) the keystroke. If you're pressing keys very quickly, it can start to queue up as all the scripts are still being processed.

The asynchronous event (OnKeyboardHookEventAsync) is more of a notification, but doesn't interrupt the input. You are not able to prevent the keystroke in this event.

For your purposes, you're not trying to stop any keystrokes, simply react to certain events so it should be fine and not interfere with keyboard input. See if this works better.


Thank you again, Now I get it.
soooulp  
#9 Posted : Tuesday, March 30, 2021 4:15:57 AM(UTC)
soooulp

Rank: Advanced Member

Reputation:

Groups: Approved
Joined: 4/23/2020(UTC)
Posts: 67
China

Thanks: 14 times
Was thanked: 3 time(s) in 2 post(s)
Originally Posted by: Rob Go to Quoted Post
You should probably be using the asynchronous event instead of the synchronous one.

The difference is that the synchronous event (OnKeyboardHookEvent, from previous posts) processes each keystroke and waits for the script to return before any apps or Windows will see the key. This event allows you to consume (prevent) the keystroke. If you're pressing keys very quickly, it can start to queue up as all the scripts are still being processed.

The asynchronous event (OnKeyboardHookEventAsync) is more of a notification, but doesn't interrupt the input. You are not able to prevent the keystroke in this event.

For your purposes, you're not trying to stop any keystrokes, simply react to certain events so it should be fine and not interfere with keyboard input. See if this works better.


Hi, Rob, the script runs well for long days.

How to ignore the hotkey when the Shift key is down with a left click?

I find there is another problem that the Shift hotkey will execute when pressing down Shift with a left click to select all the files.

I use the above Keyboard Hook Events and the following Mouse Hook Events in Global Actions-Load/Unload at the same time, there is no change when left click.

Code:

//This toggles on and off a synchronous mouse button hook event subscription
//If event already bound, disconnect
var mouseButtonEventObj = sp.GetStoredObject("mouseButtonEvent");
if(mouseButtonEventObj.GetType().FullName.includes('EventConnection')) {
    mouseButtonEventObj.disconnect();
    sp.DeleteStoredObject("mouseButtonEvent");
} else {
    //Otherwise, create the event binding
    //bind to synchronous event
    var mouseButtonEvent = MouseHook.OnMouseHookButtonEvent.connect(
        function (sender, mouseHookEvent) {
            //Wrap all code in try/catch, exceptions will crash S+, such as calling clip.SetText with a null value
            try {
                if(mouseHookEvent.Button == MouseButtons.Left && mouseHookEvent.ButtonState == ButtonState.Down && (sp.GetKeyState(vk.LSHIFT) & 0x8000 || sp.GetKeyState(vk.RSHIFT) & 0x8000 || sp.GetKeyState(vk.SHIFT) & 0x8000))
                {
                    //Do something when the left mouse button is released, but don't consume
                    sp.ShowBalloonTip('Title','Message here','Info',5000);
                    sp.StoreBool("SuppressHotkey", true);
                }
            }
            catch{}
        });
    //Note that on S+ reload, events in Stored Object list have disconnect called on them
    sp.StoreObject("mouseButtonEvent", mouseButtonEvent);
}

Rob  
#10 Posted : Tuesday, March 30, 2021 1:50:20 PM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 912
United States
Location: Tampa, FL

Thanks: 21 times
Was thanked: 255 time(s) in 222 post(s)
You can use this in the keyboard hook to see if the left mouse button is down:
Code:
if((sp.GetKeyState(vk.LBUTTON) & 0x8000))
{
    //left button down
}
soooulp  
#11 Posted : Tuesday, March 30, 2021 2:33:49 PM(UTC)
soooulp

Rank: Advanced Member

Reputation:

Groups: Approved
Joined: 4/23/2020(UTC)
Posts: 67
China

Thanks: 14 times
Was thanked: 3 time(s) in 2 post(s)
Originally Posted by: Rob Go to Quoted Post
You can use this in the keyboard hook to see if the left mouse button is down:
Code:
if((sp.GetKeyState(vk.LBUTTON) & 0x8000))
{
    //left button down
}




It is failed, I add the left mouse button down code and the shift hotkey still executes.
Code:

if(__spEngineWrapper.Engine.Name == sp.EngineList().Last().Engine.Name) {
    var keyboardEventObj = sp.GetStoredObject("keyboardEvent");
    if(!keyboardEventObj.GetType().FullName.includes('EventConnection')) {
        //Bind to the synchronous event
        var keyboardEvent = KeyboardHook.OnKeyboardHookEventAsync.connect(
            function (sender, keyboardHookEvent) {
                //Wrap all code in try/catch, exceptions will crash S+, such as calling clip.SetText with a null value
                try {
                    if(keyboardHookEvent.Key == vk.LSHIFT) {
                        if(keyboardHookEvent.KeyState == KeyState.Up) {
                            if(!sp.GetStoredBool("SuppressHotkey")) {
                                 // Shift only, no other keypresses since shift down
                                sp.SendWinDown();
                                sp.SendVKey(vk.SPACE);
                                sp.SendWinUp()
                            }
                            //removed consume, no reason to leave shift in the down state
                        } else {
                             // Shift down, reset variable
                             sp.StoreBool("SuppressHotkey", false)
                        }
                    } else {
                        // If any other key pressed down while Shift is pressed, set var to ignore hotkey 
                        if(keyboardHookEvent.KeyState == KeyState.Down && sp.GetKeyState(vk.LSHIFT) & 0x8000) {
                            sp.StoreBool("SuppressHotkey", true);
                        } else if (sp.GetKeyState(vk.LBUTTON) & 0x8000 && sp.GetKeyState(vk.LSHIFT) & 0x8000) {  // Is it right that I put it here
                            sp.StoreBool("SuppressHotkey", true);
                        } 
                    } 
                }
                catch {}
            });
        sp.StoreObject("keyboardEvent", keyboardEvent);
    }
}

Rob  
#12 Posted : Tuesday, March 30, 2021 4:01:11 PM(UTC)
Rob

Rank: Administration

Reputation:

Groups: Translators, Members, Administrators
Joined: 1/11/2018(UTC)
Posts: 912
United States
Location: Tampa, FL

Thanks: 21 times
Was thanked: 255 time(s) in 222 post(s)
When you hold a key down, the DOWN event is sent repeatedly, like when you type the letter Y and hold it down, you get:

YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY

So you have to account for repeated key down messages, it was continually clearing the suppress hot key bool.

This seems to work for me:
Code:
if(__spEngineWrapper.Engine.Name == sp.EngineList().Last().Engine.Name) {

    //This toggles on and off a synchronous mouse button hook event subscription
    //If event already bound, disconnect
    var mouseButtonEventObj = sp.GetStoredObject("mouseButtonEvent");
    if(mouseButtonEventObj.GetType().FullName.includes('EventConnection')) {
        mouseButtonEventObj.disconnect();
        sp.DeleteStoredObject("mouseButtonEvent");
    } else {
        //Otherwise, create the event binding
        //bind to synchronous event
        var mouseButtonEvent = MouseHook.OnMouseHookButtonEventAsync.connect(
            function (sender, mouseHookEvent) {
                //Wrap all code in try/catch, exceptions will crash S+, such as calling clip.SetText with a null value
                try {
                    if(mouseHookEvent.Button == MouseButtons.Left && mouseHookEvent.ButtonState == ButtonState.Down && (sp.GetKeyState(vk.LSHIFT) & 0x8000 || sp.GetKeyState(vk.RSHIFT) & 0x8000 || sp.GetKeyState(vk.SHIFT) & 0x8000))
                    {
                        //Do something when the left mouse button is released, but don't consume
                        sp.ShowBalloonTip('Title','Message here','Info',5000);
                        sp.StoreBool("SuppressHotkey", true);
                    }
                }
                catch{}
            });
        //Note that on S+ reload, events in Stored Object list have disconnect called on them
        sp.StoreObject("mouseButtonEvent", mouseButtonEvent);
    }

    var keyboardEventObj = sp.GetStoredObject("keyboardEvent");
    if(!keyboardEventObj.GetType().FullName.includes('EventConnection')) {
        //Bind to the synchronous event
        var keyboardEvent = KeyboardHook.OnKeyboardHookEventAsync.connect(
            function (sender, keyboardHookEvent) {
                //Wrap all code in try/catch, exceptions will crash S+, such as calling clip.SetText with a null value
                try {
                    if(keyboardHookEvent.Key == vk.LSHIFT) {
                        if(keyboardHookEvent.KeyState == KeyState.Up) {
                            sp.StoreBool("ShiftDown", false);
                            if(!sp.GetStoredBool("SuppressHotkey")) {
                                 // Shift only, no other keypresses since shift down
                                sp.SendWinDown();
                                sp.SendVKey(vk.SPACE);
                                sp.SendWinUp();
                            }
                            //removed consume, no reason to leave shift in the down state
                        } else {
                             if(!sp.GetStoredBool("ShiftDown")) {
                                // Shift down, reset variable
                                sp.StoreBool("SuppressHotkey", false);
                             }
                             sp.StoreBool("ShiftDown", true);
                        }
                    } else {
                        // If any other key pressed down while Shift is pressed, set var to ignore hotkey 
                        if(keyboardHookEvent.KeyState == KeyState.Down && sp.GetKeyState(vk.LSHIFT) & 0x8000) {
                            sp.StoreBool("SuppressHotkey", true);
                        } 
                    } 
                }
                catch {}
            });
        sp.StoreObject("keyboardEvent", keyboardEvent);
    }
}
thanks 1 user thanked Rob for this useful post.
soooulp on 3/30/2021(UTC)
soooulp  
#13 Posted : Tuesday, March 30, 2021 4:43:24 PM(UTC)
soooulp

Rank: Advanced Member

Reputation:

Groups: Approved
Joined: 4/23/2020(UTC)
Posts: 67
China

Thanks: 14 times
Was thanked: 3 time(s) in 2 post(s)
Originally Posted by: Rob Go to Quoted Post
When you hold a key down, the DOWN event is sent repeatedly, like when you type the letter Y and hold it down, you get:

YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY

So you have to account for repeated key down messages, it was continually clearing the suppress hot key bool.

This seems to work for me:


It works well, this problem solved.

Rob, thank you again.
Users browsing this topic
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.