Share via


ゲームでショートカット キーを無効にする

この記事では、全画面表示ゲームのゲーム の中断を防ぐために、Microsoft Windows でキーボード ショートカットを一時的に無効にする方法について説明します。 Shift キーと Ctrl キーは、多くの場合、ゲームで起動または実行ボタンとして使用されます。 ユーザーが誤って (これらのキーの近くにある) Windows キーを押すと、アプリケーションから突然飛び出し、ゲームエクスペリエンスが損なわれる可能性があります。 Shift キーをゲーム ボタンとして使用するだけで、誤って StickyKeys ショートカットが実行され、警告ダイアログが表示されることがあります。 これらの問題を回避するには、全画面表示モードで実行するときにこれらのキーを無効にし、ウィンドウ モードで実行するときにキーを既定のハンドラーに戻すか、アプリケーションを終了する必要があります。

この記事では、次の操作を行う方法について説明します。

キーボード フックを使用して Windows キーを無効にする

Windows キーの処理を除外するには、低レベルのキーボード フックを使用します。 例 1 に示す低レベルのキーボード フックは、ユーザーがウィンドウを最小化したり、別のアプリケーションに切り替えたりしても有効です。 つまり、アプリケーションを非アクティブ化するときに Windows キーが無効にならないように注意する必要があります。 例 1 のコードでは、WM_ACTIVATEAPP メッセージを処理してこれを行います。

Note

このメソッドは、Windows 2000 以降のバージョンの Windows で動作します。 この方法は、最小限の特権を持つユーザー アカウント (Standard ユーザー アカウントとも呼ばれます) でも機能します。

 

このメソッドは DXUT で使用され、次のコード例に示されています。

例 1. 低レベルのキーボード フックを使用して 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;
    }
}

アクセシビリティ ショートカット キーを無効にする

Windows には、StickyKeys、FilterKeys、ToggleKeys などのアクセシビリティ機能が含まれています ( 「Windows アクセシビリティ」を参照)。 これらはそれぞれ異なる目的を果たします。StickyKeys は、2 つ以上のキーを同時に押し続けるのが困難なユーザー向けに設計されています。 これらの各アクセシビリティ機能には、機能のオンとオフを切り替えるキーボード ショートカットもあります。 たとえば、 Shift キーを 5 回押すと、StickyKeys ショートカットがトリガーされます。 Shift キーがゲームでも使用されている場合、ユーザーはゲームのプレイ中に誤ってこのショートカットをトリガーする可能性があります。 ショートカットがトリガーされると、Windows (既定) はダイアログ ボックスに警告を表示します。これにより、Windows は全画面表示モードで実行されているゲームを最小限に抑えます。 これはもちろん、ゲームプレイに大きな影響を与える可能性があります。

アクセシビリティ機能は、一部のお客様に必要であり、それ自体が全画面表示ゲームに干渉することはありません。そのため、アクセシビリティ設定を変更しないでください。 ただし、アクセシビリティ機能のショートカットは、誤ってトリガーされた場合にゲームプレイを中断する可能性があるため、 SystemParametersInfo を呼び出して、その機能が有効になっていない場合にのみ、アクセシビリティ ショートカットをオフにする必要があります。

SystemParametersInfo によってオフになっているアクセシビリティ ショートカットは、アプリケーションが終了した後でもオフのままです。 つまり、アプリケーションを終了する前に設定を復元する必要があります。 アプリケーションが正しく終了しない可能性があるため、アプリケーションを再度実行したときに復元できるように、これらの設定を永続ストレージに書き込む必要があります。 クラッシュが発生した場合は、例外ハンドラーを使用してこれらの設定を復元することもできます。

これらのショートカットをオフにするには

  1. 無効にする前に、現在のアクセシビリティ設定をキャプチャします。
  2. アクセシビリティ機能がオフの場合、アプリケーションが全画面表示モードになったときにアクセシビリティ ショートカットを無効にします。
  3. アプリケーションがウィンドウ モードになったり終了したりしたときに、アクセシビリティ設定を復元します。

このメソッドは DXUT で使用され、次のコード例に示されています。

Note

このメソッドは、Standard ユーザー アカウントで実行する場合に機能します。

 

例 2. アクセシビリティ ショートカット キーを無効にする

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