Deaktivieren von Tastenkombinationen in Spielen

In diesem Artikel wird beschrieben, wie Sie Tastenkombinationen in Microsoft Windows vorübergehend deaktivieren, um Unterbrechungen des Spiels für Vollbildspiele zu verhindern. Die UMSCHALTTASTE und die STRG-TASTE werden häufig als Feuer- oder Ausführungsschaltflächen in Spielen verwendet. Wenn Benutzer versehentlich die Windows-Taste drücken (in der Nähe dieser Tasten), können sie dazu führen, dass sie plötzlich aus der Anwendung springen, was die Spielerfahrung ruiniert. Wenn Sie einfach die UMSCHALTTASTE als Spielschaltfläche verwenden, können Sie versehentlich die Tastenkombination StickyKeys ausführen, die möglicherweise ein Warndialogfeld anzeigt. Um diese Probleme zu vermeiden, sollten Sie diese Schlüssel deaktivieren, wenn Sie im Vollbildmodus ausgeführt werden, und entweder die Schlüssel wieder zu ihren Standardhandlern aktivieren, wenn sie im Fenstermodus ausgeführt werden, oder die Anwendung beenden.

In diesem Artikel wird beschrieben, wie Sie die folgenden Schritte ausführen:

Deaktivieren der Windows-Taste mit einem Tastaturhaken

Verwenden Sie einen Tastaturhaken auf niedriger Ebene, um die Windows-Taste vor der Verarbeitung herauszufiltern. Der in Beispiel 1 gezeigte Tastaturhaken auf niedriger Ebene bleibt auch dann wirksam, wenn ein Benutzer das Fenster minimiert oder zu einer anderen Anwendung wechselt. Dies bedeutet, dass Sie darauf achten müssen, dass die Windows-Taste nicht deaktiviert wird, wenn die Anwendung deaktiviert wird. Der Code in Beispiel 1 behandelt dazu die WM_ACTIVATEAPP Meldung.

Hinweis

Diese Methode funktioniert unter Windows 2000 und höheren Versionen von Windows. Diese Methode funktioniert auch mit Benutzerkonten mit den geringsten Rechten (auch bekannt als Standardbenutzerkonten).

 

Diese Methode wird von DXUT verwendet und im folgenden Codebeispiel veranschaulicht.

Beispiel 1: Verwenden eines Tastaturhakens auf niedriger Ebene zum Deaktivieren der Windows-Taste

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

Deaktivieren der Tastenkombinationen für die Barrierefreiheit

Windows enthält Barrierefreiheitsfeatures wie StickyKeys, FilterKeys und ToggleKeys (siehe Windows-Barrierefreiheit). Jede dieser Ziele dient einem anderen Zweck; StickyKeys ist beispielsweise für Personen konzipiert, die Schwierigkeiten haben, zwei oder mehr Tasten gleichzeitig gedrückt zu halten. Jedes dieser Barrierefreiheitsfeatures verfügt außerdem über eine Tastenkombination, mit der das Feature aktiviert oder deaktiviert werden kann. Beispielsweise wird die Tastenkombination StickyKeys ausgelöst, indem fünfMal die UMSCHALTTASTE gedrückt wird. Wenn die UMSCHALTTASTE auch im Spiel verwendet wird, kann der Benutzer diese Verknüpfung während des Spiels versehentlich auslösen. Wenn die Verknüpfung ausgelöst wird, zeigt Windows (standardmäßig) eine Warnung in einem Dialogfeld an, die dazu führen würde, dass Windows ein Im Vollbildmodus ausgeführtes Spiel minimiert. Dies kann sich natürlich drastisch auf das Spiel auswirken.

Die Barrierefreiheitsfunktionen sind für einige Kunden erforderlich und beeinträchtigen nicht selbst Vollbildspiele. Daher sollten Sie die Barrierefreiheitseinstellungen nicht ändern. Da die Tastenkombinationen für Barrierefreiheitsfeatures den Spielbetrieb jedoch beeinträchtigen können, wenn sie versehentlich ausgelöst werden, sollten Sie eine Barrierefreiheitsverknüpfung nur deaktivieren, wenn diese Funktion nicht durch aufrufen von SystemParametersInfo aktiviert ist.

Eine Barrierefreiheitsverknüpfung, die von SystemParametersInfo deaktiviert wird, bleibt auch nach dem Beenden der Anwendung deaktiviert. Dies bedeutet, dass Sie die Einstellungen wiederherstellen müssen, bevor Sie die Anwendung beenden. Da es möglich ist, dass die Anwendung nicht ordnungsgemäß beendet wird, sollten Sie diese Einstellungen in den persistenten Speicher schreiben, damit sie wiederhergestellt werden können, wenn die Anwendung erneut ausgeführt wird. Sie können auch einen Ausnahmehandler verwenden, um diese Einstellungen bei einem Absturz wiederherzustellen.

So deaktivieren Sie diese Tastenkombinationen

  1. Erfassen Sie die aktuellen Barrierefreiheitseinstellungen, bevor Sie sie deaktivieren.
  2. Deaktivieren Sie die Barrierefreiheitsverknüpfung, wenn die Anwendung in den Vollbildmodus wechselt, wenn die Barrierefreiheitsfunktion deaktiviert ist.
  3. Stellen Sie die Barrierefreiheitseinstellungen wieder her, wenn die Anwendung in den Fenstermodus wechselt oder beendet wird.

Diese Methode wird in DXUT verwendet und im folgenden Codebeispiel veranschaulicht.

Hinweis

Diese Methode funktioniert, wenn sie in einem Standardbenutzerkonto ausgeführt wird.

 

Beispiel 2: Deaktivieren von Tastenkombinationen für die Barrierefreiheit

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