Implement Mouse Enter/Leave Events

This commit is contained in:
Phillip 2015-11-06 23:49:53 -08:00
parent 9fc3810015
commit 0f057a3713
2 changed files with 109 additions and 29 deletions

View File

@ -234,7 +234,8 @@ public:
case WM_DEVICECHANGE: case WM_DEVICECHANGE:
return DeviceFinder::winDevChangedHandler(wParam, lParam); return DeviceFinder::winDevChangedHandler(wParam, lParam);
case WM_SIZE: case WM_SIZING:
case WM_MOVING:
case WM_SYSKEYDOWN: case WM_SYSKEYDOWN:
case WM_KEYDOWN: case WM_KEYDOWN:
case WM_SYSKEYUP: case WM_SYSKEYUP:
@ -248,6 +249,10 @@ public:
case WM_XBUTTONDOWN: case WM_XBUTTONDOWN:
case WM_XBUTTONUP: case WM_XBUTTONUP:
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
case WM_MOUSELEAVE:
case WM_NCMOUSELEAVE:
case WM_MOUSEHOVER:
case WM_NCMOUSEHOVER:
window->_incomingEvent(&HWNDEvent(uMsg, wParam, lParam)); window->_incomingEvent(&HWNDEvent(uMsg, wParam, lParam));
default: default:

View File

