From 4b114f276443c995587f2f5a5a775b532d1b9728 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Fri, 18 Dec 2015 18:06:45 -0500 Subject: [PATCH] Started the implementation of mouse crossing on Windows. --- windows/area.h | 2 ++ windows/areaevents.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/windows/area.h b/windows/area.h index 74a65336..e33db56a 100644 --- a/windows/area.h +++ b/windows/area.h @@ -21,6 +21,8 @@ struct uiArea { clickCounter cc; BOOL capturing; + BOOL inside; + ID2D1HwndRenderTarget *rt; }; diff --git a/windows/areaevents.c b/windows/areaevents.c index 4301e728..08a772ff 100644 --- a/windows/areaevents.c +++ b/windows/areaevents.c @@ -92,6 +92,34 @@ static void areaMouseEvent(uiArea *a, uintmax_t down, uintmax_t up, WPARAM wPar (*(a->ah->MouseEvent))(a->ah, a, &me); } +// see https://blogs.msdn.microsoft.com/oldnewthing/20031013-00/?p=42193 +// TODO this does not work while captured +static void onMouseEntered(uiArea *a) +{ + TRACKMOUSEEVENT tm; + + if (a->inside) + return; + ZeroMemory(&tm, sizeof (TRACKMOUSEEVENT)); + tm.cbSize = sizeof (TRACKMOUSEEVENT); + tm.dwFlags = TME_LEAVE; + tm.hwndTrack = a->hwnd; + if (_TrackMouseEvent(&tm) == 0) + logLastError("error setting up mouse leave events in onMouseEntered()"); + a->inside = TRUE; + (*(a->ah->MouseCrossed))(a->ah, a, 0); + // TODO figure out why we did this to begin with; either we do it on both GTK+ and Windows or not at all + clickCounterReset(&(a->cc)); +} + +static void onMouseLeft(uiArea *a) +{ + a->inside = FALSE; + (*(a->ah->MouseCrossed))(a->ah, a, 1); + // TODO figure out why we did this to begin with; either we do it on both GTK+ and Windows or not at all + clickCounterReset(&(a->cc)); +} + // we use VK_SNAPSHOT as a sentinel because libui will never support the print screen key; that key belongs to the user struct extkeymap { WPARAM vk; @@ -244,9 +272,14 @@ BOOL areaDoEvents(uiArea *a, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *l *lResult = 0; return TRUE; case WM_MOUSEMOVE: + onMouseEntered(a); areaMouseEvent(a, 0, 0, wParam, lParam); *lResult = 0; return TRUE; + case WM_MOUSELEAVE: + onMouseLeft(a); + *lResult = 0; + return TRUE; case WM_LBUTTONDOWN: SetFocus(a->hwnd); areaMouseEvent(a, 1, 0, wParam, lParam);