Condividi tramite


Disabilitazione dei tasti di scelta rapida nei giochi

Questo articolo descrive come disabilitare temporaneamente i tasti di scelta rapida in Microsoft Windows per evitare interruzioni del gioco per i giochi a schermo intero. Il tasto MAIUSC e il tasto CTRL vengono spesso usati come pulsanti di attivazione o esecuzione nei giochi. Se gli utenti preme accidentalmente il tasto Windows (situato vicino a questi tasti), possono causare improvvisamente saltare fuori dall'applicazione, che rovina l'esperienza di gioco. È sufficiente usare il tasto MAIUSC come pulsante di gioco per eseguire inavvertitamente il collegamento StickyKeys che può visualizzare una finestra di dialogo di avviso. Per evitare questi problemi, è consigliabile disabilitare queste chiavi durante l'esecuzione in modalità schermo intero e abilitare di nuovo le chiavi ai gestori predefiniti durante l'esecuzione in modalità finestra o uscire dall'applicazione.

Questo articolo descrive come eseguire le operazioni seguenti:

Disabilitare il tasto Windows con un gancio da tastiera

Usa un gancio da tastiera di basso livello per escludere il tasto Windows dall'elaborazione. Il gancio da tastiera di basso livello mostrato nell'esempio 1 rimane attivo anche se un utente riduce al minimo la finestra o passa a un'altra applicazione. Ciò significa che è necessario prestare attenzione per assicurarsi che la chiave di Windows non sia disabilitata quando l'applicazione viene disattivata. Il codice nell'esempio 1 esegue questa operazione gestendo il messaggio WM_ACTIVATEAPP.

Nota

Questo metodo funziona in Windows 2000 e versioni successive di Windows. Questo metodo funziona anche con gli account utente con privilegi minimi (noti anche come account utente standard).

 

Questo metodo viene usato da DXUT ed è illustrato nell'esempio di codice seguente.

Esempio 1. Uso di un gancio da tastiera di basso livello per disabilitare il tasto Windows

HHOOK g_hKeyboardHook = nullptr;
bool g_bWindowActive = false;
bool g_bFullscreen;
 
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
    // Initialization
    g_hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(nullptr), 0 );
 
    // 
    // main application code here
    // 
 
    // Cleanup before shutdown
    UnhookWindowsHookEx( g_hKeyboardHook );
    g_hKeyboardHook = nullptr;
    
    return 0;
}
 
 
LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam )
{
    if (nCode < 0 || nCode != HC_ACTION )  // do not process message 
        return CallNextHookEx( g_hKeyboardHook, nCode, wParam, lParam); 
 
    bool bEatKeystroke = false;
    auto p = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
    switch (wParam) 
    {
        case WM_KEYDOWN:  
        case WM_KEYUP:    
        {
            bEatKeystroke = (g_bFullscreen && g_bWindowActive && ((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN)));
            // Note that this will not block the Xbox Game Bar hotkeys (Win+G, Win+Alt+R, etc.)
            break;
        }
    }
 
    if( bEatKeystroke )
        return 1;
    else
        return CallNextHookEx( g_hKeyboardHook, nCode, wParam, lParam );
}
 
 
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    switch( uMsg )
    {
       case WM_ACTIVATEAPP:
            // g_bWindowActive is used to control if the Windows key is filtered by the keyboard hook or not.
            if( wParam )
                g_bWindowActive = true;           
            else 
                g_bWindowActive = false;           
            break;
            
        case WM_SYSKEYDOWN:
            if (wParam == VK_RETURN && (lParam & 0x60000000) == 0x20000000)
            {
                // Implement the classic ALT+ENTER fullscreen toggle
             ...
                // g_bFullscreen is used to control if the Windows key is filtered by the keyboard hook or not.
                g_bFullscreen = !g_bFullscreen;                
                
                // Remember to use DXGI_MWA_NO_ALT_ENTER when you call the DXGI method MakeWindowAssociation
                // so you control the fullscreen toggling in your application.
            }
            break;
    }
}

Disabilitare i tasti di scelta rapida per l'accessibilità

Windows include funzionalità di accessibilità come StickyKeys, FilterKeys e ToggleKeys (vedere Accessibilità di Windows). Ognuno di questi serve uno scopo diverso; StickyKeys, ad esempio, è progettato per le persone che hanno difficoltà a tenere premuto due o più chiavi contemporaneamente. Ognuna di queste funzionalità di accessibilità include anche una scelta rapida da tastiera che consente di attivare o disattivare la funzionalità. Ad esempio, il tasto di scelta rapida StickyKeys viene attivato premendo MAIUSC cinque volte. Se il tasto MAIUSC viene usato anche nel gioco, l'utente potrebbe attivare accidentalmente questo collegamento durante la riproduzione del gioco. Quando il collegamento viene attivato, Windows (per impostazione predefinita) visualizza un avviso in una finestra di dialogo, in modo che Windows riduca al minimo un gioco in esecuzione in modalità schermo intero. Questo, naturalmente, può avere un effetto drastico sul gioco.

