#include #include #include #include "Win32Input.h" #include "Win32Mouse.h" namespace sp { static Vector2f _normalizePos(int x, int y, RECT area) { Vector2f out; out.x = x / ((float) (area.right - area.left)); out.y = y / ((float) (area.bottom - area.top)); return out; } static RECT GetClientArea(HWND hwnd) { RECT rect; GetClientRect(hwnd, &rect); return rect; } void Win32Mouse::init() { } Vector2f Win32Mouse::getPosition() const { return m_position; } Vector2f Win32Mouse::getAbsPosition() const { return m_abs_position; } bool Win32Mouse::isButtonDown(Mouse::Button button) const { int btn; switch(button) { case Mouse::Left : btn = VK_LBUTTON; break; case Mouse::Right : btn = VK_RBUTTON; break; case Mouse::Middle : btn = VK_MBUTTON; break; case Mouse::Button1 : btn = VK_XBUTTON1; break; case Mouse::Button2 : btn = VK_XBUTTON2; break; default: btn = 0; } return ::GetAsyncKeyState(btn) & 0x8000; } void Win32Mouse::update(InputModule *input) { HWND handle; POINT p; // Update absolute position GetCursorPos(&p); m_abs_position = Vector2f(p.x, p.y); // Update relative position handle = ::GetCapture(); if (handle) { // Translate position to focued window. ScreenToClient(handle, &p); m_position = Vector2f(p.x, p.y); } } bool Win32Mouse::handleMessage(MSG msg, Event& event) { switch(msg.message) { case WM_LBUTTONUP : case WM_LBUTTONDOWN : case WM_RBUTTONUP : case WM_RBUTTONDOWN : case WM_MBUTTONUP : case WM_MBUTTONDOWN : case WM_XBUTTONUP : case WM_XBUTTONDOWN : event.type = Event::MouseButton; break; } switch(msg.message) { case WM_LBUTTONUP : case WM_LBUTTONDOWN : event.mouseButton.button = Mouse::Button::Left; event.mouseButton.pressed = msg.message == WM_LBUTTONDOWN; return true; case WM_RBUTTONUP : case WM_RBUTTONDOWN : event.mouseButton.button = Mouse::Button::Right; event.mouseButton.pressed = msg.message == WM_RBUTTONDOWN; return true; case WM_MBUTTONUP : case WM_MBUTTONDOWN : event.mouseButton.button = Mouse::Button::Right; event.mouseButton.pressed = msg.message == WM_MBUTTONDOWN; return true; case WM_XBUTTONUP : case WM_XBUTTONDOWN : event.mouseButton.button = GET_XBUTTON_WPARAM(msg.wParam) == XBUTTON1 ? Mouse::Button::Button1 : Mouse::Button::Button2; event.mouseButton.pressed = msg.message == WM_XBUTTONDOWN; return true; case WM_MOUSEMOVE : RECT area = GetClientArea(msg.hwnd); int x = LOWORD(msg.lParam); int y = HIWORD(msg.lParam); // Do not forward the message if mouse is outside client area. if ( (x < area.left) || (x > area.right) || (y < area.top) || (y > area.bottom) ) { return false; } event.type = Event::MouseMove; event.mouseMove.x = x; event.mouseMove.y = y; return true; } return false; } } // namespace sp