259 lines
7.0 KiB
C++
259 lines
7.0 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.
|
|
//
|
|
// Module:
|
|
// EventSinks.h
|
|
//
|
|
// Description:
|
|
// This file contains definitions of the event sink templates,
|
|
// further inherited by the CMathInputControlEventListener class.
|
|
//
|
|
// Event source interface used is:
|
|
// _IMathInputControlEvents
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
// IDispEventSimpleImpl requires a constant as a sink id
|
|
#define SINK_ID 1
|
|
|
|
/////////////////////////////////////////////////////////
|
|
//
|
|
// IMathInputControlEvents
|
|
//
|
|
// The IMathInputControlEvents class handles passing of Math Input Control
|
|
// events from Math Input Control to the user of this class.
|
|
// It sets up connection between the IMathInputControl and
|
|
// this class in AdviseMathInputControl method. In the Invoke method,
|
|
// it converts the IDispatch event notification into a
|
|
// call to a virtual function which the user of this class
|
|
// can override to process a particular event.
|
|
//
|
|
/////////////////////////////////////////////////////////
|
|
|
|
class IMathInputControlEvents: public _IMathInputControlEvents
|
|
{
|
|
public:
|
|
|
|
//
|
|
// IUnknown Interface
|
|
//
|
|
HRESULT __stdcall QueryInterface(REFIID riid, void **ppvObject)
|
|
{
|
|
// Validate the input
|
|
if (NULL == ppvObject)
|
|
{
|
|
return E_POINTER;
|
|
}
|
|
|
|
// This object only supports IDispatch/_IMathInputControlEvents
|
|
if ((riid == IID_IUnknown)
|
|
|| (riid == IID_IDispatch)
|
|
|| (riid == DIID__IMathInputControlEvents))
|
|
{
|
|
*ppvObject = (IDispatch *) this;
|
|
|
|
// Note: we do not AddRef here because the lifetime
|
|
// of this object does not depend on reference counting
|
|
// but on the duration of the connection set up by
|
|
// the user of this class.
|
|
return S_OK;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
virtual ULONG STDMETHODCALLTYPE AddRef()
|
|
{
|
|
// Note: we do not AddRef here because the lifetime
|
|
// of this object does not depend on reference counting
|
|
// but on the duration of the connection set up by
|
|
// the user of this class.
|
|
return 1;
|
|
}
|
|
|
|
virtual ULONG STDMETHODCALLTYPE Release()
|
|
{
|
|
// Note: we do not do Release here because the lifetime
|
|
// of this object does not depend on reference counting
|
|
// but on the duration of the connection set up by
|
|
// the user of this class.
|
|
return 1;
|
|
}
|
|
|
|
//
|
|
// IDispatch Interface
|
|
//
|
|
STDMETHOD(GetTypeInfoCount)(UINT* /*pctinfo*/)
|
|
{
|
|
// This method is not needed for processing events
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHOD(GetTypeInfo)(
|
|
UINT /*itinfo*/,
|
|
LCID /*lcid*/,
|
|
ITypeInfo** /*pptinfo*/)
|
|
{
|
|
// This method is not needed for processing events
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHOD(GetIDsOfNames)(
|
|
REFIID /*riid*/,
|
|
LPOLESTR* /*rgszNames*/,
|
|
UINT /*cNames*/,
|
|
LCID /*lcid*/,
|
|
DISPID* /*rgdispid*/)
|
|
{
|
|
// This method is not needed for processing events
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
// Invoke translates from IDispatch to an event callout
|
|
// that can be overriden by a subclass of this class
|
|
STDMETHOD(Invoke)(
|
|
DISPID dispidMember,
|
|
REFIID /*riid*/,
|
|
LCID /*lcid*/,
|
|
WORD /*wFlags*/,
|
|
DISPPARAMS* pdispparams,
|
|
VARIANT* /*pvarResult*/,
|
|
EXCEPINFO* /*pexcepinfo*/,
|
|
UINT* /*puArgErr*/)
|
|
{
|
|
switch(dispidMember)
|
|
{
|
|
case DISPID_MICInsert:
|
|
OnMICInsert((BSTR)pdispparams->rgvarg[0].bstrVal);
|
|
break;
|
|
|
|
case DISPID_MICClose:
|
|
OnMICClose();
|
|
break;
|
|
|
|
case DISPID_MICClear:
|
|
OnMICClear();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//
|
|
// Events
|
|
// Pure virtual functions that will be overriden in the main class
|
|
//
|
|
virtual HRESULT OnMICInsert(BSTR RecoResult) = 0;
|
|
virtual HRESULT OnMICClose(void) = 0;
|
|
virtual HRESULT OnMICClear(void) = 0;
|
|
|
|
//
|
|
// Methods
|
|
//
|
|
|
|
// Constructor
|
|
IMathInputControlEvents()
|
|
{
|
|
m_pIConnectionPoint = NULL;
|
|
}
|
|
|
|
// Destructor
|
|
~IMathInputControlEvents()
|
|
{
|
|
UnadviseMathInputControl();
|
|
}
|
|
|
|
// Set up connection between sink and Math Input Control
|
|
HRESULT AdviseMathInputControl(
|
|
IMathInputControl *pIMathInputControl)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Check to ensure that the sink is not currently connected
|
|
// with another Math Input Control...
|
|
if (NULL == m_pIConnectionPoint)
|
|
{
|
|
// Get the connection point container
|
|
IConnectionPointContainer *pIConnectionPointContainer;
|
|
hr = pIMathInputControl->QueryInterface(
|
|
IID_IConnectionPointContainer,
|
|
(void **) &pIConnectionPointContainer);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
// Find the connection point for Math Input Control events
|
|
hr = pIConnectionPointContainer->FindConnectionPoint(
|
|
__uuidof(_IMathInputControlEvents), &m_pIConnectionPoint);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Hook up sink to connection point
|
|
hr = m_pIConnectionPoint->Advise(this, &m_dwCookie);
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
// Clean up after an error
|
|
if (m_pIConnectionPoint)
|
|
{
|
|
m_pIConnectionPoint->Release();
|
|
m_pIConnectionPoint = NULL;
|
|
}
|
|
}
|
|
|
|
// We don't need the connection point container any more
|
|
pIConnectionPointContainer->Release();
|
|
}
|
|
// If the sink is already connected to a Math Input Control, return a
|
|
// failure. Only one Math Input Control can be attached at any given time.
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// Remove the connection of the sink to the Math Input Control
|
|
HRESULT UnadviseMathInputControl()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// If some Math Input Control is connected to the sink,
|
|
// remove it. Otherwise, do nothing (there is nothing
|
|
// to unadvise).
|
|
if (m_pIConnectionPoint != NULL)
|
|
{
|
|
hr = m_pIConnectionPoint->Unadvise(m_dwCookie);
|
|
m_pIConnectionPoint->Release();
|
|
m_pIConnectionPoint = NULL;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
private:
|
|
|
|
//
|
|
// Data Members
|
|
//
|
|
|
|
// Connection point on Math Input Control
|
|
IConnectionPoint *m_pIConnectionPoint;
|
|
|
|
// Cookie returned from advise
|
|
DWORD m_dwCookie;
|
|
};
|