Beispiel #1
0
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;
}
Beispiel #2
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;
}