2009-04-09 10 views
7

Questo articolo di msdn - http://msdn.microsoft.com/en-us/library/bb219746(VS.85).aspx#Disabling_Accessibility_Shortcut_Keys - fornisce informazioni ai programmatori C++ su come disabilitare temporaneamente i collegamenti di Windows per l'accessibilità (come tenere premuto Shift per 8 secondi o premere Maiusc più di 5 volte in rapida successione).Disabilitare i collegamenti all'accessibilità nell'applicazione .NET?

Sicuramente c'è un modo semplice per farlo in C#, ma non riesco a trovare risorse su questo. Sto usando DirectInput in un'applicazione non a schermo intero.

Tutto quello che voglio fare è non avere i fastidiosi popup in arrivo; Preferirei qualcosa che non ha a che fare con le impostazioni di Windows, nel caso in cui l'applicazione si arresti in modo non aggraziato (preferirei che le impostazioni dell'utente non vengano modificate permanentemente in quelle situazioni) .

Qualche idea?

risposta

2

Dovrai fare la stessa cosa nel collegamento a cui fai riferimento. La funzione API SystemParametersInfo può essere richiamata attraverso il P/Invoke livello e si può trovare la definizione qui:

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

+0

Okay ... speravo in qualcosa di non permanente, ma anche questo è buono. Grazie! – x4000

+0

@ x4000: la tua domanda dice che mostra come disabilitare temporaneamente i tasti di scelta rapida. Viene chiamata la stessa API, quindi devi solo strutturare il codice allo stesso modo e dovrebbe anche essere non permanente. – casperOne

+0

Beh, immagino di aver misspoke - ti mostrano come spegnerlo e riaccenderlo, aspettandoti di riaccenderlo quando hai finito. Va tutto bene finché l'applicazione non si blocca. – x4000

6

Solo nel caso qualcuno altro ha bisogno di questo, ecco il codice C# convertito, che finalmente funziona:

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

Si noti che non sono riuscito a convertire tre delle istruzioni IF da C++ (quelle sono commentate). Microsoft consiglia quelli, ma non conosco un modo per farli funzionare in C#. Inoltre, non sto usando sizeof() sulle structs (invece di creare manualmente variabili per le loro dimensioni), perché farlo richiede un codice non sicuro, e non voglio che sia un requisito per il mio particolare programma.

0

Si può guardare anche questo 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); 
    } 
} 

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

applausi

2

nota in relazione al codice C# postato sopra: È possibile convertire quelle linee problema E -ing con il campo flags della struct in questo modo: if ((skOff.dwFlags & SKF_STICKYKEYSON) == 0) You ' È necessario aggiungere la riga: private const uint FKF_FILTERKEYSON = 0x00000001; anche sotto le definizioni const.

5

Grazie ragazzi con alcune rifiniture secondarie che hanno funzionato nel mio gioco XNA per impedire la comparsa di popup.

ecco il codice finale:

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 
} 

Io lo uso al inizio del gioco con il parametro impostato su false e poco prima le uscite di gioco con il parametro impostato su true:

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

Funziona perfettamente per quanto posso dire.

Saluti

Problemi correlati