GetKeyboardState() 는 Keyboard 관련 Message 를 처리할때마다 업데이트 되는 값을 들고옴.
GetKeyState 는 바로 이 Message 가 처리될 때 마다 호출이 되며 위 함수가 참조하는 값을 업데이트 하기도 함.
GetAsyncKeyState 는 Interupt 차원에서 값을 처리해서 Message 와는 크게 관계가 없음.
int main() { byte keyState[256]; ZeroMemory(keyState, sizeof(byte) * 255); byte pressed = (keyState[KEY_0] & 0x80); while (pressed == false) { ZeroMemory(keyState, sizeof(byte) * 255); //GetKeyState(0); //GetAsyncKeyState(KEY_0); std::cout << GetKeyboardState(keyState) << std::endl; pressed = (keyState[KEY_0] & 0x80); Sleep(10000); }; }
그래서 무한루프를 도는 위 함수는 GetKeyState 가 있는 줄의 주석만 풀면 잘 작동함.
이에 반해 GetAsyncKeyState 로는 작동하지 않음.
const int KEY_0 = 0x30; int main() { byte keyState[256]; ZeroMemory(keyState, sizeof(byte) * 255); auto func = [](byte* keyState, DWORD threadID) { DWORD my_id = GetCurrentThreadId(); AttachThreadInput(my_id, threadID, true); // 없어도 작동함 byte pressed = (keyState[KEY_0] & 0x80); while (pressed == false) { ZeroMemory(keyState, sizeof(byte) * 255); GetKeyState(0); //GetAsyncKeyState(KEY_0); std::cout << GetKeyboardState(keyState) << std::endl; pressed = (keyState[KEY_0] & 0x80); //Sleep(10000); }; }; //func(keyState, GetCurrentThreadId()); auto t = std::thread(func, keyState, GetCurrentThreadId()); t.join(); }
위 코드는 재현다하가 뻘짓한 코드로 아래 설명에 대한 코드 아님.
GetKeyboardState 가 참조하는 값들은 멀티스레드 환경에서 실험하면 알 수 있듯이 스레드마다 독립적으로 갖음. 만약 window message 펌프를 한 스레드에서 실행하면 GetKeyState() 없이도 잘 될거임. 이때 딴 스레드에서 GetKeyboardState() 를 호출하면 이건 잘 작동하지 않음. 이때 그 스레드에서도 GetKeyState() 를 호출하면 잘 작동하게 됨.