Disabling Accessibility Shortcuts in .NET Application? Disabling Accessibility Shortcuts in .NET Application? windows windows

Disabling Accessibility Shortcuts in .NET Application?


Just in case anyone else needs this, here's the converted C# code, which at last does work:

    [DllImport( "user32.dll", EntryPoint = "SystemParametersInfo", SetLastError = false )]    private static extern bool SystemParametersInfo( uint action, uint param,        ref SKEY vparam, uint init );    [DllImport( "user32.dll", EntryPoint = "SystemParametersInfo", SetLastError = false )]    private static extern bool SystemParametersInfo( uint action, uint param,        ref FILTERKEY vparam, uint init );    private const uint SPI_GETFILTERKEYS = 0x0032;    private const uint SPI_SETFILTERKEYS = 0x0033;    private const uint SPI_GETTOGGLEKEYS = 0x0034;    private const uint SPI_SETTOGGLEKEYS = 0x0035;    private const uint SPI_GETSTICKYKEYS = 0x003A;    private const uint SPI_SETSTICKYKEYS = 0x003B;    private static bool StartupAccessibilitySet = false;    private static SKEY StartupStickyKeys;    private static SKEY StartupToggleKeys;    private static FILTERKEY StartupFilterKeys;    private const uint SKF_STICKYKEYSON = 0x00000001;    private const uint TKF_TOGGLEKEYSON = 0x00000001;    private const uint SKF_CONFIRMHOTKEY = 0x00000008;    private const uint SKF_HOTKEYACTIVE = 0x00000004;    private const uint TKF_CONFIRMHOTKEY = 0x00000008;    private const uint TKF_HOTKEYACTIVE = 0x00000004;    private const uint FKF_CONFIRMHOTKEY = 0x00000008;    private const uint FKF_HOTKEYACTIVE = 0x00000004;    [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Auto )]    public struct SKEY    {        public uint cbSize;        public uint dwFlags;    }    [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Auto )]    public struct FILTERKEY    {        public uint cbSize;        public uint dwFlags;        public uint iWaitMSec;        public uint iDelayMSec;        public uint iRepeatMSec;        public uint iBounceMSec;    }    private static uint SKEYSize = sizeof( uint ) * 2;    private static uint FKEYSize = sizeof( uint ) * 6;    public static void ToggleAccessibilityShortcutKeys( bool ReturnToStarting )    {        if ( !StartupAccessibilitySet )        {            StartupStickyKeys.cbSize = Configuration.SKEYSize;            StartupToggleKeys.cbSize = Configuration.SKEYSize;            StartupFilterKeys.cbSize = Configuration.FKEYSize;            SystemParametersInfo( SPI_GETSTICKYKEYS, SKEYSize, ref StartupStickyKeys, 0 );            SystemParametersInfo( SPI_GETTOGGLEKEYS, SKEYSize, ref StartupToggleKeys, 0 );            SystemParametersInfo( SPI_GETFILTERKEYS, FKEYSize, ref StartupFilterKeys, 0 );            StartupAccessibilitySet = true;        }        if ( ReturnToStarting )        {            // Restore StickyKeys/etc to original state and enable Windows key            SystemParametersInfo( SPI_SETSTICKYKEYS, SKEYSize, ref StartupStickyKeys, 0 );            SystemParametersInfo( SPI_SETTOGGLEKEYS, SKEYSize, ref StartupToggleKeys, 0 );            SystemParametersInfo( SPI_SETFILTERKEYS, FKEYSize, ref StartupFilterKeys, 0 );        }        else        {            // Disable StickyKeys/etc shortcuts but if the accessibility feature is on,             // then leave the settings alone as its probably being usefully used            SKEY skOff = StartupStickyKeys;            //if ( ( skOff & SKF_STICKYKEYSON ) == 0 )            {                // Disable the hotkey and the confirmation                skOff.dwFlags &= ~SKF_HOTKEYACTIVE;                skOff.dwFlags &= ~SKF_CONFIRMHOTKEY;                SystemParametersInfo( SPI_SETSTICKYKEYS, SKEYSize, ref skOff, 0 );            }            SKEY tkOff = StartupToggleKeys;            //if ( ( tkOff & TKF_TOGGLEKEYSON ) == 0 )            {                // Disable the hotkey and the confirmation                tkOff.dwFlags &= ~TKF_HOTKEYACTIVE;                tkOff.dwFlags &= ~TKF_CONFIRMHOTKEY;                rs = SystemParametersInfo( SPI_SETTOGGLEKEYS, SKEYSize, ref tkOff, 0 );            }            FILTERKEY fkOff = StartupFilterKeys;            //if ( ( fkOff & FKF_FILTERKEYSON ) == 0 )            {                // Disable the hotkey and the confirmation                fkOff.dwFlags &= ~FKF_HOTKEYACTIVE;                fkOff.dwFlags &= ~FKF_CONFIRMHOTKEY;                SystemParametersInfo( SPI_SETFILTERKEYS, FKEYSize, ref fkOff, 0 );            }        }    }

Do note that I was unable to convert three of the IF statements from C++ (those are commented out). Microsoft recommends those, but I don't know a way to make them work in C#. Additionally, I'm not using sizeof() on the structs (instead manually creating variables for their size), because to do that would require unsafe code, and I don't want that to be a requirement for my particular program.


Thanks guys with some minor finishing off that worked in my XNA game to prevent the sticky key popup.

Here is the finished code:

using System;using System.Diagnostics;using System.Collections.Generic;using Microsoft.Xna.Framework;using System.Runtime.InteropServices; namespace Engine{#if WINDOWS    /// <summary>    /// Helper for Windows to temporarily disable the popup caused by the     /// Accessibility features.    /// See: http://stackoverflow.com/questions/734618/disabling-accessibility-shortcuts-in-net-application    /// and: http://msdn.microsoft.com/en-us/library/ee416808(v=vs.85).aspx    /// </summary>    public class WindowsHelperAccessibilityKeys    {        [DllImport("user32.dll", EntryPoint = "SystemParametersInfo", SetLastError = false)]        private static extern bool SystemParametersInfo(uint action, uint param,            ref SKEY vparam, uint init);        [DllImport("user32.dll", EntryPoint = "SystemParametersInfo", SetLastError = false)]        private static extern bool SystemParametersInfo(uint action, uint param,            ref FILTERKEY vparam, uint init);        private const uint SPI_GETFILTERKEYS = 0x0032;        private const uint SPI_SETFILTERKEYS = 0x0033;        private const uint SPI_GETTOGGLEKEYS = 0x0034;        private const uint SPI_SETTOGGLEKEYS = 0x0035;        private const uint SPI_GETSTICKYKEYS = 0x003A;        private const uint SPI_SETSTICKYKEYS = 0x003B;        private static bool StartupAccessibilitySet = false;        private static SKEY StartupStickyKeys;        private static SKEY StartupToggleKeys;        private static FILTERKEY StartupFilterKeys;        private const uint SKF_STICKYKEYSON = 0x00000001;        private const uint TKF_TOGGLEKEYSON = 0x00000001;        private const uint SKF_CONFIRMHOTKEY = 0x00000008;        private const uint SKF_HOTKEYACTIVE = 0x00000004;        private const uint TKF_CONFIRMHOTKEY = 0x00000008;        private const uint TKF_HOTKEYACTIVE = 0x00000004;        private const uint FKF_CONFIRMHOTKEY = 0x00000008;        private const uint FKF_HOTKEYACTIVE = 0x00000004;        private const uint FKF_FILTERKEYSON = 0x00000001;        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]        public struct SKEY        {            public uint cbSize;            public uint dwFlags;        }        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]        public struct FILTERKEY        {            public uint cbSize;            public uint dwFlags;            public uint iWaitMSec;            public uint iDelayMSec;            public uint iRepeatMSec;            public uint iBounceMSec;        }        private static uint SKEYSize = sizeof(uint) * 2;        private static uint FKEYSize = sizeof(uint) * 6;        /// <summary>        /// False to stop the sticky keys popup.        /// True to return to whatever the system has been set to.        /// </summary>        public static void AllowAccessibilityShortcutKeys(bool bAllowKeys)        {            if (!StartupAccessibilitySet)            {                StartupStickyKeys.cbSize = SKEYSize;                StartupToggleKeys.cbSize = SKEYSize;                StartupFilterKeys.cbSize = FKEYSize;                SystemParametersInfo(SPI_GETSTICKYKEYS, SKEYSize, ref StartupStickyKeys, 0);                SystemParametersInfo(SPI_GETTOGGLEKEYS, SKEYSize, ref StartupToggleKeys, 0);                SystemParametersInfo(SPI_GETFILTERKEYS, FKEYSize, ref StartupFilterKeys, 0);                StartupAccessibilitySet = true;            }            if (bAllowKeys)            {                // Restore StickyKeys/etc to original state and enable Windows key                 SystemParametersInfo(SPI_SETSTICKYKEYS, SKEYSize, ref StartupStickyKeys, 0);                SystemParametersInfo(SPI_SETTOGGLEKEYS, SKEYSize, ref StartupToggleKeys, 0);                SystemParametersInfo(SPI_SETFILTERKEYS, FKEYSize, ref StartupFilterKeys, 0);            }            else            {                // Disable StickyKeys/etc shortcuts but if the accessibility feature is on,                  // then leave the settings alone as its probably being usefully used                 SKEY skOff = StartupStickyKeys;                if ( ( skOff.dwFlags & SKF_STICKYKEYSON ) == 0 )                 {                    // Disable the hotkey and the confirmation                     skOff.dwFlags &= ~SKF_HOTKEYACTIVE;                    skOff.dwFlags &= ~SKF_CONFIRMHOTKEY;                    SystemParametersInfo(SPI_SETSTICKYKEYS, SKEYSize, ref skOff, 0);                }                SKEY tkOff = StartupToggleKeys;                if ( ( tkOff.dwFlags & TKF_TOGGLEKEYSON ) == 0 )                 {                    // Disable the hotkey and the confirmation                     tkOff.dwFlags &= ~TKF_HOTKEYACTIVE;                    tkOff.dwFlags &= ~TKF_CONFIRMHOTKEY;                    SystemParametersInfo(SPI_SETTOGGLEKEYS, SKEYSize, ref tkOff, 0);                }                FILTERKEY fkOff = StartupFilterKeys;                if ( ( fkOff.dwFlags & FKF_FILTERKEYSON ) == 0 )                 {                    // Disable the hotkey and the confirmation                     fkOff.dwFlags &= ~FKF_HOTKEYACTIVE;                    fkOff.dwFlags &= ~FKF_CONFIRMHOTKEY;                    SystemParametersInfo(SPI_SETFILTERKEYS, FKEYSize, ref fkOff, 0);                }            }        }     }#endif}

I use it at the start of the game with the parameter set to false and just before the game exits with the parameter set to true:

    /// <summary>    /// This is the preferred way to return to the operating system.    /// </summary>    public void ExitAndTidyUP()    {#if WINDOWS        WindowsHelperAccessibilityKeys.AllowAccessibilityShortcutKeys(true);#endif        Exit();    }

It works perfectly as far as I can tell.

Regards


You will have to do the same thing that is done in the link you reference. The SystemParametersInfo API function can be called through the P/Invoke layer and you can find the definition here:

http://www.pinvoke.net/default.aspx/user32/SystemParametersInfo.html