391 lines
11 KiB
C++
391 lines
11 KiB
C++
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
// GestureHandler.cpp : Implementation of CGestureHandler
|
|
|
|
#include "stdafx.h"
|
|
#include "GestureHandler.h"
|
|
|
|
|
|
// CGestureHandler
|
|
// IStylusAsyncPlugin Interface implementation
|
|
|
|
STDMETHODIMP CGestureHandler::Packets(
|
|
/* [in] */ IRealTimeStylus *piRtsSrc,
|
|
/* [in] */ const StylusInfo *pStylusInfo,
|
|
/* [in] */ ULONG cPktCount,
|
|
/* [in] */ ULONG cPktBuffLength,
|
|
/* [size_is][in] */ LONG *pPackets,
|
|
/* [out][in] */ ULONG *pcInOutPkts,
|
|
/* [out][in] */ LONG **ppInOutPkts)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CGestureHandler::StylusDown(
|
|
/* [in] */ IRealTimeStylus *piRtsSrc,
|
|
/* [in] */ const StylusInfo *pStylusInfo,
|
|
/* [in] */ ULONG cPropCountPerPkt,
|
|
/* [size_is][in] */ LONG *pPacket,
|
|
/* [out][in] */ LONG **ppInOutPkt)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CGestureHandler::StylusUp(
|
|
/* [in] */ IRealTimeStylus *piRtsSrc,
|
|
/* [in] */ const StylusInfo *pStylusInfo,
|
|
/* [in] */ ULONG cPropCountPerPkt,
|
|
/* [size_is][in] */ LONG *pPacket,
|
|
/* [out][in] */ LONG **ppInOutPkt)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CGestureHandler::Error(
|
|
/* [in] */ IRealTimeStylus *piRtsSrc,
|
|
/* [in] */ IStylusPlugin *piPlugin,
|
|
/* [in] */ RealTimeStylusDataInterest dataInterest,
|
|
/* [in] */ HRESULT hrErrorCode,
|
|
/* [out][in] */ LONG_PTR *lptrKey)
|
|
{
|
|
CString strError;
|
|
strError.Format(L"An error occured. Error code: %d", hrErrorCode);
|
|
TRACE(strError);
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CGestureHandler::DataInterest(
|
|
/* [retval][out] */ RealTimeStylusDataInterest *pDataInterest)
|
|
{
|
|
*pDataInterest = (RealTimeStylusDataInterest)(RTSDI_CustomStylusDataAdded | RTSDI_Error);
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
/// The remaining interface methods are not used in this sample application
|
|
STDMETHODIMP CGestureHandler::RealTimeStylusEnabled(
|
|
/* [in] */ IRealTimeStylus *piRtsSrc,
|
|
/* [in] */ ULONG cTcidCount,
|
|
/* [size_is][in] */ const TABLET_CONTEXT_ID *pTcids)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CGestureHandler::RealTimeStylusDisabled(
|
|
/* [in] */ IRealTimeStylus *piRtsSrc,
|
|
/* [in] */ ULONG cTcidCount,
|
|
/* [size_is][in] */ const TABLET_CONTEXT_ID *pTcids)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CGestureHandler::StylusInRange(
|
|
/* [in] */ IRealTimeStylus *piRtsSrc,
|
|
/* [in] */ TABLET_CONTEXT_ID tcid,
|
|
/* [in] */ STYLUS_ID sid)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CGestureHandler::StylusOutOfRange(
|
|
/* [in] */ IRealTimeStylus *piRtsSrc,
|
|
/* [in] */ TABLET_CONTEXT_ID tcid,
|
|
/* [in] */ STYLUS_ID sid)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CGestureHandler::StylusButtonDown(
|
|
/* [in] */ IRealTimeStylus *piRtsSrc,
|
|
/* [in] */ STYLUS_ID sid,
|
|
/* [in] */ const GUID *pGuidStylusButton,
|
|
/* [out][in] */ POINT *pStylusPos)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CGestureHandler::StylusButtonUp(
|
|
/* [in] */ IRealTimeStylus *piRtsSrc,
|
|
/* [in] */ STYLUS_ID sid,
|
|
/* [in] */ const GUID *pGuidStylusButton,
|
|
/* [out][in] */ POINT *pStylusPos)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CGestureHandler::InAirPackets(
|
|
/* [in] */ IRealTimeStylus *piRtsSrc,
|
|
/* [in] */ const StylusInfo *pStylusInfo,
|
|
/* [in] */ ULONG cPktCount,
|
|
/* [in] */ ULONG cPktBuffLength,
|
|
/* [size_is][in] */ LONG *pPackets,
|
|
/* [out][in] */ ULONG *pcInOutPkts,
|
|
/* [out][in] */ LONG **ppInOutPkts)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CGestureHandler::CustomStylusDataAdded(
|
|
/* [in] */ IRealTimeStylus *piRtsSrc,
|
|
/* [in] */ const GUID *pGuidId,
|
|
/* [in] */ ULONG cbData,
|
|
/* [in] */ const BYTE *pbData)
|
|
{
|
|
// Did we get passed gesture data?
|
|
if (*pGuidId == GUID_GESTURE_DATA)
|
|
{
|
|
/* See if the data pointer actually points to something.
|
|
If more than one alternate is detected ignore the
|
|
lower alternates */
|
|
if ((pbData != NULL) && (cbData % sizeof(GESTURE_DATA)))
|
|
{
|
|
// Access the data coming as a GESTURE_DATA structure
|
|
GESTURE_DATA* pGD = (GESTURE_DATA*)pbData;
|
|
|
|
CString strStatus;
|
|
CString strGestureId;
|
|
|
|
// Helper function that maps the gesture ID to a string value
|
|
SetGestureString(pGD->gestureId, &strGestureId);
|
|
|
|
strStatus.Format(L"Gesture=%s\tConfidence=%d\tStrokes=%d", strGestureId, pGD->recoConfidence, pGD->strokeCount);
|
|
m_pStatusControl->SetWindowTextW(strStatus);
|
|
}
|
|
else
|
|
{
|
|
m_pStatusControl->SetWindowTextW(L"Not gesture data.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_pStatusControl->SetWindowTextW(L"Not gesture data.");
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CGestureHandler::SystemEvent(
|
|
/* [in] */ IRealTimeStylus *piRtsSrc,
|
|
/* [in] */ TABLET_CONTEXT_ID tcid,
|
|
/* [in] */ STYLUS_ID sid,
|
|
/* [in] */ SYSTEM_EVENT event,
|
|
/* [in] */ SYSTEM_EVENT_DATA eventdata)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CGestureHandler::TabletAdded(
|
|
/* [in] */ IRealTimeStylus *piRtsSrc,
|
|
/* [in] */ IInkTablet *piTablet)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CGestureHandler::TabletRemoved(
|
|
/* [in] */ IRealTimeStylus *piRtsSrc,
|
|
/* [in] */ LONG iTabletIndex)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CGestureHandler::UpdateMapping(
|
|
/* [in] */ IRealTimeStylus *piRtsSrc)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
// Helper functions
|
|
|
|
// Sets a string identifying the gesture
|
|
void CGestureHandler::SetGestureString(int gestureID, CString* strResult)
|
|
{
|
|
switch (gestureID)
|
|
{
|
|
case IAG_AllGestures:
|
|
strResult->SetString(L"AllGestures", sizeof("AllGestures"));
|
|
break;
|
|
|
|
case IAG_NoGesture:
|
|
strResult->SetString(L"NoGesture", sizeof("NoGesture"));
|
|
break;
|
|
|
|
case IAG_Scratchout:
|
|
strResult->SetString(L"Scratchout", sizeof("Scratchout"));
|
|
break;
|
|
|
|
case IAG_Triangle:
|
|
strResult->SetString(L"Triangle", sizeof("Triangle"));
|
|
break;
|
|
|
|
case IAG_Square:
|
|
strResult->SetString(L"Square", sizeof("Square"));
|
|
break;
|
|
|
|
case IAG_Star:
|
|
strResult->SetString(L"Star", sizeof("Star"));
|
|
break;
|
|
|
|
case IAG_Check:
|
|
strResult->SetString(L"Check", sizeof("Check"));
|
|
break;
|
|
|
|
case IAG_Curlicue:
|
|
strResult->SetString(L"Curlicue", sizeof("Curlicue"));
|
|
break;
|
|
|
|
case IAG_DoubleCurlicue:
|
|
strResult->SetString(L"DoubleCurlicue", sizeof("DoubleCurlicue"));
|
|
break;
|
|
|
|
case IAG_Circle:
|
|
strResult->SetString(L"Circle", sizeof("Circle"));
|
|
break;
|
|
|
|
case IAG_DoubleCircle:
|
|
strResult->SetString(L"DoubleCircle", sizeof("DoubleCircle"));
|
|
break;
|
|
|
|
case IAG_SemiCircleLeft:
|
|
strResult->SetString(L"SemiCircleLeft", sizeof("SemiCircleLeft"));
|
|
break;
|
|
|
|
case IAG_SemiCircleRight:
|
|
strResult->SetString(L"SemiCircleRight", sizeof("SemiCircleRight"));
|
|
break;
|
|
|
|
case IAG_ChevronUp:
|
|
strResult->SetString(L"ChevronUp", sizeof("ChevronUp"));
|
|
break;
|
|
|
|
case IAG_ChevronDown:
|
|
strResult->SetString(L"ChevronDown", sizeof("ChevronDown"));
|
|
break;
|
|
|
|
case IAG_ChevronLeft:
|
|
strResult->SetString(L"ChevronLeft", sizeof("ChevronLeft"));
|
|
break;
|
|
|
|
case IAG_ChevronRight:
|
|
strResult->SetString(L"ChevronRight", sizeof("ChevronRight"));
|
|
break;
|
|
|
|
case IAG_ArrowUp:
|
|
strResult->SetString(L"ArrowUp", sizeof("ArrowUp"));
|
|
break;
|
|
|
|
case IAG_ArrowDown:
|
|
strResult->SetString(L"ArrowDown", sizeof("ArrowDown"));
|
|
break;
|
|
|
|
case IAG_ArrowLeft:
|
|
strResult->SetString(L"ArrowLeft", sizeof("ArrowLeft"));
|
|
break;
|
|
|
|
case IAG_ArrowRight:
|
|
strResult->SetString(L"ArrowRight", sizeof("ArrowRight"));
|
|
break;
|
|
|
|
case IAG_Up:
|
|
strResult->SetString(L"Up", sizeof("Up"));
|
|
break;
|
|
|
|
case IAG_Down:
|
|
strResult->SetString(L"Down", sizeof("Down"));
|
|
break;
|
|
|
|
case IAG_Left:
|
|
strResult->SetString(L"Left", sizeof("Left"));
|
|
break;
|
|
|
|
case IAG_Right:
|
|
strResult->SetString(L"Right", sizeof("Right"));
|
|
break;
|
|
|
|
case IAG_UpDown:
|
|
strResult->SetString(L"UpDown", sizeof("UpDown"));
|
|
break;
|
|
|
|
case IAG_DownUp:
|
|
strResult->SetString(L"UpDown", sizeof("UpDown"));
|
|
break;
|
|
|
|
case IAG_LeftRight:
|
|
strResult->SetString(L"UpDown", sizeof("UpDown"));
|
|
break;
|
|
|
|
case IAG_RightLeft:
|
|
strResult->SetString(L"RightLeft", sizeof("RightLeft"));
|
|
break;
|
|
|
|
case IAG_UpLeftLong:
|
|
strResult->SetString(L"UpLeftLong", sizeof("UpLeftLong"));
|
|
break;
|
|
|
|
case IAG_UpRightLong:
|
|
strResult->SetString(L"UpRightLong", sizeof("UpRightLong"));
|
|
break;
|
|
|
|
case IAG_DownLeftLong:
|
|
strResult->SetString(L"DownLeftLong", sizeof("DownLeftLong"));
|
|
break;
|
|
|
|
case IAG_DownRightLong:
|
|
strResult->SetString(L"DownRightLong", sizeof("DownRightLong"));
|
|
break;
|
|
|
|
case IAG_UpLeft:
|
|
strResult->SetString(L"UpLeft", sizeof("UpLeft"));
|
|
break;
|
|
|
|
case IAG_UpRight:
|
|
strResult->SetString(L"UpRight", sizeof("UpRight"));
|
|
break;
|
|
|
|
case IAG_DownLeft:
|
|
strResult->SetString(L"DownLeft", sizeof("DownLeft"));
|
|
break;
|
|
|
|
case IAG_DownRight:
|
|
strResult->SetString(L"DownRight", sizeof("DownRight"));
|
|
break;
|
|
|
|
case IAG_LeftUp:
|
|
strResult->SetString(L"LeftUp", sizeof("LeftUp"));
|
|
break;
|
|
|
|
case IAG_LeftDown:
|
|
strResult->SetString(L"LeftDown", sizeof("LeftDown"));
|
|
break;
|
|
|
|
case IAG_RightUp:
|
|
strResult->SetString(L"RightUp", sizeof("RightUp"));
|
|
break;
|
|
|
|
case IAG_RightDown:
|
|
strResult->SetString(L"RightDown", sizeof("RightDown"));
|
|
break;
|
|
|
|
case IAG_Exclamation:
|
|
strResult->SetString(L"Exclamation", sizeof("Exclamation"));
|
|
break;
|
|
|
|
case IAG_Tap:
|
|
strResult->SetString(L"Tap", sizeof("Tap"));
|
|
break;
|
|
|
|
case IAG_DoubleTap:
|
|
strResult->SetString(L"DoubleTap", sizeof("DoubleTap"));
|
|
break;
|
|
|
|
default:
|
|
strResult->SetString(L"Unknown", sizeof("Unknown"));
|
|
break;
|
|
}
|
|
}
|