Control Caps Lock via VBA

Guard913

Board Regular
Joined
Apr 10, 2016
Messages
137
Office Version
  1. 2016
  2. 2010
Platform
  1. Windows
Ok, so I need a macro that will activate caps lock on my keyboard that will work outside of excel. I already have a code that will work inside excel, but the thing is certain data on certain sheets when i submit to a program outside of excel needs to be Capped, while inside excel it does not. And because of how this program works (not my program) it must be typed manually. I don't wanna use the caps lock key on keyboard because of how fast paced the work environment is if I cap in the wrong spot i have to re-do everything again.... very complex and time consuming. I just want it to change over when on a certain form, and then deactivate after I leave said form.
 

Excel Facts

Enter current date or time
Ctrl+: enters current time. Ctrl+; enters current date. Use Ctrl+: Ctrl+; Enter for current date & time.

Jaafar Tribak

Well-known Member
Joined
Dec 5, 2002
Messages
8,334
Office Version
  1. 2016
Platform
  1. Windows
Are you saying that you want the Caps Lock key to be On after leaving excel and Off when re-activating excel ?

And you mentioned "I just want it to change over when on a certain form, and then deactivate after I leave said form."- Will you be working on an excel userform when switching back and forth between excel and the outside program ?
 

Guard913

Board Regular
Joined
Apr 10, 2016
Messages
137
Office Version
  1. 2016
  2. 2010
Platform
  1. Windows
Are you saying that you want the Caps Lock key to be On after leaving excel and Off when re-activating excel ?

And you mentioned "I just want it to change over when on a certain form, and then deactivate after I leave said form."- Will you be working on an excel userform when switching back and forth between excel and the outside program ?
I will be using the excel program userform and sheet and will be moving in and out of that and outside program. It will be attached to a button that starts the form (already created just need to add extra code for caps lock) that will be used on outside source and then when i click a premade button to close form it would turn caps off.
 

Jaafar Tribak

Well-known Member
Joined
Dec 5, 2002
Messages
8,334
Office Version
  1. 2016
Platform
  1. Windows
So why don't you just turn caps lock on once when first loading the userform ? That way, Caps lock will remain on when switching to the outside program.

And then, turn Caps lock Off only when unloading the userform.
 

Guard913

Board Regular
Joined
Apr 10, 2016
Messages
137
Office Version
  1. 2016
  2. 2010
Platform
  1. Windows

ADVERTISEMENT

So why don't you just turn caps lock on once when first loading the userform ? That way, Caps lock will remain on when switching to the outside program.

And then, turn Caps lock Off only when unloading the userform.
cuzz thats not what i need/want. because i still have to communicate to my team via text and they would not be happy with all caps :D
 

Jaafar Tribak

Well-known Member
Joined
Dec 5, 2002
Messages
8,334
Office Version
  1. 2016
Platform
  1. Windows
Try this code which will monitor the capslock key while the userform is being used.

When the userform is active, the capslock key will be OFF and when the userform is not active the capslock key will be ON.

workbook demo


1- Code in a Standard Module:
VBA Code:
Option Explicit

Private Type KeyboardBytes
    kbByte(0 To 255) As Byte
End Type

#If VBA7 Then
    Private Declare PtrSafe Function SetTimer Lib "user32" (ByVal hwnd As LongPtr, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As LongPtr) As Long
    Private Declare PtrSafe Function KillTimer Lib "user32" (ByVal hwnd As LongPtr, ByVal uIDEvent As Long) As Long
    Private Declare PtrSafe Function GetCurrentProcessId Lib "kernel32" () As Long
    Private Declare PtrSafe Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As LongPtr, lpdwProcessId As Long) As Long
    Private Declare PtrSafe Function GetForegroundWindow Lib "user32" () As LongPtr
    Private Declare PtrSafe Function GetKeyboardState Lib "user32" (pbKeyState As KeyboardBytes) As Long
    Private Declare PtrSafe Function SetKeyboardState Lib "user32" (lppbKeyState As KeyboardBytes) As Long
    Private Declare PtrSafe Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As LongPtr)
#Else
    Private Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
    Private Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal uIDEvent As Long) As Long
    Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
    Private Declare Function GetForegroundWindow Lib "user32" () As Long
    Private Declare Function GetKeyboardState Lib "user32" (pbKeyState As KeyboardBytes) As Long
    Private Declare Function SetKeyboardState Lib "user32" (lppbKeyState As KeyboardBytes) As Long
    Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
#End If

Private bEnable As Boolean


Public Property Let MonitorCapsLock(Optional ByVal EnableCapsLockInCurrentProcess As Boolean, ByVal bMonitor As Boolean)

    Const VK_CAPITAL = &H14
    Static lInitCapsState As Long
    Dim kbArray As KeyboardBytes
   

    bEnable = EnableCapsLockInCurrentProcess
   
    If bMonitor Then
        Call GetKeyboardState(kbArray)
        lInitCapsState = kbArray.kbByte(VK_CAPITAL)
        Call SetTimer(Application.hwnd, 0, 0, AddressOf TimerProc)
    Else
        Call KillTimer(Application.hwnd, 0)
        Call GetKeyboardState(kbArray)
        If lInitCapsState <> kbArray.kbByte(VK_CAPITAL) Then
            Call ToggleCapsLock
        End If
    End If

End Property


