2009-04-09 25 views
7

Este artículo msdn - http://msdn.microsoft.com/en-us/library/bb219746(VS.85).aspx#Disabling_Accessibility_Shortcut_Keys - proporciona información para los programadores de C++ sobre cómo deshabilitar temporalmente los accesos directos de Windows para la accesibilidad (como mantener presionada la tecla Mayús durante 8 segundos o presionar Mayús más de 5 veces en sucesión rápida).¿Deshabilitar accesos directos de accesibilidad en la aplicación .NET?

Seguramente hay una manera fácil de hacer esto en C#, pero no puedo encontrar ningún recurso en esto. Estoy usando DirectInput en una aplicación que no es de pantalla completa.

Todo lo que quiero hacer es que no aparezcan las molestas ventanas emergentes; Sin embargo, preferiría algo que no tenga que ensuciar con la configuración de Windows, en caso de que la aplicación se cierre de una manera no elegante (preferiría no tener la configuración del usuario alterada permanentemente en esas situaciones) .

¿Alguna idea?

Respuesta

2

Deberá hacer lo mismo que se hace en el enlace al que hace referencia. La función de la API SystemParametersInfo se puede llamar a través de la P/Invoke capa y se puede encontrar la definición aquí:

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

+0

Bien ... Esperaba algo no permanente, pero esto también está bien. ¡Gracias! – x4000

+0

@ x4000: su pregunta dice que muestra cómo deshabilitar temporalmente las teclas de método abreviado. Es la misma API que se llama, por lo que solo tiene que estructurar el código de la misma manera y también debe ser no permanente. – casperOne

+0

Bueno, supongo que me equivoqué: le muestran cómo apagarlo y volver a encenderlo, con la expectativa de que lo vuelva a encender cuando haya terminado. Eso está muy bien hasta que la aplicación falla. – x4000

6

Sólo en caso de cualquier otra persona necesita esto, aquí está el código C#, que mantiene al fin funciona:

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

Tenga en cuenta que no he podido convertir tres de las declaraciones IF de C++ (están comentadas). Microsoft los recomienda, pero no sé cómo hacer que funcionen en C#. Además, no estoy usando sizeof() en las estructuras (en lugar de crear manualmente variables para su tamaño), porque para hacerlo requeriría un código inseguro, y no quiero que sea un requisito para mi programa en particular.

0

Usted puede mirar esto también 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); 
    } 
} 

encontramos aquí http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/47647b7e-b23f-4f80-9363-ffd5f11a2570

aplausos

2

Nota en relación con el código C# Enviado arriba: Puede convertir esas líneas de problemas de Y -ing con el campo de banderas de la estructura como lo siguiente: if ((skOff.dwFlags & SKF_STICKYKEYSON) == 0) You ' Necesitaré agregar la línea: const. privada FKF_FILTERKEYSON = 0x00000001; bajo las definiciones de const también.

5

Gracias chicos con algunos pequeños retoques que funcionaron en mi juego XNA para evitar el emergente de la tecla adhesiva.

Este es el código final:

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 
} 

lo uso en el inicio del juego con el parámetro establecido en false y justo antes de las salidas de juego con el parámetro establecido en true:

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

Funciona perfectamente hasta donde yo sé.

Saludos

Cuestiones relacionadas