共用方式為


在遊戲中停用快速鍵

本文說明如何在 Microsoft Windows 中暫時停用鍵盤快速鍵,以防止全螢幕遊戲的遊戲中斷。 SHIFT鍵和CTRL鍵通常用於遊戲中的引發或執行按鈕。 如果使用者不小心按下 Windows 鍵 (位於這些按鍵附近) ,他們可能會導致自己突然跳出應用程式,這會破壞遊戲體驗。 只要使用 SHIFT 鍵做為遊戲按鈕,就可以不小心執行可顯示警告對話方塊的 StickyKeys 快捷方式。 若要避免這些問題,您應該在全螢幕模式中執行時停用這些金鑰,並在視窗模式中執行或結束應用程式時,啟用金鑰回到其預設處理常式。

本文說明如何執行下列動作:

使用鍵盤勾點停用 Windows 鍵

使用低階鍵盤勾點來篩選出正在處理的 Windows 按鍵。 範例 1 所示的低階鍵盤勾點仍然有效,即使使用者最小化視窗或切換至另一個應用程式也一樣。 這表示您必須小心,以確保應用程式停用時不會停用 Windows 金鑰。 範例 1 中的程式碼會藉由處理WM_ACTI加值稅EAPP訊息來執行此動作。

注意

此方法適用于 Windows 2000 和更新版本的 Windows。 此方法也適用于最低許可權使用者帳戶, (也稱為標準使用者帳戶) 。

 

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 是專為難以同時按住兩個或多個金鑰的人員所設計。 所有這些協助工具功能也有一個鍵盤快速鍵,可讓功能開啟或關閉。 例如,StickyKeys 快捷方式會按下 SHIFT 鍵五次來觸發。 如果遊戲也使用 SHIFT 鍵,使用者可能會在遊戲期間意外觸發此快捷方式。 觸發快捷方式時,Windows (預設) 會在對話方塊中顯示警告,這會導致 Windows 將全螢幕模式中執行的遊戲降到最低。 當然,這可能會影響遊戲遊戲。

某些客戶需要協助工具功能,而且本身不會干擾全螢幕遊戲;因此,您不應該變更協助工具設定。 不過,由於協助工具快捷方式會在意外觸發時中斷遊戲遊戲,因此只有在呼叫 SystemParametersInfo未啟用該功能時,才應該關閉協助工具快捷方式。

SystemParametersInfo關閉的協助工具快捷方式仍會保持關閉,即使應用程式結束也一直關閉。 這表示您必須在結束應用程式之前還原設定。 因為應用程式無法正確結束,所以您應該將這些設定寫入持續性儲存體,以便在應用程式再次執行時還原這些設定。 如果發生當機,您也可以使用例外狀況處理常式來還原這些設定。

關閉這些快捷方式

  1. 先擷取目前的協助工具設定,再加以停用。
  2. 如果協助工具功能關閉,當應用程式進入全螢幕模式時,請停用協助工具快捷方式。
  3. 當應用程式進入視窗模式或結束時,還原協助工具設定。

這個方法用於 DXUT,並在下列程式碼範例中說明。

注意

此方法可在標準使用者帳戶上執行時運作。

 

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