question

ansalc-1556 avatar image
0 Votes"
ansalc-1556 asked ·

Caps Lock off

In Visual Basic, how do I check if the Caps Lock key is locked (on) ?

The following do not work

  1. If Window.Current.CoreWindow.GetKeyState(VirtualKey.CapitalLock).Locked Then... evaluated as True always

  2. If Window.Current.CoreWindow.GetKeyState(VirtualKey.CapitalLock).HasFlag(VirtualKey.Down) Then... throws an error

windows-uwp
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

RoyLi-MSFT avatar image
0 Votes"
RoyLi-MSFT answered ·

Hello,

Welcome to Micorsoft Q&A!

You need to check both VirtualKey.state and CoreVirtualKeyStates to confirm if the Caps Lock button is on.

And for another question - switch the caps lock key's states, you need to add InjectedInputKeyOptions for the InputInjector object

You could use the following code:

         // detect the caps lock key state
         Dim keystate = Window.Current.CoreWindow.GetKeyState(VirtualKey.CapitalLock)
         Dim isNumLocked = (keystate And CoreVirtualKeyStates.Locked) <> 0


         // inject a caps lock key press no matter what's the state of it.
     Dim inputInjector As InputInjector = InputInjector.TryCreate()

     Dim info = New InjectedInputKeyboardInfo()
     info.VirtualKey = VirtualKey.CapitalLock

     'press the key
     info.KeyOptions = InjectedInputKeyOptions.ExtendedKey
     inputInjector.InjectKeyboardInput({info})
     Await Task.Delay(100)

     'release the caps lock key. If you do not release the key, the cap lock will remain pressed state
     info.KeyOptions = InjectedInputKeyOptions.KeyUp
     inputInjector.InjectKeyboardInput({info})
     Await Task.Delay(100)


Thank you!






· 17 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi RoyLi,


It does not seem to work


I've tried


Dim keystate = Window.Current.CoreWindow.GetKeyState(VirtualKey.CapitalLock)

  If keystate And Windows.UI.Core.CoreVirtualKeyStates.Locked <> 0 Then
        
      info.VirtualKey = VirtualKey.CapitalLock
      inputInjector.InjectKeyboardInput({info})
  End If


It does not remove the Caps Lock when it is on to start with


The following almost works, but if the Caps Lock key was on it has to be depressed twice after it was switched off programmatically twice, not once as expected, to recover its normal behaviour. Otherwise the program does the opposite as expected. So it is not good


If Window.Current.CoreWindow.GetKeyState(VirtualKey.CapitalLock).Locked And Windows.UI.Core.CoreVirtualKeyStates.Locked Then info.VirtualKey = VirtualKey.CapitalLock inputInjector.InjectKeyboardInput({info}) End If


0 Votes 0 ·

What behavior do you really want to get? The code I give could only detect Caps Lock states.

0 Votes 0 ·

I want to detect if the Caps Lock is on and if so, switch it to off


The code in my previous post, based on your input, has the issue I mentioned that renders it unusable


Can you post the full code to detect if the Caps Lock is on and if so switch it to off in UWP VB?


0 Votes 0 ·

Why do you want to control the Caps Lock key in code?

0 Votes 0 ·

Because I inject key strokes programmatically and need to control the Caps Lock key status


0 Votes 0 ·

I've updated my answer, please check that.

0 Votes 0 ·

Roy,


I have seen your updated answer. I still cannot make it work.


Can you please provide the code clearly for switching Caps Lock to off if it is On before the program runs.


The following works from the moment the app runs. But if the Caps Lock is on to start with, it does not work


If Window.Current.CoreWindow.GetKeyState(VirtualKey.CapitalLock).HasFlag(Windows.UI.Core.CoreVirtualKeyStates.Locked) Then

      info.VirtualKey = VirtualKey.CapitalLock
      inputInjector.InjectKeyboardInput({info})
      info.KeyOptions = InjectedInputKeyOptions.KeyUp
      inputInjector.InjectKeyboardInput({info})

  End If


It is as if the app cannot get the Caps Lock status from before


0 Votes 0 ·

