#include "pch.h" #include #include #define ASSERT assert #include #include "ManipulationEventSink.h" namespace ManipulationHelper { ManipulationEventSink::ManipulationEventSink() : m_cRefCount(1), m_pConnection(NULL), m_dwCookie(0) { } bool ManipulationEventSink::Connect(IManipulationProcessor* pManipulationProcessor) { // Check input arguments if (pManipulationProcessor == NULL) { ASSERT((pManipulationProcessor != NULL) && L"CManipulationEventSink::Create : incorrect arguments"); return false; } // Check object state if ((m_dwCookie != 0) || (m_pConnection != NULL)) { ASSERT((m_dwCookie == 0) && (m_pConnection == NULL) && L"CManipulationEventSink::Connect : connection already established"); return false; } // Get the container with the connection points. IConnectionPointContainer* pConnectionContainer = NULL; HRESULT hr = pManipulationProcessor->QueryInterface(&pConnectionContainer); if (FAILED(hr)) { ASSERT(SUCCEEDED(hr) && L"CManipulationEventSink::Connect : failed to get the container with the connection points"); return false; } // Get a connection point. hr = pConnectionContainer->FindConnectionPoint(__uuidof(_IManipulationEvents), &m_pConnection); if (FAILED(hr)) { ASSERT(SUCCEEDED(hr) && L"CManipulationEventSink::Connect : failed to get a connection point"); pConnectionContainer->Release(); return false; } // Release the connection container. pConnectionContainer->Release(); // Advise. Establishes an advisory connection between the connection point and the // caller's sink object. hr = m_pConnection->Advise(this, &m_dwCookie); if (FAILED(hr)) { ASSERT(SUCCEEDED(hr) && L"CManipulationEventSink::Connect : failed to Advise"); m_pConnection->Release(); m_pConnection = NULL; return false; } m_pIManipProc = pManipulationProcessor; return true; } bool ManipulationEventSink::Disconnect() { // Check object state if ((m_dwCookie == 0) || (m_pConnection == NULL)) { ASSERT((m_dwCookie != 0) && (m_pConnection != NULL) && L"CManipulationEventSink::Disconnect : connection does not exist"); return false; } // Unadvise. Terminate the connection. HRESULT hr = m_pConnection->Unadvise(m_dwCookie); ASSERT(SUCCEEDED(hr) && L"CManipulationEventSink::Disconnect : failed to Unadvise"); UNREFERENCED_PARAMETER(hr); m_pConnection->Release(); m_pConnection = NULL; m_dwCookie = 0; return true; } void ManipulationEventSink::SetManipulationStartedCallBack(ManipulationStartedCallBack msCallback) { m_mStartedCallBack = msCallback; } void ManipulationEventSink::SetManipulationDeltaCallBack(ManipulationDeltaCallBack mdCallback) { m_mDeltaCallBack = mdCallback; } void ManipulationEventSink::SetManipulationCompletedCallBack(ManipulationCompletedCallBack mcCallback) { m_mCompletedCallBack = mcCallback; } ManipulationEventSink::~ManipulationEventSink() { ASSERT((m_dwCookie == 0) && (m_pConnection == NULL) && L"CManipulationEventSink destructor : connection is not properly terminated"); } HRESULT STDMETHODCALLTYPE ManipulationEventSink::ManipulationStarted( FLOAT x, FLOAT y) { if (m_mStartedCallBack != NULL) { m_mStartedCallBack(x, y); } return S_OK; } // This event is called by the ManipulationProcessor during the movement of // the fingers. // in: // x - x coordiante of the initial point of manipulation // (1/100 of pixel) // y - y coordiante of the initial point of manipulation // (1/100 of pixel) // translationDeltaX - shift of the x-coordinate (1/100 of pixel) // translationDeltaY - shift of the y-coordinate (1/100 of pixel) // scaleDelta - scale factor (zoom in/out) // expansionDelta - the current rate of scale change // rotationDelta - rotation angle in radians // cumulativeTranslationX - cumulative shift of x-coordinate (1/100 of pixel) // cumulativeTranslationY - cumulative shift of y-coordinate (1/100 of pixel) // cumulativeScale - cumulative scale factor (zoom in/out) // cumulativeExpansion - cumulative rate of scale change // cumulativeRotation - cumulative rotation angle in radians HRESULT STDMETHODCALLTYPE ManipulationEventSink::ManipulationDelta( FLOAT x, FLOAT y, FLOAT translationDeltaX, FLOAT translationDeltaY, FLOAT scaleDelta, FLOAT expansionDelta, FLOAT rotationDelta, FLOAT cumulativeTranslationX, FLOAT cumulativeTranslationY, FLOAT cumulativeScale, FLOAT cumulativeExpansion, FLOAT cumulativeRotation) { if (m_mDeltaCallBack != NULL) { m_mDeltaCallBack( x, y, translationDeltaX, translationDeltaY, scaleDelta, expansionDelta, rotationDelta, cumulativeTranslationX, cumulativeTranslationY, cumulativeScale, cumulativeExpansion, cumulativeRotation); } return S_OK; } HRESULT STDMETHODCALLTYPE ManipulationEventSink::ManipulationCompleted( FLOAT x, FLOAT y, FLOAT cumulativeTranslationX, FLOAT cumulativeTranslationY, FLOAT cumulativeScale, FLOAT cumulativeExpansion, FLOAT cumulativeRotation) { m_mCompletedCallBack( x, y, cumulativeTranslationX, cumulativeTranslationY, cumulativeScale, cumulativeExpansion, cumulativeRotation); return S_OK; } // IUnknown implementation ULONG ManipulationEventSink::AddRef(void) { return InterlockedIncrement(&m_cRefCount); } ULONG ManipulationEventSink::Release(void) { ULONG cNewRefCount = InterlockedDecrement(&m_cRefCount); if (cNewRefCount == 0) { delete this; } return cNewRefCount; } HRESULT ManipulationEventSink::QueryInterface(REFIID riid, LPVOID* ppvObj) { if ((riid == __uuidof(_IManipulationEvents)) || (riid == IID_IUnknown)) { *ppvObj = this; AddRef(); return S_OK; } *ppvObj = NULL; return E_NOINTERFACE; } }