@ -420,14 +420,14 @@ class WindowWin32 : public IWindow
HWND m_hwnd; HWND m_hwnd;
std::unique_ptr<GraphicsContextWin32> m_gfxCtx; std::unique_ptr<GraphicsContextWin32> m_gfxCtx;
IWindowCallback* m_callback = nullptr; IWindowCallback* m_callback = nullptr;
public: public:
WindowWin32(const SystemString& title, Boo3DAppContext& b3dCtx) WindowWin32(const SystemString& title, Boo3DAppContext& b3dCtx)
{ {
m_hwnd = CreateWindowW(L"BooWindow", title.c_str(), WS_OVERLAPPEDWINDOW, m_hwnd = CreateWindowW(L"BooWindow", title.c_str(), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, NULL, NULL); NULL, NULL, NULL, NULL);
IGraphicsContext::EGraphicsAPI api = IGraphicsContext::API_D3D11; IGraphicsContext::EGraphicsAPI api = IGraphicsContext::API_D3D11;
#if _WIN32_WINNT_WIN10 #if _WIN32_WINNT_WIN10
if (b3dCtx.m_ctx12.m_dev) if (b3dCtx.m_ctx12.m_dev)
@ -440,39 +440,39 @@ public:
} }
m_gfxCtx.reset(new GraphicsContextWin32D3D(api, this, m_hwnd, b3dCtx)); m_gfxCtx.reset(new GraphicsContextWin32D3D(api, this, m_hwnd, b3dCtx));
} }
~WindowWin32() ~WindowWin32()
{ {
} }
void setCallback(IWindowCallback* cb) void setCallback(IWindowCallback* cb)
{ {
m_callback = cb; m_callback = cb;
} }
void showWindow() void showWindow()
{ {
ShowWindow(m_hwnd, SW_SHOW); ShowWindow(m_hwnd, SW_SHOW);
} }
void hideWindow() void hideWindow()
{ {
ShowWindow(m_hwnd, SW_HIDE); ShowWindow(m_hwnd, SW_HIDE);
} }
SystemString getTitle() SystemString getTitle()
{ {
wchar_t title[256]; wchar_t title[256];
int c = GetWindowTextW(m_hwnd, title, 256); int c = GetWindowTextW(m_hwnd, title, 256);
return SystemString(title, c); return SystemString(title, c);
} }
void setTitle(const SystemString& title) void setTitle(const SystemString& title)
{ {
SetWindowTextW(m_hwnd, title.c_str()); SetWindowTextW(m_hwnd, title.c_str());
} }
void setWindowFrameDefault() void setWindowFrameDefault()
{ {
MONITORINFO monInfo; MONITORINFO monInfo;
@ -481,13 +481,17 @@ public:
genFrameDefault(&monInfo, x, y, w, h); genFrameDefault(&monInfo, x, y, w, h);
setWindowFrame(x, y, w, h); setWindowFrame(x, y, w, h);
} }
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const
{ {
RECT rct; RECT rct;
GetClientRect(m_hwnd, &rct); GetClientRect(m_hwnd, &rct);
xOut = rct.left; POINT pt;
yOut = rct.top; pt.x = rct.left;
pt.y = rct.top;
MapWindowPoints(m_hwnd, HWND_DESKTOP, &pt, 1);
xOut = pt.x;
yOut = pt.y;
wOut = rct.right; wOut = rct.right;
hOut = rct.bottom; hOut = rct.bottom;
} }
@ -496,12 +500,16 @@ public:
{ {
RECT rct; RECT rct;
GetClientRect(m_hwnd, &rct); GetClientRect(m_hwnd, &rct);
xOut = rct.left; POINT pt;
yOut = rct.top; pt.x = rct.left;
pt.y = rct.top;
MapWindowPoints(m_hwnd, HWND_DESKTOP, &pt, 1);
xOut = pt.x;
yOut = pt.y;
wOut = rct.right; wOut = rct.right;
hOut = rct.bottom; hOut = rct.bottom;
} }
void setWindowFrame(float x, float y, float w, float h) void setWindowFrame(float x, float y, float w, float h)
{ {
MoveWindow(m_hwnd, x, y, w, h, true); MoveWindow(m_hwnd, x, y, w, h, true);
@ -511,17 +519,17 @@ public:
{ {
MoveWindow(m_hwnd, x, y, w, h, true); MoveWindow(m_hwnd, x, y, w, h, true);
} }
float getVirtualPixelFactor() const float getVirtualPixelFactor() const
{ {
return 1.0; return 1.0;
} }
bool isFullscreen() const bool isFullscreen() const
{ {
return m_gfxCtx->m_3dCtx.isFullscreen(this); return m_gfxCtx->m_3dCtx.isFullscreen(this);
} }
void setFullscreen(bool fs) void setFullscreen(bool fs)
{ {
m_gfxCtx->m_3dCtx.setFullscreen(this, fs); m_gfxCtx->m_3dCtx.setFullscreen(this, fs);
@ -570,13 +578,26 @@ public:
m_callback->mouseUp(coord, button, EModifierKey(modifierMask)); m_callback->mouseUp(coord, button, EModifierKey(modifierMask));
} }
} }
void _trackMouse()
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_NONCLIENT | TME_HOVER | TME_LEAVE;
tme.dwHoverTime = 500;
tme.hwndTrack = m_hwnd;
}
bool mouseTracking = false;
bool moving = false;
bool resizing = false;
void _incomingEvent(void* ev) void _incomingEvent(void* ev)
{ {
HWNDEvent& e = *static_cast<HWNDEvent*>(ev); HWNDEvent& e = *static_cast<HWNDEvent*>(ev);
switch (e.uMsg) switch (e.uMsg)
{ {
case WM_SIZE: case WM_SIZING:
{ {
SWindowRect rect; SWindowRect rect;
getWindowFrame(rect.location[0], rect.location[1], rect.size[0], rect.size[1]); getWindowFrame(rect.location[0], rect.location[1], rect.size[0], rect.size[1]);
@ -587,6 +608,17 @@ public:
m_callback->resized(rect); m_callback->resized(rect);
return; return;
} }
case WM_MOVING:
{
SWindowRect rect;
getWindowFrame(rect.location[0], rect.location[1], rect.size[0], rect.size[1]);
if (!rect.size[0] || !rect.size[1])
return;
if (m_callback)
m_callback->windowMoved(rect);
return;
}
case WM_KEYDOWN: case WM_KEYDOWN:
case WM_SYSKEYDOWN: case WM_SYSKEYDOWN:
{ {
@ -681,7 +713,50 @@ public:
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam)}, {(unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam)},
{float(GET_X_LPARAM(e.lParam)) / float(w), float(GET_Y_LPARAM(e.lParam)) / float(h)} {float(GET_X_LPARAM(e.lParam)) / float(w), float(GET_Y_LPARAM(e.lParam)) / float(h)}
}; };
m_callback->mouseMove(coord); if (!mouseTracking)
{
_trackMouse();
mouseTracking = true;
m_callback->mouseEnter(coord);
}
else
m_callback->mouseMove(coord);
}
return;
}
case WM_MOUSELEAVE:
case WM_NCMOUSELEAVE:
{
if (m_callback)
{
int x, y, w, h;
getWindowFrame(x, y, w, h);
SWindowCoord coord =
{
{ (unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam) },
{ (unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam) },
{ float(GET_X_LPARAM(e.lParam)) / float(w), float(GET_Y_LPARAM(e.lParam)) / float(h) }
};
m_callback->mouseLeave(coord);
mouseTracking = false;
}
return;
}
case WM_NCMOUSEHOVER:
case WM_MOUSEHOVER:
{
if (m_callback)
{
int x, y, w, h;
getWindowFrame(x, y, w, h);
SWindowCoord coord =
{
{ (unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam) },
{ (unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam) },
{ float(GET_X_LPARAM(e.lParam)) / float(w), float(GET_Y_LPARAM(e.lParam)) / float(h) }
};
m_callback->mouseEnter(coord);
} }
return; return;
} }
@ -743,7 +818,7 @@ public:
{ {
return m_gfxCtx->getLoadContextDataFactory(); return m_gfxCtx->getLoadContextDataFactory();
} }
}; };
IWindow* _WindowWin32New(const SystemString& title, Boo3DAppContext& d3dCtx) IWindow* _WindowWin32New(const SystemString& title, Boo3DAppContext& d3dCtx)