This is the code I'm using. This equals press the cap lock key once. So don't need to detect the cap lock state.


         Private Async Sub Button_Click(sender As Object, e As RoutedEventArgs)
    
         Dim inputInjector As InputInjector = InputInjector.TryCreate()
    
         Dim info = New InjectedInputKeyboardInfo()
         info.VirtualKey = VirtualKey.CapitalLock
    
         'press the key
         info.KeyOptions = InjectedInputKeyOptions.ExtendedKey
         inputInjector.InjectKeyboardInput({info})
         Await Task.Delay(100)
    
         'release the caps lock key. If you do not release the key, the cap lock will remain pressed state
         info.KeyOptions = InjectedInputKeyOptions.KeyUp
         inputInjector.InjectKeyboardInput({info})
         Await Task.Delay(100)
    
    
     End Sub
0 Votes 0 ·

Yes, I agree with your code above if you only want to press the cap lock key once. It does that fine.


However, what is the code to do that if and only if the Caps Lock is on ?


0 Votes 0 ·
Show more comments
ansalc-1556 avatar image
0 Votes"
ansalc-1556 answered ·

For me it does not work. If I have the Caps Lock on and run the following code by pressing Button1 the Caps Lock, The Caps Lock continues as On.

It will start working fine from them on.

It is as if the app does not capture the initial state of the Caps Lock key. Only after it has been refreshed by the app.

 Private Async Sub Button1_Click(sender As Object, e As RoutedEventArgs)

     Dim inputInfo As New InjectedInputKeyboardInfo
     Dim info As New InjectedInputKeyboardInfo()
     Dim inputInjector As InputInjector = InputInjector.TryCreate()


     Dim keystate = Window.Current.CoreWindow.GetKeyState(VirtualKey.CapitalLock)
     Dim isNumLocked = (keystate And Windows.UI.Core.CoreVirtualKeyStates.Locked) <> 0


     If isNumLocked Then

         info.VirtualKey = VirtualKey.CapitalLock

         'press the key
         info.KeyOptions = InjectedInputKeyOptions.ExtendedKey
         inputInjector.InjectKeyboardInput({info})
         Await Task.Delay(100)

         'release the caps lock key. If you do not release the key, the cap lock will remain pressed state
         info.KeyOptions = InjectedInputKeyOptions.KeyUp
         inputInjector.InjectKeyboardInput({info})
         Await Task.Delay(100)

     End If

 End Sub

· 4 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

What do you mean by it does not work? Did you try to enter some text to test and it shows still in the capital? How do you test whether the caps lock is on or not?

0 Votes 0 ·

Hello Roy,

Any further ideas about this issue?

I have tested it on a different computer and I get the same problem.

It is hard to understand why something so simple is so complicated in UWP.

In .NET it just took a line of code and worked fine: If Control.IsKeyLocked(Keys.CapsLock)) Then

0 Votes 0 ·

Could you please tell me how you test it and check whether the caps lock is on or off?

0 Votes 0 ·

With the code above in the Button1 clicked event:

  1. I set the Caps Lock as locked

  2. I run the app

  3. I click button1 and see that Caps Lock stays locked


0 Votes 0 ·
ansalc-1556 avatar image
0 Votes"
ansalc-1556 answered ·

I've found (almost) a solution, to put the code in the MainPage loaded event. It is not ideal because the timing of the Caps Lock status change is not exactly when needed

Why does it not work if it is in the Button clicked event? Hard to understand

 Private Async Sub MainPage_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded

     Dim inputInfo As New InjectedInputKeyboardInfo
     Dim info As New InjectedInputKeyboardInfo()
     Dim inputInjector As InputInjector = InputInjector.TryCreate()

     If Window.Current.CoreWindow.GetKeyState(VirtualKey.CapitalLock).HasFlag(Windows.UI.Core.CoreVirtualKeyStates.Locked) Then

         info.VirtualKey = VirtualKey.CapitalLock

         info.KeyOptions = InjectedInputKeyOptions.None
         inputInjector.InjectKeyboardInput({info})
         Await Task.Delay(100)


         info.KeyOptions = InjectedInputKeyOptions.KeyUp
         inputInjector.InjectKeyboardInput({info})
         Await Task.Delay(100)

     End If


 End Sub
·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

ansalc-1556 avatar image
0 Votes"
ansalc-1556 answered ·

I've found the reason for my trouble.

Before the Caps Lock check I had:

Await Task.Delay(5000).ConfigureAwait(False)

I've changed it to:

Await Task.Delay(5000).ConfigureAwait(True)

And all is working fine. This is due to True continuing on Captured Context. With False it did not capture the Window.Current.CoreWindow status.

I've found this out, because I wrote my project in C# and C# alerted me that there was no instance of Window.Current.CoreWindow, which brought my attention to the ConfigureAwait above.

The Visual Basic compiler did not alert me of the problem.

·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.