LRESULT Ivy::System::Win32Window::WindowEventHandler(UINT msg, WPARAM wParam, LPARAM lParam) { Event event; switch (msg) { case WM_CLOSE: event = Event::WindowClosed; Close(); events.push(event); break; case WM_CREATE: event = Event::WindowCreated; events.push(event); break; case WM_KEYDOWN: event = Event::KeyPressed; input.keyboard.SetKeyState(ConvertVirtualKey(wParam), Input::InputState::Pressed); events.push(event); break; case WM_KEYUP: event = Event::KeyReleased; input.keyboard.SetKeyState(ConvertVirtualKey(wParam), Input::InputState::Released); events.push(event); break; case WM_MOUSEMOVE: event = Event::MouseMoved; input.mouse.SetCursorPosition(Math::Point<int>(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); events.push(event); break; case WM_MOVE: event = Event::WindowMoved; x = GET_X_LPARAM(lParam); y = GET_Y_LPARAM(lParam); events.push(event); break; case WM_SIZE: event = Event::WindowResized; width = GET_X_LPARAM(lParam); height = GET_Y_LPARAM(lParam); viewportNeedsResize = true; events.push(event); break; default: return DefWindowProc(hWnd, msg, wParam, lParam); } return 0; }
void XinputHandler::HandleKeyStrokeMessage(XINPUT_KEYSTROKE const* const keystroke) const { HandleGamePadButton( (keystroke->Flags & XINPUT_KEYSTROKE_KEYDOWN) == XINPUT_KEYSTROKE_KEYDOWN, (keystroke->Flags & XINPUT_KEYSTROKE_REPEAT) == XINPUT_KEYSTROKE_REPEAT, keystroke->UserIndex, ConvertVirtualKey(keystroke->VirtualKey)); }
bool NzWindowImpl::HandleMessage(HWND window, UINT message, WPARAM wParam, LPARAM lParam) { // Inutile de récupérer des évènements ne venant pas de notre fenêtre if (m_handle != window) return false; switch (message) { case WM_DESTROY: if (fullscreenWindow == this) ChangeDisplaySettings(nullptr, 0); break; case WM_SETCURSOR: // http://msdn.microsoft.com/en-us/library/windows/desktop/ms648382(v=vs.85).aspx if (LOWORD(lParam) == HTCLIENT) ::SetCursor(m_cursor); break; case WM_WINDOWPOSCHANGING: { WINDOWPOS* pos = reinterpret_cast<WINDOWPOS*>(lParam); pos->cx = std::max(pos->cx, m_minSize.x); pos->cy = std::max(pos->cy, m_minSize.y); if (m_maxSize.x >= 0) pos->cx = std::min(pos->cx, m_maxSize.x); if (m_maxSize.y >= 0) pos->cy = std::min(pos->cy, m_maxSize.y); break; } default: break; } if (m_eventListener) { switch (message) { case WM_CHAR: { // http://msdn.microsoft.com/en-us/library/ms646267(VS.85).aspx bool repeated = ((HIWORD(lParam) & KF_REPEAT) != 0); if (m_keyRepeat || !repeated) { NzEvent event; event.type = nzEventType_TextEntered; event.text.character = static_cast<char32_t>(wParam); event.text.repeated = repeated; m_parent->PushEvent(event); } break; } case WM_CLOSE: { NzEvent event; event.type = nzEventType_Quit; m_parent->PushEvent(event); return true; // Afin que Windows ne ferme pas la fenêtre automatiquement } #if !NAZARA_UTILITY_THREADED_WINDOW case WM_ENTERSIZEMOVE: { m_sizemove = true; break; } case WM_EXITSIZEMOVE: { m_sizemove = false; // On vérifie ce qui a changé RECT clientRect, windowRect; GetClientRect(m_handle, &clientRect); GetWindowRect(m_handle, &windowRect); NzVector2i position(windowRect.left, windowRect.top); if (m_position != position) { m_position = position; NzEvent event; event.type = nzEventType_Moved; event.position.x = position.x; event.position.y = position.y; m_parent->PushEvent(event); } NzVector2ui size(clientRect.right-clientRect.left, clientRect.bottom-clientRect.top); if (m_size != size) { m_size = size; NzEvent event; event.type = nzEventType_Resized; event.size.width = size.x; event.size.height = size.y; m_parent->PushEvent(event); } } #endif case WM_KEYDOWN: case WM_SYSKEYDOWN: { // http://msdn.microsoft.com/en-us/library/ms646267(VS.85).aspx bool repeated = ((HIWORD(lParam) & KF_REPEAT) != 0); if (m_keyRepeat || !repeated) { NzEvent event; event.type = nzEventType_KeyPressed; event.key.code = ConvertVirtualKey(wParam, lParam); event.key.alt = ((GetAsyncKeyState(VK_MENU) & 0x8000) != 0); event.key.control = ((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0); event.key.repeated = repeated; event.key.shift = ((GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0); event.key.system = (((GetAsyncKeyState(VK_LWIN) & 0x8000) != 0) || ((GetAsyncKeyState(VK_RWIN) & 0x8000) != 0)); m_parent->PushEvent(event); } break; } case WM_KEYUP: case WM_SYSKEYUP: { // http://msdn.microsoft.com/en-us/library/ms646267(VS.85).aspx NzEvent event; event.type = nzEventType_KeyReleased; event.key.code = ConvertVirtualKey(wParam, lParam); event.key.alt = ((GetAsyncKeyState(VK_MENU) & 0x8000) != 0); event.key.control = ((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0); event.key.shift = ((GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0); event.key.system = ((GetAsyncKeyState(VK_LWIN) & 0x8000) || (GetAsyncKeyState(VK_RWIN) & 0x8000)); m_parent->PushEvent(event); break; } case WM_KILLFOCUS: { NzEvent event; event.type = nzEventType_LostFocus; m_parent->PushEvent(event); break; } case WM_LBUTTONDBLCLK: { // Cet évènement est généré à la place d'un WM_LBUTTONDOWN lors d'un double-clic. // Comme nous désirons quand même notifier chaque clic, nous envoyons les deux évènements. NzEvent event; event.mouseButton.button = NzMouse::Left; event.mouseButton.x = GET_X_LPARAM(lParam); event.mouseButton.y = GET_Y_LPARAM(lParam); event.type = nzEventType_MouseButtonDoubleClicked; m_parent->PushEvent(event); event.type = nzEventType_MouseButtonPressed; m_parent->PushEvent(event); break; } case WM_LBUTTONDOWN: { NzEvent event; event.type = nzEventType_MouseButtonPressed; event.mouseButton.button = NzMouse::Left; event.mouseButton.x = GET_X_LPARAM(lParam); event.mouseButton.y = GET_Y_LPARAM(lParam); m_parent->PushEvent(event); break; } case WM_LBUTTONUP: { NzEvent event; event.type = nzEventType_MouseButtonReleased; event.mouseButton.button = NzMouse::Left; event.mouseButton.x = GET_X_LPARAM(lParam); event.mouseButton.y = GET_Y_LPARAM(lParam); m_parent->PushEvent(event); break; } case WM_MBUTTONDBLCLK: { NzEvent event; event.mouseButton.button = NzMouse::Middle; event.mouseButton.x = GET_X_LPARAM(lParam); event.mouseButton.y = GET_Y_LPARAM(lParam); event.type = nzEventType_MouseButtonDoubleClicked; m_parent->PushEvent(event); event.type = nzEventType_MouseButtonPressed; m_parent->PushEvent(event); break; } case WM_MBUTTONDOWN: { NzEvent event; event.type = nzEventType_MouseButtonPressed; event.mouseButton.button = NzMouse::Middle; event.mouseButton.x = GET_X_LPARAM(lParam); event.mouseButton.y = GET_Y_LPARAM(lParam); m_parent->PushEvent(event); break; } case WM_MBUTTONUP: { NzEvent event; event.type = nzEventType_MouseButtonReleased; event.mouseButton.button = NzMouse::Middle; event.mouseButton.x = GET_X_LPARAM(lParam); event.mouseButton.y = GET_Y_LPARAM(lParam); m_parent->PushEvent(event); break; } // Nécessite un appel précédent à TrackMouseEvent (Fait dans WM_MOUSEMOVE) // http://msdn.microsoft.com/en-us/library/windows/desktop/ms645615(v=vs.85).aspx case WM_MOUSELEAVE: { m_mouseInside = false; NzEvent event; event.type = nzEventType_MouseLeft; m_parent->PushEvent(event); break; } case WM_MOUSEMOVE: { int currentX = GET_X_LPARAM(lParam); int currentY = GET_Y_LPARAM(lParam); if (!m_mouseInside) { m_mouseInside = true; // On créé un évènement pour être informé de la sortie de la fenêtre TRACKMOUSEEVENT mouseEvent; mouseEvent.cbSize = sizeof(TRACKMOUSEEVENT); mouseEvent.dwFlags = TME_LEAVE; mouseEvent.hwndTrack = m_handle; TrackMouseEvent(&mouseEvent); NzEvent event; event.type = nzEventType_MouseEntered; m_parent->PushEvent(event); event.type = nzEventType_MouseMoved; // Le delta sera 0 event.mouseMove.deltaX = 0; event.mouseMove.deltaY = 0; event.mouseMove.x = currentX; event.mouseMove.y = currentY; m_mousePos.x = currentX; m_mousePos.y = currentY; m_parent->PushEvent(event); break; } // Si la souris n'a pas bougé (Ou qu'on veut ignorer l'évènement) if (m_mousePos.x == currentX && m_mousePos.y == currentY) break; NzEvent event; event.type = nzEventType_MouseMoved; event.mouseMove.deltaX = currentX - m_mousePos.x; event.mouseMove.deltaY = currentY - m_mousePos.y; event.mouseMove.x = currentX; event.mouseMove.y = currentY; m_mousePos.x = currentX; m_mousePos.y = currentY; m_parent->PushEvent(event); break; } case WM_MOUSEWHEEL: { if (m_smoothScrolling) { NzEvent event; event.type = nzEventType_MouseWheelMoved; event.mouseWheel.delta = static_cast<float>(GET_WHEEL_DELTA_WPARAM(wParam))/WHEEL_DELTA; m_parent->PushEvent(event); } else { m_scrolling += GET_WHEEL_DELTA_WPARAM(wParam); if (std::abs(m_scrolling) >= WHEEL_DELTA) { NzEvent event; event.type = nzEventType_MouseWheelMoved; event.mouseWheel.delta = static_cast<float>(m_scrolling/WHEEL_DELTA); m_parent->PushEvent(event); m_scrolling %= WHEEL_DELTA; } } break; } case WM_MOVE: { RECT windowRect; GetWindowRect(m_handle, &windowRect); NzEvent event; event.type = nzEventType_Moved; event.position.x = windowRect.left; event.position.y = windowRect.top; m_parent->PushEvent(event); break; } case WM_RBUTTONDBLCLK: { NzEvent event; event.mouseButton.button = NzMouse::Right; event.mouseButton.x = GET_X_LPARAM(lParam); event.mouseButton.y = GET_Y_LPARAM(lParam); event.type = nzEventType_MouseButtonDoubleClicked; m_parent->PushEvent(event); event.type = nzEventType_MouseButtonPressed; m_parent->PushEvent(event); break; } case WM_RBUTTONDOWN: { NzEvent event; event.type = nzEventType_MouseButtonPressed; event.mouseButton.button = NzMouse::Right; event.mouseButton.x = GET_X_LPARAM(lParam); event.mouseButton.y = GET_Y_LPARAM(lParam); m_parent->PushEvent(event); break; } case WM_RBUTTONUP: { NzEvent event; event.type = nzEventType_MouseButtonReleased; event.mouseButton.button = NzMouse::Right; event.mouseButton.x = GET_X_LPARAM(lParam); event.mouseButton.y = GET_Y_LPARAM(lParam); m_parent->PushEvent(event); break; } case WM_SETFOCUS: { NzEvent event; event.type = nzEventType_GainedFocus; m_parent->PushEvent(event); break; } case WM_SIZE: { #if NAZARA_UTILITY_THREADED_WINDOW if (wParam != SIZE_MINIMIZED) #else if (!m_sizemove && wParam != SIZE_MINIMIZED) #endif { RECT rect; GetClientRect(m_handle, &rect); NzVector2ui size(rect.right-rect.left, rect.bottom-rect.top); // On récupère uniquement la taille de la zone client if (m_size == size) break; m_size = size; NzEvent event; event.type = nzEventType_Resized; event.size.width = size.x; event.size.height = size.y; m_parent->PushEvent(event); } break; } case WM_UNICHAR: { // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646288(v=vs.85).aspx if (wParam != UNICODE_NOCHAR) { bool repeated = ((HIWORD(lParam) & KF_REPEAT) != 0); if (m_keyRepeat || !repeated) { NzEvent event; event.type = nzEventType_TextEntered; event.text.character = static_cast<char32_t>(wParam); event.text.repeated = repeated; m_parent->PushEvent(event); } return true; } } case WM_XBUTTONDBLCLK: { NzEvent event; if (HIWORD(wParam) == XBUTTON1) event.mouseButton.button = NzMouse::XButton1; else event.mouseButton.button = NzMouse::XButton2; event.mouseButton.x = GET_X_LPARAM(lParam); event.mouseButton.y = GET_Y_LPARAM(lParam); event.type = nzEventType_MouseButtonDoubleClicked; m_parent->PushEvent(event); event.type = nzEventType_MouseButtonPressed; m_parent->PushEvent(event); break; } case WM_XBUTTONDOWN: { NzEvent event; event.type = nzEventType_MouseButtonPressed; if (HIWORD(wParam) == XBUTTON1) event.mouseButton.button = NzMouse::XButton1; else event.mouseButton.button = NzMouse::XButton2; event.mouseButton.x = GET_X_LPARAM(lParam); event.mouseButton.y = GET_Y_LPARAM(lParam); m_parent->PushEvent(event); break; } case WM_XBUTTONUP: { NzEvent event; event.type = nzEventType_MouseButtonReleased; if (HIWORD(wParam) == XBUTTON1) event.mouseButton.button = NzMouse::XButton1; else event.mouseButton.button = NzMouse::XButton2; event.mouseButton.x = GET_X_LPARAM(lParam); event.mouseButton.y = GET_Y_LPARAM(lParam); m_parent->PushEvent(event); break; } default: break; } } #if NAZARA_UTILITY_WINDOWS_DISABLE_MENU_KEYS // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646360(v=vs.85).aspx if (message == WM_SYSCOMMAND && wParam == SC_KEYMENU) return true; #endif return false; }