Le funzionalità di accessibilità sono necessarie per alcuni clienti e non interferiscono con i giochi a schermo intero; pertanto, non è consigliabile modificare le impostazioni di accessibilità. Tuttavia, poiché i tasti di scelta rapida per le funzionalità di accessibilità possono interrompere la riproduzione del gioco se attivato accidentalmente, è consigliabile disattivare un collegamento di accessibilità solo quando tale funzionalità non è abilitata chiamando SystemParametersInfo.

Un collegamento di accessibilità disattivato da SystemParametersInfo rimane disattivato anche dopo l'uscita dell'applicazione. Ciò significa che è necessario ripristinare le impostazioni prima di uscire dall'applicazione. Poiché è possibile che l'applicazione non venga chiusa correttamente, è necessario scrivere queste impostazioni nell'archiviazione permanente in modo che possano essere ripristinate quando l'applicazione viene eseguita di nuovo. È anche possibile usare un gestore eccezioni per ripristinare queste impostazioni in caso di arresto anomalo del sistema.

Per disattivare questi tasti di scelta rapida

  1. Acquisire le impostazioni di accessibilità correnti prima di disabilitarle.
  2. Disabilitare il collegamento di accessibilità quando l'applicazione passa alla modalità schermo intero se la funzionalità di accessibilità è disattivata.
  3. Ripristinare le impostazioni di accessibilità quando l'applicazione passa alla modalità finestra o si chiude.

Questo metodo viene usato in DXUT ed è illustrato nell'esempio di codice seguente.

Nota

Questo metodo funziona quando viene eseguito su un account utente standard.

 

Esempio 2. Disabilitazione dei tasti di scelta rapida per l'accessibilità

STICKYKEYS g_StartupStickyKeys = {sizeof(STICKYKEYS), 0};
TOGGLEKEYS g_StartupToggleKeys = {sizeof(TOGGLEKEYS), 0};
FILTERKEYS g_StartupFilterKeys = {sizeof(FILTERKEYS), 0};    
 
 
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
    // Save the current sticky/toggle/filter key settings so they can be restored them later
    SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), &g_StartupStickyKeys, 0);
    SystemParametersInfo(SPI_GETTOGGLEKEYS, sizeof(TOGGLEKEYS), &g_StartupToggleKeys, 0);
    SystemParametersInfo(SPI_GETFILTERKEYS, sizeof(FILTERKEYS), &g_StartupFilterKeys, 0);
 
 ...
 
    // Disable when full screen
    AllowAccessibilityShortcutKeys( false );
 
 ...
 
    // Restore back when going to windowed or shutting down
    AllowAccessibilityShortcutKeys( true );
}
 
 
void AllowAccessibilityShortcutKeys( bool bAllowKeys )
{
    if( bAllowKeys )
    {
        // Restore StickyKeys/etc to original state and enable Windows key      
        STICKYKEYS sk = g_StartupStickyKeys;
        TOGGLEKEYS tk = g_StartupToggleKeys;
        FILTERKEYS fk = g_StartupFilterKeys;
        
        SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &g_StartupStickyKeys, 0);
        SystemParametersInfo(SPI_SETTOGGLEKEYS, sizeof(TOGGLEKEYS), &g_StartupToggleKeys, 0);
        SystemParametersInfo(SPI_SETFILTERKEYS, sizeof(FILTERKEYS), &g_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
 
        STICKYKEYS skOff = g_StartupStickyKeys;
        if( (skOff.dwFlags & SKF_STICKYKEYSON) == 0 )
        {
            // Disable the hotkey and the confirmation
            skOff.dwFlags &= ~SKF_HOTKEYACTIVE;
            skOff.dwFlags &= ~SKF_CONFIRMHOTKEY;
 
            SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &skOff, 0);
        }
 
        TOGGLEKEYS tkOff = g_StartupToggleKeys;
        if( (tkOff.dwFlags & TKF_TOGGLEKEYSON) == 0 )
        {
            // Disable the hotkey and the confirmation
            tkOff.dwFlags &= ~TKF_HOTKEYACTIVE;
            tkOff.dwFlags &= ~TKF_CONFIRMHOTKEY;
 
            SystemParametersInfo(SPI_SETTOGGLEKEYS, sizeof(TOGGLEKEYS), &tkOff, 0);
        }
 
        FILTERKEYS fkOff = g_StartupFilterKeys;
        if( (fkOff.dwFlags & FKF_FILTERKEYSON) == 0 )
        {
            // Disable the hotkey and the confirmation
            fkOff.dwFlags &= ~FKF_HOTKEYACTIVE;
            fkOff.dwFlags &= ~FKF_CONFIRMHOTKEY;
 
            SystemParametersInfo(SPI_SETFILTERKEYS, sizeof(FILTERKEYS), &fkOff, 0);
        }
    }
}