Private Sub TimerProc()

    Const VK_CAPITAL = &H14
   
    Dim kbArray As KeyboardBytes
    Dim lPID As Long, lCapsLockState As Long
   
    lCapsLockState = IIf(bEnable, 0, 1)
    Call GetKeyboardState(kbArray)
    Call GetWindowThreadProcessId(GetForegroundWindow, lPID)
   
    If lPID = GetCurrentProcessId Then
        If kbArray.kbByte(VK_CAPITAL) = lCapsLockState Then
            Call ToggleCapsLock
        End If
    Else
        If kbArray.kbByte(VK_CAPITAL) <> lCapsLockState Then
            kbArray.kbByte(VK_CAPITAL) = lCapsLockState
            Call SetKeyboardState(kbArray)
            Call ToggleCapsLock
        End If
    End If

End Sub


Private Sub ToggleCapsLock()

    Const VK_CAPITAL = &H14
    Const KEYEVENTF_EXTENDEDKEY = &H1
    Const KEYEVENTF_KEYUP = &H2
   
    Call keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or 0, 0)
    Call keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)

End Sub


2- Code Usage in the UserForm Module:
VBA Code:
Option Explicit

Private Sub UserForm_Initialize()

    MonitorCapsLock(EnableCapsLockInCurrentProcess:=False) = True

End Sub

Private Sub UserForm_Terminate()

    MonitorCapsLock = False

End Sub


Setting the EnableCapsLockInCurrentProcess flag parameter to FALSE will turn the capslock key OFF for the calling process and ON for all other processes... Setting the parameter to TRUE will turn the capslock key ON for the calling process and OFF for all other running processes.
 
Solution

Guard913

Board Regular
Joined
Apr 10, 2016
Messages
137
Office Version
  1. 2016
  2. 2010
Platform
  1. Windows
Try this code which will monitor the capslock key while the userform is being used.

When the userform is active, the capslock key will be OFF and when the userform is not active the capslock key will be ON.

workbook demo


1- Code in a Standard Module:
VBA Code:
Option Explicit

Private Type KeyboardBytes
    kbByte(0 To 255) As Byte
End Type

#If VBA7 Then
    Private Declare PtrSafe Function SetTimer Lib "user32" (ByVal hwnd As LongPtr, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As LongPtr) As Long
    Private Declare PtrSafe Function KillTimer Lib "user32" (ByVal hwnd As LongPtr, ByVal uIDEvent As Long) As Long
    Private Declare PtrSafe Function GetCurrentProcessId Lib "kernel32" () As Long
    Private Declare PtrSafe Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As LongPtr, lpdwProcessId As Long) As Long
    Private Declare PtrSafe Function GetForegroundWindow Lib "user32" () As LongPtr
    Private Declare PtrSafe Function GetKeyboardState Lib "user32" (pbKeyState As KeyboardBytes) As Long
    Private Declare PtrSafe Function SetKeyboardState Lib "user32" (lppbKeyState As KeyboardBytes) As Long
    Private Declare PtrSafe Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As LongPtr)
#Else
    Private Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
    Private Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal uIDEvent As Long) As Long
    Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
    Private Declare Function GetForegroundWindow Lib "user32" () As Long
    Private Declare Function GetKeyboardState Lib "user32" (pbKeyState As KeyboardBytes) As Long
    Private Declare Function SetKeyboardState Lib "user32" (lppbKeyState As KeyboardBytes) As Long
    Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
#End If

Private bEnable As Boolean


Public Property Let MonitorCapsLock(Optional ByVal EnableCapsLockInCurrentProcess As Boolean, ByVal bMonitor As Boolean)

    Const VK_CAPITAL = &H14
    Static lInitCapsState As Long
    Dim kbArray As KeyboardBytes
  

    bEnable = EnableCapsLockInCurrentProcess
  
    If bMonitor Then
        Call GetKeyboardState(kbArray)
        lInitCapsState = kbArray.kbByte(VK_CAPITAL)
        Call SetTimer(Application.hwnd, 0, 0, AddressOf TimerProc)
    Else
        Call KillTimer(Application.hwnd, 0)
        Call GetKeyboardState(kbArray)
        If lInitCapsState <> kbArray.kbByte(VK_CAPITAL) Then
            Call ToggleCapsLock
        End If
    End If

End Property


Private Sub TimerProc()

    Const VK_CAPITAL = &H14
  
    Dim kbArray As KeyboardBytes
    Dim lPID As Long, lCapsLockState As Long
  
    lCapsLockState = IIf(bEnable, 0, 1)
    Call GetKeyboardState(kbArray)
    Call GetWindowThreadProcessId(GetForegroundWindow, lPID)
  
    If lPID = GetCurrentProcessId Then
        If kbArray.kbByte(VK_CAPITAL) = lCapsLockState Then
            Call ToggleCapsLock
        End If
    Else
        If kbArray.kbByte(VK_CAPITAL) <> lCapsLockState Then
            kbArray.kbByte(VK_CAPITAL) = lCapsLockState
            Call SetKeyboardState(kbArray)
            Call ToggleCapsLock
        End If
    End If

End Sub


Private Sub ToggleCapsLock()

    Const VK_CAPITAL = &H14
    Const KEYEVENTF_EXTENDEDKEY = &H1
    Const KEYEVENTF_KEYUP = &H2
  
    Call keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or 0, 0)
    Call keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)

End Sub


2- Code Usage in the UserForm Module:
VBA Code:
Option Explicit

Private Sub UserForm_Initialize()

    MonitorCapsLock(EnableCapsLockInCurrentProcess:=False) = True

End Sub

Private Sub UserForm_Terminate()

    MonitorCapsLock = False

End Sub


Setting the EnableCapsLockInCurrentProcess flag parameter to FALSE will turn the capslock key OFF for the calling process and ON for all other processes... Setting the parameter to TRUE will turn the capslock key ON for the calling process and OFF for all other running processes.

Works perfectly!!! Thank you so much!!!
 

Forum statistics

Threads
1,144,514
Messages
5,724,805
Members
422,579
Latest member
parsnipsnatcher

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Top