c # - Deaktivering af genvejsgenveje i .NET-applikation?

Indlæg af Hanne Mølgaard Plasc

Problem



Denne msdn-artikel - http://msdn.microsoft.com/en-us/library/bb219746(VS.85).aspx#Disabling\_Accessibility\_Shortcut\_Keys - giver oplysninger til C ++-programmører om, hvordan du midlertidigt deaktiverer Windows-genveje for tilgængelighed (f.eks. som at holde Shift i 8 sekunder eller trykke Shift mere end 5 gange i hurtig rækkefølge). [5]


Sikkert er der en nem måde at gøre dette i C #, men jeg kan ikke finde nogen ressourcer på dette. Jeg bruger DirectInput i en ikke-fuldskærms applikation.


Alt jeg vil gøre er ikke at få de irriterende popups komme op; Jeg foretrækker noget, der ikke behøver at gnide med Windows-indstillingerne, men bare hvis applikationen lukkes på en ikke-grasiøs måde (jeg foretrækker ikke at ændre brugerens indstillinger permanent i disse situationer).


nogen tanker?

Bedste reference


Du bliver nødt til at gøre det samme som i det link, du refererer til. SystemParametersInfo API-funktionen kan kaldes gennem P/Invoke-laget, og du kan finde definitionen her:


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

Andre referencer 1


Bare hvis nogen andre har brug for dette, her er den konverterede C # kode, som til sidst virker:


    [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 );
            }
        }
    }


Bemærk, at jeg ikke kunne konvertere tre af IF-udsagnene fra C ++ (de kommenteres). Microsoft anbefaler dem, men jeg ved ikke en måde at få dem til at arbejde i C #. Desuden bruger jeg ikke sizeof () på strukturerne (i stedet manuelt oprette variabler for deres størrelse), fordi det ville kræve en usikker kode , og det ønsker jeg ikke at være et krav til mit særlige program.

Andre referencer 2


Tak fyrene med lidt mindre færdigbehandling, der fungerede i mit XNA-spil for at forhindre klæbrig nøgle popup.


Her er den færdige kode:


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
}


Jeg bruger det ved starten af ​​spillet med parameteren sat til falsk og lige før spillet forlader med parameteren sat til true:


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


Det virker perfekt så vidt jeg kan fortælle.


Hilsen

Andre referencer 3


Bemærk i forhold til C # -koden ovenfor:
Du kan konvertere disse problem linjer ved AND-ing med flag-feltet i strukturen som sådan:
hvis ((skOff.dwFlags &SKF\_STICKYKEYSON) == 0)
Du skal tilføje linjen:
privat konstant FKF\_FILTERKEYSON=0x00000001;
også under definitionerne.

Andre referencer 4


Du kan se dette også C #


using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1 {
  public partial class Form1 : Form {
    private const int MYKEYID = 0;    // In case you want to register more than one...
    public Form1() {
      InitializeComponent();
      RegisterHotKey(this.Handle, MYKEYID, MOD\_ALT, Keys.Tab);
      this.FormClosing += Form1\_FormClosing;
    }
    private void Form1\_FormClosing(object sender, FormClosingEventArgs e) {
      UnregisterHotKey(this.Handle, MYKEYID);
    }
    protected override void WndProc(ref Message m) {
      if (m.Msg == WM\_HOTKEY && m.WParam.ToInt32() == MYKEYID) {
        Console.Beep();
      }
      base.WndProc(ref m);
    }
    // P/Invoke declarations
    private const int WM\_HOTKEY = 0x312;
    private const int MOD\_ALT = 1;
    private const int MOD\_CONTROL = 2;
    private const int MOD\_SHIFT = 4;
    [DllImport("user32.dll")]
    private static extern int RegisterHotKey(IntPtr hWnd, int id, int modifier, Keys vk);
    [DllImport("user32.dll")]
    private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
  }
}


fundet det her
http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/47647b7e-b23f-4f80-9363-ffd5f11a2570[7]


Skål