📄 mousegesture.cpp
字号:
// nID - The ID of the pattern to remove
//
// Returns
// true : the pattern was found and removed
// false : the pattern was not found
//////////////////////////////////////////////////////////////////////
bool CMouseGesture::RemoveGesture(UINT nID)
{
bool ret = m_GestureMap.erase(nID) == 1;
if (ret)
{
// reset the m_ButtonFlag in case a mouse button is eliminated
m_ButtonFlag = 0;
for (GestureMap::const_iterator it = m_GestureMap.begin(); it != m_GestureMap.end(); ++it)
{
m_ButtonFlag |= (*it).second[0];
}
}
return ret;
}
//////////////////////////////////////////////////////////////////////
// Detach
// public member function
//
// Detaches this CMouseGesture object from the window
//////////////////////////////////////////////////////////////////////
#pragma warning(push)
#pragma warning(disable: 4189) // 'erased' : local variable is initialized but not referenced
void CMouseGesture::Detach()
{
if (m_hWnd != NULL)
{
int erased = WindowMap.erase(m_hWnd);
_ASSERT (erased == 1);
m_hWnd = NULL;
}
if (WindowMap.size() == 0 && MainHook != NULL)
{
UnhookWindowsHookEx(MainHook);
MainHook = NULL;
}
}
#pragma warning(pop)
//////////////////////////////////////////////////////////////////////
// Mouse message handler functions
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// MouseMessage
// private member function
//
// Called by the MouseHookProc to handle the mouse messages
//
// Returns:
// the this pointer if handling a gesture
// NULL if not
//////////////////////////////////////////////////////////////////////
CMouseGesture* CMouseGesture::MouseMessage(WPARAM wp, LPARAM lp)
{
CMouseGesture *ret = NULL;
DWORD Message = (DWORD)wp;
MOUSEHOOKSTRUCT *pMHS = (MOUSEHOOKSTRUCT *)lp;
switch (Message)
{
case WM_LBUTTONDOWN:
if (m_ButtonFlag & LeftButton)
{
m_CurrentGesture.clear();
m_CurrentGesture.push_back(LeftButton);
m_ButtonDown = LeftButton;
ret = OnButtonDown(pMHS);
}
break;
case WM_MBUTTONDOWN:
if (m_ButtonFlag & MiddleButton)
{
m_CurrentGesture.clear();
m_CurrentGesture.push_back(MiddleButton);
m_ButtonDown = MiddleButton;
ret = OnButtonDown(pMHS);
}
break;
case WM_RBUTTONDOWN:
if (m_ButtonFlag & RightButton)
{
m_CurrentGesture.clear();
m_CurrentGesture.push_back(RightButton);
m_ButtonDown = RightButton;
ret = OnButtonDown(pMHS);
}
break;
case WM_LBUTTONUP:
if (m_ButtonDown == LeftButton)
{
ret = OnButtonUp(pMHS);
}
break;
case WM_MBUTTONUP:
if (m_ButtonDown == MiddleButton)
{
ret = OnButtonUp(pMHS);
}
break;
case WM_RBUTTONUP:
if (m_ButtonDown == RightButton)
{
ret = OnButtonUp(pMHS);
}
break;
case WM_MOUSEMOVE:
case WM_NCMOUSEMOVE:
if (m_ButtonDown != None)
{
ret = OnMouseMove(pMHS);
}
}
if (ret == NULL)
{
KillGesture();
}
return ret;
}
//////////////////////////////////////////////////////////////////////
// OnButtonDown
// protected virtual member function
//
// Handles the start of a gesture
//////////////////////////////////////////////////////////////////////
CMouseGesture* CMouseGesture::OnButtonDown(MOUSEHOOKSTRUCT *pMHS)
{
m_BoundingSquare.left = pMHS->pt.x - m_nDistance;
m_BoundingSquare.top = pMHS->pt.y - m_nDistance;
m_BoundingSquare.right = pMHS->pt.x + m_nDistance;
m_BoundingSquare.bottom = pMHS->pt.y + m_nDistance;
SHOW_BOUNDING_SQUARE (pMHS, m_BoundingSquare);
m_LastDirection = None;
if (IsSHIFTpressed())
{
m_bShift = true;
m_CurrentGesture.push_back(Shift);
}
if (IsCTRLpressed())
{
m_bControl = true;
m_CurrentGesture.push_back(Control);
}
return this;
}
//////////////////////////////////////////////////////////////////////
// OnMouseMove
// protected virtual member function
//
// Handles the building of the gesture
//////////////////////////////////////////////////////////////////////
CMouseGesture* CMouseGesture::OnMouseMove(MOUSEHOOKSTRUCT *pMHS)
{
#ifdef _SHOW_GESTURE
{
POINT pt;
pt.x = pMHS->pt.x;
pt.y = pMHS->pt.y;
HWND hWnd = WindowFromPoint(pt);
ScreenToClient(hWnd, &pt);
HDC hdc = GetDC(hWnd);
SetPixel(hdc, pt.x, pt.y, RGB(255, 0, 0));
ReleaseDC(hWnd, hdc);
}
#endif
// make sure the SHIFT and CTRL keys are in
// the same state as when the gesture started
if (m_bShift != IsSHIFTpressed() ||
m_bControl != IsCTRLpressed())
{
return NULL;
}
// looking for next direction mouse is taking
if (PtInRect(&m_BoundingSquare, pMHS->pt))
{
// not yet able to determine
return this;
}
Motion Direction = None;
if ((pMHS->pt.x >= m_BoundingSquare.right) &&
(pMHS->pt.y >= m_BoundingSquare.top) &&
(pMHS->pt.y <= m_BoundingSquare.bottom))
{
Direction = Right;
}
else if ((pMHS->pt.x <= m_BoundingSquare.left) &&
(pMHS->pt.y >= m_BoundingSquare.top) &&
(pMHS->pt.y <= m_BoundingSquare.bottom))
{
Direction = Left;
}
else if ((pMHS->pt.y >= m_BoundingSquare.bottom) &&
(pMHS->pt.x >= m_BoundingSquare.left) &&
(pMHS->pt.x <= m_BoundingSquare.right))
{
Direction = Down;
}
else if ((pMHS->pt.y <= m_BoundingSquare.top) &&
(pMHS->pt.x >= m_BoundingSquare.left) &&
(pMHS->pt.x <= m_BoundingSquare.right))
{
Direction = Up;
}
if (Direction == None)
{
// Unable to calculate the direction, probably went
// diagonally off a corner of the bounding square
return NULL;
}
SHOW_BOUNDING_SQUARE (pMHS, m_BoundingSquare);
// move the bounding square to follow the mouse
if (m_LastDirection == Direction)
{
switch (Direction)
{
case Left:
case Right:
m_BoundingSquare.left = pMHS->pt.x - m_nDistance;
m_BoundingSquare.right = pMHS->pt.x + m_nDistance;
break;
case Up:
case Down:
m_BoundingSquare.top = pMHS->pt.y - m_nDistance;
m_BoundingSquare.bottom = pMHS->pt.y + m_nDistance;
}
}
else // m_LastDirection != Direction
{
m_BoundingSquare.left = pMHS->pt.x - m_nDistance;
m_BoundingSquare.right = pMHS->pt.x + m_nDistance;
m_BoundingSquare.top = pMHS->pt.y - m_nDistance;
m_BoundingSquare.bottom = pMHS->pt.y + m_nDistance;
// direction changed, save the new direction
m_CurrentGesture.push_back(Direction);
m_LastDirection = Direction;
}
SHOW_BOUNDING_SQUARE (pMHS, m_BoundingSquare);
if (GetCapture() == NULL)
{
// capture the mouse so we can continue recieving messages
// if the mouse leaves the window
SetCapture(m_hWnd);
m_bCaptured = true;
}
return this;
}
//////////////////////////////////////////////////////////////////////
// OnButtonUp
// protected virtual member function
//
// Handles the end of the mouse gesture
//////////////////////////////////////////////////////////////////////
CMouseGesture* CMouseGesture::OnButtonUp(MOUSEHOOKSTRUCT *pMHS)
{
UNREFERENCED_PARAMETER(pMHS);
// make sure the SHIFT and CTRL keys are in
// the same state as when the gesture started
if (m_bShift != IsSHIFTpressed() ||
m_bControl != IsCTRLpressed())
{
return NULL;
}
#ifdef _DEBUG
OutputDebugString (_T("\nDumping gesture:\n"));
for (Gesture::iterator it = m_CurrentGesture.begin(); it != m_CurrentGesture.end(); ++it)
{
switch (*it)
{
case Up:
OutputDebugString (_T("Up, "));
break;
case Down:
OutputDebugString (_T("Down, "));
break;
case Left:
OutputDebugString (_T("Left, "));
break;
case Right:
OutputDebugString (_T("Right, "));
break;
case LeftButton:
OutputDebugString (_T("Left Button, "));
break;
case MiddleButton:
OutputDebugString (_T("Middle Button, "));
break;
case RightButton:
OutputDebugString (_T("Right Button, "));
break;
case Shift:
OutputDebugString (_T("Shift, "));
break;
case Control:
OutputDebugString (_T("Control, "));
break;
default:
OutputDebugString (_T("Invalid Gesture"));
}
}
OutputDebugString (_T("\n\n"));
#endif
UINT GestureID = GetGestureIdFromMap(m_CurrentGesture);
if (GestureID > 0 && IsWindow(m_hWnd))
{
PostMessage(m_hWnd, WMU_MOUSEGESTURE, (WPARAM)GestureID, (LPARAM)this);
}
return NULL;
}
//////////////////////////////////////////////////////////////////////
// Helper functions
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// GetGestureIdFromMap
// private member function
//
// Finds the gesture in the map of recognized patterns
//
// Returns:
// The ID of the pattern found
// 0 if not found
//////////////////////////////////////////////////////////////////////
UINT CMouseGesture::GetGestureIdFromMap(const Gesture &gesture)
{
UINT ret = 0;
for (GestureMap::const_iterator it = m_GestureMap.begin(); it != m_GestureMap.end(); ++it)
{
if ((*it).second == gesture)
{
ret = (*it).first;
break;
}
}
return ret;
}
//////////////////////////////////////////////////////////////////////
// KillGesture
// private member function
//
// Cleans up when a gesture ends or is abandoned
//////////////////////////////////////////////////////////////////////
void CMouseGesture::KillGesture()
{
#ifdef _SHOW_GESTURE
// remove any drawing done
RedrawWindow(m_hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE);
#endif
OutputDebugString (_T("Gesture Ended\n"));
if (m_bCaptured && GetCapture() == m_hWnd)
{
ReleaseCapture();
}
m_ButtonDown = None;
m_bShift = false;
m_bControl = false;
m_CurrentGesture.clear();
m_bCaptured = false;
}
//////////////////////////////////////////////////////////////////////
// End
//////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -