Disable Sticky Keys
Posted: Sat Aug 26, 2023 5:26 am
Do games disable Sticky Keys when they start? I assume they would. Has anyone figured out how to disable and enable it in PureBasic?
http://www.purebasic.com
https://www.purebasic.fr/english/
Code: Select all
Structure STICKYKEYS
cbSize.l
dwFlags.l
EndStructure
Define.STICKYKEYS sk\cbSize=SizeOf(STICKYKEYS), skOrig=sk
#SKF_STICKYKEYSON=$00000001
#SKF_HOTKEYACTIVE=$00000004
#SKF_CONFIRMHOTKEY=$00000008
SystemParametersInfo_(#SPI_GETSTICKYKEYS, SizeOf(STICKYKEYS), @skOrig, 0); get original settings
sk\dwFlags=skOrig\dwFlags&~(#SKF_STICKYKEYSON|#SKF_HOTKEYACTIVE); turn off the SKF_STICKYKEYSON and SKF_HOTKEYACTIVE flags
SystemParametersInfo_(#SPI_SETSTICKYKEYS, SizeOf(STICKYKEYS), @sk, 0); set new settings
Code: Select all
SystemParametersInfo_(#SPI_SETSTICKYKEYS, SizeOf(STICKYKEYS), @skOrig, 0); reset settings to original
Code: Select all
; Disable keyboard accessibility
; 2023-08-27 by Enne (NS studios)
; Allows disabling, reverting, and checking the state of the system-wide settings for filter, sticky, and toggle keys
; should be dll-friendly
; InitA11y() must be called before using any of the isX() macros or DisableA11y func
EnableExplicit
;{ consts
#FKF_FILTERKEYSON=$00000001
#FKF_HOTKEYACTIVE=$00000004
#FKF_CONFIRMHOTKEY=$00000008
#SKF_STICKYKEYSON=$00000001
#SKF_HOTKEYACTIVE=$00000004
#SKF_CONFIRMHOTKEY=$00000008
#TKF_TOGGLEKEYSON=$00000001
#TKF_HOTKEYACTIVE=$00000004
#TKF_CONFIRMHOTKEY=$00000008
;} consts
;{ structs
Structure FILTERKEYS
cbSize.l
dwFlags.l
iWaitMSec.l
iDelayMSec.l
iRepeatMSec.l
iBounceMSec.l
EndStructure
Structure STICKYKEYS
cbSize.l
dwFlags.l
EndStructure
Structure TOGGLEKEYS
cbSize.l
dwFlags.l
EndStructure
;} structs
Global fkOrig.FILTERKEYS, skOrig.STICKYKEYS, tkOrig.TOGGLEKEYS, a11yInit
; get initial accessibility settings
; return=1 if all features have been read successfully, 0 otherwise
Procedure.i initA11y()
fkOrig\cbSize=SizeOf(FILTERKEYS): skOrig\cbSize=SizeOf(STICKYKEYS): tkOrig\cbSize=SizeOf(TOGGLEKEYS)
Protected fkr=SystemParametersInfo_(#SPI_GETFILTERKEYS, SizeOf(FILTERKEYS), @fkOrig, 0),
skr=SystemParametersInfo_(#SPI_GETSTICKYKEYS, SizeOf(STICKYKEYS), @skOrig, 0),
tkr=SystemParametersInfo_(#SPI_GETTOGGLEKEYS, SizeOf(TOGGLEKEYS), @tkOrig, 0)
a11yInit=Bool(fkr And skr And tkr)
ProcedureReturn a11yInit
EndProcedure
; DisableAccessibility (not exact port of https://learn.microsoft.com/en-us/windows/win32/dxtecharts/disabling-shortcut-keys-in-games)
; state=1 to disable accessibility features (default), 0 to restore them to original settings
; force=whether to disable an accessibility feature even if it's currently active (1=force, 0=don't force (default))
; return=1 if all settings were set successfully, 0 otherwise
; Warning!!! This will affect the accessibility settings system-wide, and the settings will persist after the app exits. It's a must to return the settings to their original state at the very least before exiting, but preferably when the window loses focus, too.
Procedure.i DisableA11y(state=1, force=0)
If Not a11yInit
DebuggerError("initA11y() must be called before calling DisableA11y()!")
EndIf
Protected fk.FILTERKEYS=fkOrig, sk.STICKYKEYS=skOrig, tk.TOGGLEKEYS=tkOrig
If state
If Not fk\dwFlags&#FKF_FILTERKEYSON Or force
fk\dwFlags&~(#FKF_FILTERKEYSON|#FKF_HOTKEYACTIVE|#FKF_CONFIRMHOTKEY)
EndIf
If Not sk\dwFlags&#SKF_STICKYKEYSON Or force
sk\dwFlags&~(#SKF_STICKYKEYSON|#SKF_HOTKEYACTIVE|#SKF_CONFIRMHOTKEY)
EndIf
If Not tk\dwFlags&#TKF_TOGGLEKEYSON Or force
tk\dwFlags&~(#TKF_TOGGLEKEYSON|#TKF_HOTKEYACTIVE|#TKF_CONFIRMHOTKEY)
EndIf
EndIf
Protected fkr=SystemParametersInfo_(#SPI_SETFILTERKEYS, SizeOf(FILTERKEYS), @fk, 0),
skr=SystemParametersInfo_(#SPI_SETSTICKYKEYS, SizeOf(STICKYKEYS), @sk, 0),
tkr=SystemParametersInfo_(#SPI_SETTOGGLEKEYS, SizeOf(TOGGLEKEYS), @tk, 0)
ProcedureReturn Bool(fkr And skr And tkr)
EndProcedure
; checks if filter keys are either active or the hotkey for them is on, meaning they could be triggered
Macro isFilterKeys()
(Bool(fkOrig\dwFlags&(#FKF_FILTERKEYSON|#FKF_HOTKEYACTIVE)))
EndMacro
; checks if sticky keys are either active or the hotkey for them is on, meaning they could be triggered
Macro isStickyKeys()
(Bool(skOrig\dwFlags&(#SKF_STICKYKEYSON|#SKF_HOTKEYACTIVE)))
EndMacro
; checks if toggle keys are either active or the hotkey for them is on, meaning they could be triggered
Macro isToggleKeys()
(Bool(tkOrig\dwFlags&(#TKF_TOGGLEKEYSON|#TKF_HOTKEYACTIVE)))
EndMacro
; checks if at least one accessibility feature is either active or the hotkey for it is on, meaning it can be triggered
Macro isA11y()
(Bool(isFilterKeys() Or isStickyKeys() Or isToggleKeys()))
EndMacro
coco2 wrote: Mon Aug 28, 2023 12:30 pm It works well, except I think I ran it without restoring the original settings now I think I have broken my toggle keys. I tried rebooting and checking the Windows settings but I can't get it to work again. Do you happen to know how to force toggle keys back on? I seem to have broken it. Which goes to show how it can be problematic playing around with these settings and the game crashes. But if Microsoft has documentation saying how to do it then it seems like it is somewhat expected that developers are going to do it.
check box.Allow the shortcut key to start Toggle Keys
coco2 wrote: Mon Aug 28, 2023 12:50 pm The only way I got it to work again was to change the registry:
[HKEY_CURRENT_USER\Control Panel\Accessibility\ToggleKeys]
"Flags"="63"
It seems that ToggleKeys does not have a way for the user to turn the keyboard shortcut back on in the settings of Windows 11. Not sure about Windows 10.