Ooops
October 28, 2020, 06:31:09 AM

Author Topic: [bb] DisableStickyKeys and RestoreStickyKeys functions by Zethrax [ 1+ years ago ]  (Read 1250 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
Title : DisableStickyKeys and RestoreStickyKeys functions
Author : Zethrax
Posted : 1+ years ago

Description : *** Blitz3D/BlitzPlus code. See below for the link to the BlitzMax version. ***

-- DisableStickyKeys function --

Turns off the sticky keys prompt and hotkeys. Run this function at the begining of your program.

Returns the stickykeys flags. The returned integer value should be saved in a global and provided as the parameter for the 'RestoreStickyKeys' function.

The 'RestoreStickyKeys' function must be run prior to program shutown to restore the user's stickykeys settings. This is no way to run a railroad, but seems to be best practice in this case. Welcome to the Windows API.
-- RestoreStickyKeys function --

Restores the original state of the sticky keys prompt and hotkeys.

Run this function at the end of your program.

The 'stickykeys_flags' parameter should be the value returned by 'DisableStickyKeys'.

You can find the BlitzMax version of this code at:-
<a href="codearcsa05f.html?code=3010" target="_blank">http://www.blitzbasic.com/codearcs/codearcs.php?code=3010[/url]

Reference links:-
<a href="http://msdn.microsoft.com/en-us/library/ee416808(v=vs.85).aspx" target="_blank">http://msdn.microsoft.com/en-us/library/ee416808(v=vs.85).aspx[/url]
<a href="http://msdn.microsoft.com/en-us/library/dd373652(v=vs.85).aspx" target="_blank">http://msdn.microsoft.com/en-us/library/dd373652(v=vs.85).aspx[/url]
<a href="http://msdn.microsoft.com/en-us/library/ms724947(VS.85).aspx" target="_blank">http://msdn.microsoft.com/en-us/library/ms724947(VS.85).aspx[/url]

Requirements:-
Grab the user32.dll decls from: <a href="codearcsbcfe.html?code=1179" target="_blank">http://www.blitzbasic.com/codearcs/codearcs.php?code=1179[/url]
Put them in your userlibs folder in a text file named: user32.decls

Example:-
; Run this code at the start of your program.
Global G_sticky_keys_data = DisableStickyKeys()

; Run this code prior to shutting down your program.
RestoreStickyKeys( G_sticky_keys_data )

Notes:-
The functions will save and delete a temporary file named "stickykeys.dat". That file is used to restore the state of the sticky keys on the users system in case the program crashes before the 'RestoreStickyKeys' function can be run (this seems to be best practice in this case). If files can't be saved to the folder the program is in then the 'filepath$' variable in the functions below should be set to save to a folder that can be saved to.


Code :
Code: BlitzBasic
  1. Function DisableStickyKeys()
  2.         ; Turns off the sticky keys prompt and hotkeys.
  3.         ; Run this function at the begining of your program.
  4.  
  5.         ; Returns the stickykeys flags. The returned integer value should be saved in a global
  6.         ; and provided as the parameter for the 'RestoreStickyKeys' function.
  7.  
  8.         ; The 'RestoreStickyKeys' function must be run prior to program shutown to restore
  9.         ; the user's stickykeys settings. This is no way to run a railroad, but seems to be
  10.         ; best practice in this case. Welcome to the Windows API.
  11.        
  12.         ; Reference links:-
  13.         ; http://msdn.microsoft.com/en-us/library/ee416808(v=vs.85).aspx
  14.         ; http://msdn.microsoft.com/en-us/library/dd373652(v=vs.85).aspx
  15.         ; http://msdn.microsoft.com/en-us/library/ms724947(VS.85).aspx
  16.         ;
  17.         ; Requirements:-
  18.         ; Grab the user32.dll decls from: http://www.blitzbasic.com/codearcs/codearcs.php?code=1179
  19.         ; Put them in your userlibs folder in a text file named: user32.decls
  20.        
  21.         Local SPI_GETSTICKYKEYS = $0000003A
  22.         Local SPI_SETSTICKYKEYS = $0000003B
  23.         Local SKF_HOTKEYACTIVE_MASK = $00000004 Xor $ffffffff
  24.         Local SKF_CONFIRMHOTKEY_MASK = $00000008 Xor $ffffffff
  25.         Local stickykeys_flags
  26.        
  27.         Local filepath$ = "stickykeys.dat"
  28.        
  29.         ; Create a bank to store the STICKYKEYS structure.
  30.         Local bank = CreateBank( 8 )
  31.  
  32.         ; Set the first integer in the bank to the total size of the bank (8 bytes).
  33.         PokeInt bank, 0, 8
  34.  
  35.         ; Open the file that holds the STICKYKEYS flags.
  36.         file = ReadFile( filepath$ )
  37.        
  38.         If file ; If the file exists then the stickykeys state wasn't properly 
  39.         ; restored last time - possibly due to a crash during the last session.
  40.        
  41.                 ; Grab the STICKYKEYS flags from the file so we can restore the state.
  42.                 PokeInt bank, 4, ReadInt( file )
  43.                 CloseFile file
  44.                
  45.         Else ; If the file doesn't exist then the stickykeys state was properly
  46.         ; restored last time, so we get it via SystemParametersInfo.
  47.                
  48.                 ; - Get the STICKYKEYS structure.
  49.                 ; First parameter is the value of the SPI_GETSTICKYKEYS Windows constant.
  50.                 ; Second parameter is the size of the STICKYKEYS structure again (8 bytes).
  51.                 ; Third parameter is the address of the STICKYKEYS structure (the bank handle).
  52.                 ; Fourth parameter is not used and should be a zero.
  53.                 api_SystemParametersInfo( SPI_GETSTICKYKEYS, 8, bank, 0 )
  54.                
  55.         EndIf
  56.  
  57.         ; Save the value of the second INT in the STICKYKEYS structure to a file.
  58.         ; This allows the state to be restored in case a program crash happens before
  59.         ; the 'RestoreStickyKeys' function can be run.
  60.         file = WriteFile( filepath$ )
  61.         If file
  62.                 WriteInt file, PeekInt( bank, 4 )
  63.                 CloseFile file
  64.         EndIf
  65.  
  66.         stickykeys_flags = PeekInt( bank, 4 )
  67.  
  68.         ; Turn off the SKF_HOTKEYACTIVE and SKF_CONFIRMHOTKEY flags
  69.         PokeInt bank, 4, ( stickykeys_flags And SKF_HOTKEYACTIVE_MASK ) And SKF_CONFIRMHOTKEY_MASK
  70.  
  71.         ; Set the first integer in the bank to the total size of the bank (8 bytes).
  72.         PokeInt bank, 0, 8
  73.  
  74.         ; - Set the STICKYKEYS structure.
  75.         ; First parameter is the value of the SPI_SETSTICKYKEYS Windows constant.
  76.         ; Second parameter is the size of the STICKYKEYS structure again (8 bytes).
  77.         ; Third parameter is the address of the STICKYKEYS structure (the bank handle).
  78.         ; Fourth parameter is not used and should be a zero.
  79.         api_SystemParametersInfo( SPI_SETSTICKYKEYS, 8, bank, 0 )
  80.  
  81.         FreeBank bank
  82.        
  83.         ; Return the flags so they can be stored in a global and uses with the 'RestoreStickyKeys' function.
  84.         Return stickykeys_flags
  85. End Function
  86.  
  87.  
  88.  
  89. Function RestoreStickyKeys( stickykeys_flags )
  90.         ; Restores the original state of the sticky keys prompt and hotkeys.
  91.        
  92.         ; Run this function at the end of your program.
  93.        
  94.         ; The 'stickykeys_flags' parameter should be the value returned by 'DisableStickyKeys'.
  95.  
  96.         Local SPI_SETSTICKYKEYS = $0000003B
  97.        
  98.         filepath$ = "stickykeys.dat"
  99.        
  100.         ; Create a bank to store the STICKYKEYS structure.
  101.         bank = CreateBank( 8 )
  102.        
  103.         ; Set the first integer in the bank to the total size of the bank (8 bytes).
  104.         PokeInt bank, 0, 8
  105.        
  106.         ; Store the sticky keys flags in the second integer in the bank.
  107.         PokeInt bank, 4, stickykeys_flags
  108.        
  109.         ; - Set the STICKYKEYS structure.
  110.         ; First parameter is the value of the SPI_SETSTICKYKEYS Windows constant.
  111.         ; Second parameter is the size of the STICKYKEYS structure again (8 bytes).
  112.         ; Third parameter is the address of the STICKYKEYS structure (the bank handle).
  113.         ; Fourth parameter is not used and should be a zero.
  114.         api_SystemParametersInfo( SPI_SETSTICKYKEYS, 8, bank, 0 )
  115.  
  116.         FreeBank bank
  117.  
  118.         ; Delete the temporary file used to store the stickykeys flags.
  119.         If FileType( filepath$ ) = 1 Then DeleteFile filepath$
  120. End Function


Comments :


Imperium(Posted 1+ years ago)

 The API commands work fine but the sticky keys still trigger when I press shift 5 times. I'm confident I did everything correct. Can anyone confirm this works?


Zethrax(Posted 1+ years ago)

 It works for me in Windows 7. What operating system are you using it on? Can you post some example code that fails to work?The code below works fine for me on Windows 7 (64 bit edition).
Code: [Select]
Global G_sticky_keys_data = DisableStickyKeys()

Graphics 800, 600, 0, 2

While Not KeyHit( 1 )

Flip

Delay( 20 )

Wend

RestoreStickyKeys( G_sticky_keys_data )

End


Function DisableStickyKeys()
; Turns off the sticky keys prompt and hotkeys.
; Run this function at the begining of your program.

; Returns the stickykeys flags. The returned integer value should be saved in a global
; and provided as the parameter for the 'RestoreStickyKeys' function.

; The 'RestoreStickyKeys' function must be run prior to program shutown to restore
; the user's stickykeys settings. This is no way to run a railroad, but seems to be
; best practice in this case. Welcome to the Windows API.

; Reference links:-
; <a href="http://msdn.microsoft.com/en-us/library/ee416808(v=vs.85).aspx" target="_blank">http://msdn.microsoft.com/en-us/library/ee416808(v=vs.85).aspx</a>
; <a href="http://msdn.microsoft.com/en-us/library/dd373652(v=vs.85).aspx" target="_blank">http://msdn.microsoft.com/en-us/library/dd373652(v=vs.85).aspx</a>
; <a href="http://msdn.microsoft.com/en-us/library/ms724947(VS.85).aspx" target="_blank">http://msdn.microsoft.com/en-us/library/ms724947(VS.85).aspx</a>
;
; Requirements:-
; Grab the user32.dll decls from: <a href="codearcsbcfe.html?code=1179" target="_blank">http://www.blitzbasic.com/codearcs/codearcs.php?code=1179</a>
; Put them in your userlibs folder in a text file named: user32.decls

Local SPI_GETSTICKYKEYS = $0000003A
Local SPI_SETSTICKYKEYS = $0000003B
Local SKF_HOTKEYACTIVE_MASK = $00000004 Xor $ffffffff
Local SKF_CONFIRMHOTKEY_MASK = $00000008 Xor $ffffffff
Local stickykeys_flags

Local filepath$ = "stickykeys.dat"

; Create a bank to store the STICKYKEYS structure.
Local bank = CreateBank( 8 )

; Set the first integer in the bank to the total size of the bank (8 bytes).
PokeInt bank, 0, 8

; Open the file that holds the STICKYKEYS flags.
file = ReadFile( filepath$ )

If file ; If the file exists then the stickykeys state wasn't properly
; restored last time - possibly due to a crash during the last session.

; Grab the STICKYKEYS flags from the file so we can restore the state.
PokeInt bank, 4, ReadInt( file )
CloseFile file

Else ; If the file doesn't exist then the stickykeys state was properly
; restored last time, so we get it via SystemParametersInfo.

; - Get the STICKYKEYS structure.
; First parameter is the value of the SPI_GETSTICKYKEYS Windows constant.
; Second parameter is the size of the STICKYKEYS structure again (8 bytes).
; Third parameter is the address of the STICKYKEYS structure (the bank handle).
; Fourth parameter is not used and should be a zero.
api_SystemParametersInfo( SPI_GETSTICKYKEYS, 8, bank, 0 )

EndIf

; Save the value of the second INT in the STICKYKEYS structure to a file.
; This allows the state to be restored in case a program crash happens before
; the 'RestoreStickyKeys' function can be run.
file = WriteFile( filepath$ )
If file
WriteInt file, PeekInt( bank, 4 )
CloseFile file
EndIf

stickykeys_flags = PeekInt( bank, 4 )

; Turn off the SKF_HOTKEYACTIVE and SKF_CONFIRMHOTKEY flags
PokeInt bank, 4, ( stickykeys_flags And SKF_HOTKEYACTIVE_MASK ) And SKF_CONFIRMHOTKEY_MASK

; Set the first integer in the bank to the total size of the bank (8 bytes).
PokeInt bank, 0, 8

; - Set the STICKYKEYS structure.
; First parameter is the value of the SPI_SETSTICKYKEYS Windows constant.
; Second parameter is the size of the STICKYKEYS structure again (8 bytes).
; Third parameter is the address of the STICKYKEYS structure (the bank handle).
; Fourth parameter is not used and should be a zero.
api_SystemParametersInfo( SPI_SETSTICKYKEYS, 8, bank, 0 )

FreeBank bank

; Return the flags so they can be stored in a global and uses with the 'RestoreStickyKeys' function.
Return stickykeys_flags
End Function



Function RestoreStickyKeys( stickykeys_flags )
; Restores the original state of the sticky keys prompt and hotkeys.

; Run this function at the end of your program.

; The 'stickykeys_flags' parameter should be the value returned by 'DisableStickyKeys'.

Local SPI_SETSTICKYKEYS = $0000003B

filepath$ = "stickykeys.dat"

; Create a bank to store the STICKYKEYS structure.
bank = CreateBank( 8 )

; Set the first integer in the bank to the total size of the bank (8 bytes).
PokeInt bank, 0, 8

; Store the sticky keys flags in the second integer in the bank.
PokeInt bank, 4, stickykeys_flags

; - Set the STICKYKEYS structure.
; First parameter is the value of the SPI_SETSTICKYKEYS Windows constant.
; Second parameter is the size of the STICKYKEYS structure again (8 bytes).
; Third parameter is the address of the STICKYKEYS structure (the bank handle).
; Fourth parameter is not used and should be a zero.
api_SystemParametersInfo( SPI_SETSTICKYKEYS, 8, bank, 0 )

FreeBank bank

; Delete the temporary file used to store the stickykeys flags.
If FileType( filepath$ ) = 1 Then DeleteFile filepath$
End Function



Imperium(Posted 1+ years ago)

 I think nothing is being written to the .dat file? When I open the program while its running and after I see only 5 blank spaces. Could this be a permission issue since I'm not logged on the admin account?Edit: Made no difference.


Zethrax(Posted 1+ years ago)

 The dat file stores the data as a 32 bit int, so you may see nothing if you open it in a text editor. That file is just used to restore the flags, so the sticky key dialog window should still be turned off until the program ends.I'm finding that the sticky key flags aren't being properly restored when the program ends (pressing shift 5 times doesn't open the sticky keys dialog) but are still restored ok when Windows is restarted, so I don't know what's going on there. I tested it thoroughly when I originally posted this archive code. I'll have to look into it when I get time. The Windows API should be backwards compatible with previous versions, but it's possible they may have changed something in an update.


Imperium(Posted 1+ years ago)

 I will also try this one here:<a href="codearcs5737.html?code=1334" target="_blank">http://www.blitzbasic.com/codearcs/codearcs.php?code=1334[/url]On my XP box stickykeys is always disabled so I can't test it on that. [/i]

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal