전체 화면으로 게임을 하거나, 작업 중에 "Win 키"가 눌리면서 화면이 아래로 내려가서 방해가 되는 경우가 있습니다.
이를 방지하기 위한 게임 및 애플리케이션 개발 시 사용할 수 있는 소스를 공개합니다.
아래의 소스는 Windows hook이라는 기술을 이용한 방법입니다.
(Hook 이란 "가로채기"라는 뜻으로써, 시스템에 전달되는 이벤트를 먼저 가로채는 기술입니다.
보통은 가로챈 이벤트의 처리가 끝나면 반드시 CallNextHookEx함수를 호출하여 시스템에 전달 될 수 있도록 해야합니다.)
핵심 소스 부분
아래와 같이 "왼쪽 Windows 키"나 "오른쪽 Windows 키"가 눌린 경우 "CallNextHookEx(...)"함수를 호출하여 시스템으로 넘겨 해당 키에 대한 이벤트 처리를 하도록 넘기지 않고, "return 1;"로 처리함으로 써 처리를 못 하도록 하는 것입니다.
switch (wParam)
{
case WM_KEYDOWN:
case WM_KEYUP:
{
bEatKeystroke = (g_bFullscreen && g_bWindowActive && ((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN)));
break;
}
}
if( bEatKeystroke )
return 1;
return CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam);
전체 소스
윈도우 키 눌림 방지를 위한 전체 소스와 주석입니다.
HHOOK g_hKeyboardHook = nullptr;
bool g_bWindowActive = false; // 애플리케이션 활성화 여부
bool g_bFullscreen = false; // full screen 여부
// main 함수
INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
// 키 훅 초기화
g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(nullptr), 0);
//
// 사용자 소스 부분...
//
// 키 훅 종료
UnhookWindowsHookEx(g_hKeyboardHook);
g_hKeyboardHook = nullptr;
return 0;
}
// 키 훅 프로시저 함수
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// 키 이벤트와 관련 없는 경우 바로 시스템으로 넘김
if (nCode < 0 || nCode != HC_ACTION)
return CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam);
bool bEatKeystroke = false;
auto p = reinterpret_cast<KBDLLHOOKSTRUCT *>(lParam);
switch (wParam)
{
case WM_KEYDOWN:
case WM_KEYUP:
{
// 왼/오른쪽 윈도우 키가 Down/Up인 경우 플래그 설정
bEatKeystroke = (g_bFullscreen && g_bWindowActive && ((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN)));
break;
}
}
// 키 이벤트를 시스템에 전달하지 않음
if (bEatKeystroke) {
return 1;
}
// 키 이벤트를 시스템에 전달
return CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam);
}
// 윈도우 프로시저 함수
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_ACTIVATEAPP:
// 애플리케이션 활성화 여부 플래그 설정
if (wParam)
g_bWindowActive = true;
else
g_bWindowActive = false;
break;
case WM_SYSKEYDOWN:
// "Alt + Enter"키 조합으로 전체화면모드를 지원하는 경우
// Direct X를 사용하는 경우, DXGI MakeWindowAssociation, DXGI_MWA_NO_ALT_ENTER를 사용해야 함.
if (wParam == VK_RETURN && (lParam & 0x60000000) == 0x20000000)
{
// 전체 화면 여부 플래그 설정
g_bFullscreen = !g_bFullscreen;
}
break;
}
}
반응형
댓글