게임에서 바로 가기 키 비활성화
이 문서에서는 전체 화면 게임에 대한 게임 플레이 중단을 방지하기 위해 Microsoft Windows에서 바로 가기 키를 일시적으로 사용하지 않도록 설정하는 방법을 설명합니다. Shift 키와 Ctrl 키는 게임에서 실행 또는 실행 단추로 자주 사용됩니다. 사용자가 실수로 Windows 키(이러한 키 근처에 있음)를 누르면 애플리케이션에서 갑자기 뛰어내리게 되어 게임 환경이 손상될 수 있습니다. SHIFT 키를 게임 단추로 사용하면 실수로 경고 대화 상자를 표시할 수 있는 StickyKeys 바로 가기를 실행할 수 있습니다. 이러한 문제를 방지하려면 전체 화면 모드에서 실행할 때 이러한 키를 사용하지 않도록 설정하고 창 모드에서 실행할 때 키를 기본 처리기로 다시 사용하도록 설정하거나 애플리케이션을 종료해야 합니다.
이 문서에서는 다음을 수행하는 방법을 설명합니다.
키보드 후크를 사용하여 Windows 키 사용 안 함
하위 수준 키보드 후크를 사용하여 Windows 키가 처리되지 않도록 필터링합니다. 예제 1에 표시된 하위 수준 키보드 후크는 사용자가 창을 최소화하거나 다른 애플리케이션으로 전환하더라도 계속 적용됩니다. 즉, 애플리케이션이 비활성화될 때 Windows 키가 비활성화되지 않도록 주의해야 합니다. 예제 1의 코드는 WM_ACTIVATEAPP 메시지를 처리하여 이 작업을 수행합니다.
참고
이 메서드는 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에서 해제된 접근성 바로 가기는 애플리케이션이 종료된 후에도 꺼져 있습니다. 즉, 애플리케이션을 종료하기 전에 설정을 복원해야 합니다. 애플리케이션이 올바르게 종료되지 않을 수 있으므로 애플리케이션을 다시 실행할 때 복원할 수 있도록 영구 스토리지에 이러한 설정을 작성해야 합니다. 충돌이 발생할 경우 예외 처리기를 사용하여 이러한 설정을 복원할 수도 있습니다.
이러한 바로 가기를 끄려면
- 현재 접근성 설정을 사용하지 않도록 설정하기 전에 캡처합니다.
- 접근성 기능이 꺼져 있는 경우 애플리케이션이 전체 화면 모드로 전환되면 접근성 바로 가기를 사용하지 않도록 설정합니다.
- 애플리케이션이 창 모드로 전환되거나 종료될 때 접근성 설정을 복원합니다.
이 메서드는 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);
}
}
}