/////////////////////////////////////////////////////////// /// Convert a Win32 virtual key code to a SFML key code //////////////////////////////////////////////////////////// Key::Code VirtualKeyCodeToSF(WPARAM VirtualKey, LPARAM Flags) { switch (VirtualKey) { // VK_SHIFT is handled by the GetShiftState function case VK_MENU : return (Flags & (1 << 24)) ? Key::RAlt : Key::LAlt; case VK_CONTROL : return (Flags & (1 << 24)) ? Key::RControl : Key::LControl; case VK_LWIN : return Key::LSystem; case VK_RWIN : return Key::RSystem; case VK_APPS : return Key::Menu; case VK_OEM_1 : return Key::SemiColon; case VK_OEM_2 : return Key::Slash; case VK_OEM_PLUS : return Key::Equal; case VK_OEM_MINUS : return Key::Dash; case VK_OEM_4 : return Key::LBracket; case VK_OEM_6 : return Key::RBracket; case VK_OEM_COMMA : return Key::Comma; case VK_OEM_PERIOD : return Key::Period; case VK_OEM_7 : return Key::Quote; case VK_OEM_5 : return Key::BackSlash; case VK_OEM_3 : return Key::Tilde; case VK_ESCAPE : return Key::Escape; case VK_SPACE : return Key::Space; case VK_RETURN : return Key::Return; case VK_BACK : return Key::Back; case VK_TAB : return Key::Tab; case VK_PRIOR : return Key::PageUp; case VK_NEXT : return Key::PageDown; case VK_END : return Key::End; case VK_HOME : return Key::Home; case VK_INSERT : return Key::Insert; case VK_DELETE : return Key::Delete; case VK_ADD : return Key::Add; case VK_SUBTRACT : return Key::Subtract; case VK_MULTIPLY : return Key::Multiply; case VK_DIVIDE : return Key::Divide; case VK_PAUSE : return Key::Pause; case VK_F1 : return Key::F1; case VK_F2 : return Key::F2; case VK_F3 : return Key::F3; case VK_F4 : return Key::F4; case VK_F5 : return Key::F5; case VK_F6 : return Key::F6; case VK_F7 : return Key::F7; case VK_F8 : return Key::F8; case VK_F9 : return Key::F9; case VK_F10 : return Key::F10; case VK_F11 : return Key::F11; case VK_F12 : return Key::F12; case VK_F13 : return Key::F13; case VK_F14 : return Key::F14; case VK_F15 : return Key::F15; case VK_RIGHT : return Key::Right; case VK_UP : return Key::Up; case VK_DOWN : return Key::Down; case VK_NUMPAD0 : return Key::Numpad0; case VK_NUMPAD1 : return Key::Numpad1; case VK_NUMPAD2 : return Key::Numpad2; case VK_NUMPAD3 : return Key::Numpad3; case VK_NUMPAD4 : return Key::Numpad4; case VK_NUMPAD5 : return Key::Numpad5; case VK_NUMPAD6 : return Key::Numpad6; case VK_NUMPAD7 : return Key::Numpad7; case VK_NUMPAD8 : return Key::Numpad8; case VK_NUMPAD9 : return Key::Numpad9; case 'A' : return Key::A; case 'Z' : return Key::Z; case 'E' : return Key::E; case 'R' : return Key::R; case 'T' : return Key::T; case 'Y' : return Key::Y; case 'U' : return Key::U; case 'I' : return Key::I; case 'O' : return Key::O; case 'P' : return Key::P; case 'Q' : return Key::Q; case 'S' : return Key::S; case 'D' : return Key::D; case 'F' : return Key::F; case 'G' : return Key::G; case 'H' : return Key::H; case 'J' : return Key::J; case 'K' : return Key::K; case 'L' : return Key::L; case 'M' : return Key::M; case 'W' : return Key::W; case 'X' : return Key::X; case 'C' : return Key::C; case 'V' : return Key::V; case 'B' : return Key::B; case 'N' : return Key::N; case '0' : return Key::Num0; case '1' : return Key::Num1; case '2' : return Key::Num2; case '3' : return Key::Num3; case '4' : return Key::Num4; case '5' : return Key::Num5; case '6' : return Key::Num6; case '7' : return Key::Num7; case '8' : return Key::Num8; case '9' : return Key::Num9; } return Key::Code(0); } //////////////////////////////////////////////////////////// /// Process a Win32 event //////////////////////////////////////////////////////////// void ProcessEvent(UINT Message, WPARAM WParam, LPARAM LParam) { // Don't process any message until window is created if (myHandle == NULL) return; switch (Message) { // Destroy event case WM_DESTROY : { // Here we must cleanup resources ! Cleanup(); break; } // Set cursor event case WM_SETCURSOR : { // The mouse has moved, if the cursor is in our window we must refresh the cursor if (LOWORD(LParam) == HTCLIENT) SetCursor(myCursor); break; } case WM_CLOSE : { Event Evt; Evt.Type = Event::Closed; SendEvent(Evt); break; } // Resize event case WM_SIZE : { // Update window size RECT Rect; GetClientRect(myHandle, &Rect); myWidth = Rect.right - Rect.left; myHeight = Rect.bottom - Rect.top; Event Evt; Evt.Type = Event::Resized; Evt.Size.Width = myWidth; Evt.Size.Height = myHeight; SendEvent(Evt); break; } // Gain focus event case WM_SETFOCUS : { Event Evt; Evt.Type = Event::GainedFocus; SendEvent(Evt); break; } // Lost focus event case WM_KILLFOCUS : { Event Evt; Evt.Type = Event::LostFocus; SendEvent(Evt); break; } // Text event case WM_CHAR : { Event Evt; Evt.Type = Event::TextEntered; Evt.Text.Unicode = static_cast(WParam); SendEvent(Evt); break; } // Keydown event case WM_KEYDOWN : case WM_SYSKEYDOWN : { if (myKeyRepeatEnabled || ((LParam & (1 << 30)) == 0)) { Event Evt; Evt.Type = Event::KeyPressed; Evt.Key.Code = (WParam == VK_SHIFT) ? GetShiftState(true) : VirtualKeyCodeToSF(WParam, LParam); Evt.Key.Alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0; Evt.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0; Evt.Key.Shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0; SendEvent(Evt); } break; } // Keyup event case WM_KEYUP : case WM_SYSKEYUP : { Event Evt; Evt.Type = Event::KeyReleased; Evt.Key.Code = (WParam == VK_SHIFT) ? GetShiftState(false) : VirtualKeyCodeToSF(WParam, LParam); Evt.Key.Alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0; Evt.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0; Evt.Key.Shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0; SendEvent(Evt); break; } // Mouse wheel event case WM_MOUSEWHEEL : { Event Evt; Evt.Type = Event::MouseWheelMoved; Evt.MouseWheel.Delta = static_cast(HIWORD(WParam)) / 120; SendEvent(Evt); break; } // Mouse left button down event case WM_LBUTTONDOWN : { Event Evt; Evt.Type = Event::MouseButtonPressed; Evt.MouseButton.Button = Mouse::Left; Evt.MouseButton.X = LOWORD(LParam); Evt.MouseButton.Y = HIWORD(LParam); SendEvent(Evt); break; } // Mouse left button up event case WM_LBUTTONUP : { Event Evt; Evt.Type = Event::MouseButtonReleased; Evt.MouseButton.Button = Mouse::Left; Evt.MouseButton.X = LOWORD(LParam); Evt.MouseButton.Y = HIWORD(LParam); SendEvent(Evt); break; } // Mouse right button down event case WM_RBUTTONDOWN : { Event Evt; Evt.Type = Event::MouseButtonPressed; Evt.MouseButton.Button = Mouse::Right; Evt.MouseButton.X = LOWORD(LParam); Evt.MouseButton.Y = HIWORD(LParam); SendEvent(Evt); break; } // Mouse right button up event case WM_RBUTTONUP : { Event Evt; Evt.Type = Event::MouseButtonReleased; Evt.MouseButton.Button = Mouse::Right; Evt.MouseButton.X = LOWORD(LParam); Evt.MouseButton.Y = HIWORD(LParam); SendEvent(Evt); break; } // Mouse wheel button down event case WM_MBUTTONDOWN : { Event Evt; Evt.Type = Event::MouseButtonPressed; Evt.MouseButton.Button = Mouse::Middle; Evt.MouseButton.X = LOWORD(LParam); Evt.MouseButton.Y = HIWORD(LParam); SendEvent(Evt); break; } // Mouse wheel button up event case WM_MBUTTONUP : { Event Evt; Evt.Type = Event::MouseButtonReleased; Evt.MouseButton.Button = Mouse::Middle; Evt.MouseButton.X = LOWORD(LParam); Evt.MouseButton.Y = HIWORD(LParam); SendEvent(Evt); break; } // Mouse X button down event case WM_XBUTTONDOWN : { Event Evt; Evt.Type = Event::MouseButtonPressed; Evt.MouseButton.Button = HIWORD(WParam) == XBUTTON1 ? Mouse::XButton1 : Mouse::XButton2; Evt.MouseButton.X = LOWORD(LParam); Evt.MouseButton.Y = HIWORD(LParam); SendEvent(Evt); break; } // Mouse X button up event case WM_XBUTTONUP : { Event Evt; Evt.Type = Event::MouseButtonReleased; Evt.MouseButton.Button = HIWORD(WParam) == XBUTTON1 ? Mouse::XButton1 : Mouse::XButton2; Evt.MouseButton.X = LOWORD(LParam); SendEvent(Evt); break; } // Mouse move event case WM_MOUSEMOVE : { // Check if we need to generate a MouseEntered event if (!myIsCursorIn) { TRACKMOUSEEVENT MouseEvent; MouseEvent.cbSize = sizeof(TRACKMOUSEEVENT); MouseEvent.hwndTrack = myHandle; MouseEvent.dwFlags = TME_LEAVE; TrackMouseEvent(&MouseEvent); myIsCursorIn = true; Event Evt; Evt.Type = Event::MouseEntered; SendEvent(Evt); } Event Evt; Evt.Type = Event::MouseMoved; Evt.MouseMove.X = LOWORD(LParam); SendEvent(Evt); break; } // Mouse leave event case WM_MOUSELEAVE : { myIsCursorIn = false; Event Evt; Evt.Type = Event::MouseLeft; SendEvent(Evt); break; } } } /////////////////////////////////////////////////////////// /// Check the state of the shift keys on a key event, /// and return the corresponding SF key code //////////////////////////////////////////////////////////// Key::Code WindowImplWin32::GetShiftState(bool KeyDown) { static bool LShiftPrevDown = false; static bool RShiftPrevDown = false; bool LShiftDown = (HIWORD(GetAsyncKeyState(VK_LSHIFT)) != 0); bool RShiftDown = (HIWORD(GetAsyncKeyState(VK_RSHIFT)) != 0); Key::Code Code = Key::Code(0); if (KeyDown) { if (!LShiftPrevDown && LShiftDown) Code = Key::LShift; else if (!RShiftPrevDown && RShiftDown) Code = Key::RShift; } else { if (LShiftPrevDown && !LShiftDown) Code = Key::LShift; else if (RShiftPrevDown && !RShiftDown) Code = Key::RShift; } LShiftPrevDown = LShiftDown; RShiftPrevDown = RShiftDown; return Code; }