290 lines
6.9 KiB
C++
290 lines
6.9 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 2001 Microsoft Corporation. All Rights Reserved.
|
|
**************************************************************************/
|
|
|
|
/**************************************************************************
|
|
|
|
File: Monitor.cpp
|
|
|
|
Description:
|
|
|
|
**************************************************************************/
|
|
|
|
/**************************************************************************
|
|
#include statements
|
|
**************************************************************************/
|
|
|
|
#include "Monitor.h"
|
|
|
|
/**************************************************************************
|
|
global variables and definitions
|
|
**************************************************************************/
|
|
|
|
/**************************************************************************
|
|
|
|
CCompartmentMonitor::CCompartmentMonitor()
|
|
|
|
**************************************************************************/
|
|
|
|
CCompartmentMonitor::CCompartmentMonitor(void)
|
|
{
|
|
m_dwRef = 1;
|
|
m_dwCookie = 0;
|
|
m_pCompartment = NULL;
|
|
m_guidCompartment = GUID_NULL;
|
|
m_pCallback = NULL;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CCompartmentMonitor::~CCompartmentMonitor()
|
|
|
|
**************************************************************************/
|
|
|
|
CCompartmentMonitor::~CCompartmentMonitor()
|
|
{
|
|
Uninitialize();
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CCompartmentMonitor::Initialize()
|
|
|
|
**************************************************************************/
|
|
|
|
HRESULT CCompartmentMonitor::Initialize( const GUID *pguidCompartment,
|
|
PCOMPARTMENTMONITORPROC pCallback,
|
|
LPARAM lParam)
|
|
{
|
|
if(!IsEqualGUID(m_guidCompartment, GUID_NULL))
|
|
{
|
|
//Initialize() has already been called
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
m_guidCompartment = *pguidCompartment;
|
|
m_pCallback = pCallback;
|
|
m_lParam = lParam;
|
|
|
|
HRESULT hr;
|
|
ITfThreadMgr *pThreadMgr;
|
|
|
|
//create a thread manager object
|
|
hr = CoCreateInstance(CLSID_TF_ThreadMgr,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_ITfThreadMgr,
|
|
(void**)&pThreadMgr);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
ITfCompartmentMgr *pCompMgr;
|
|
|
|
//get the global compartment manager
|
|
hr = pThreadMgr->GetGlobalCompartment(&pCompMgr);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
//get the Speech UI compartment
|
|
hr = pCompMgr->GetCompartment(m_guidCompartment,
|
|
&m_pCompartment);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
ITfSource *pSource;
|
|
|
|
//install the advise sink
|
|
hr = m_pCompartment->QueryInterface(IID_ITfSource,
|
|
(LPVOID*)&pSource);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = pSource->AdviseSink(IID_ITfCompartmentEventSink,
|
|
(ITfCompartmentEventSink*)this,
|
|
&m_dwCookie);
|
|
}
|
|
|
|
//if something went wrong, release the member interface
|
|
if(FAILED(hr))
|
|
{
|
|
m_pCompartment->Release();
|
|
m_pCompartment = NULL;
|
|
}
|
|
}
|
|
|
|
//release the compartment manager
|
|
pCompMgr->Release();
|
|
}
|
|
|
|
//release the thread manager
|
|
pThreadMgr->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CCompartmentMonitor::Uninitialize()
|
|
|
|
**************************************************************************/
|
|
|
|
HRESULT CCompartmentMonitor::Uninitialize(void)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if(m_pCompartment)
|
|
{
|
|
ITfSource *pSource;
|
|
|
|
hr = m_pCompartment->QueryInterface(IID_ITfSource, (void **)&pSource);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = pSource->UnadviseSink(m_dwCookie);
|
|
|
|
pSource->Release();
|
|
}
|
|
|
|
m_pCompartment->Release();
|
|
m_pCompartment = NULL;
|
|
}
|
|
|
|
m_guidCompartment = GUID_NULL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// IUnknown
|
|
//
|
|
|
|
/**************************************************************************
|
|
|
|
CCompartmentMonitor::QueryInterface()
|
|
|
|
**************************************************************************/
|
|
|
|
STDAPI CCompartmentMonitor::QueryInterface(REFIID riid, void **ppvObj)
|
|
{
|
|
*ppvObj = NULL;
|
|
|
|
if (IsEqualIID(riid, IID_IUnknown) ||
|
|
IsEqualIID(riid, IID_ITfCompartmentEventSink))
|
|
{
|
|
*ppvObj = (ITfCompartmentEventSink*)this;
|
|
}
|
|
|
|
if (*ppvObj)
|
|
{
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CCompartmentMonitor::AddRef()
|
|
|
|
**************************************************************************/
|
|
|
|
STDAPI_(ULONG) CCompartmentMonitor::AddRef()
|
|
{
|
|
return ++m_dwRef;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CCompartmentMonitor::Release()
|
|
|
|
**************************************************************************/
|
|
|
|
STDAPI_(ULONG) CCompartmentMonitor::Release()
|
|
{
|
|
m_dwRef--;
|
|
|
|
if(0 == m_dwRef)
|
|
{
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
return m_dwRef;
|
|
}
|
|
|
|
//
|
|
// ITfCompartmentEventSink
|
|
//
|
|
|
|
/**************************************************************************
|
|
|
|
CCompartmentMonitor::OnChange()
|
|
|
|
**************************************************************************/
|
|
|
|
STDAPI CCompartmentMonitor::OnChange(REFGUID rguid)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if(IsEqualGUID(rguid, m_guidCompartment))
|
|
{
|
|
GUID guid = m_guidCompartment;
|
|
BOOL fStatus;
|
|
|
|
GetStatus(&fStatus);
|
|
|
|
//notify the status of this compartment has changed
|
|
hr = (*m_pCallback)(&guid, fStatus, m_lParam);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/**************************************************************************
|
|
|
|
CCompartmentMonitor::GetStatus()
|
|
|
|
**************************************************************************/
|
|
|
|
HRESULT CCompartmentMonitor::GetStatus(BOOL *pfEnabled)
|
|
{
|
|
if(NULL == pfEnabled)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
if(!m_pCompartment)
|
|
{
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
HRESULT hr;
|
|
VARIANT var;
|
|
|
|
VariantInit(&var);
|
|
hr = m_pCompartment->GetValue(&var);
|
|
if(S_OK == hr)
|
|
{
|
|
switch(var.vt)
|
|
{
|
|
case VT_I4:
|
|
*pfEnabled = var.lVal;
|
|
break;
|
|
}
|
|
|
|
VariantClear(&var);
|
|
}
|
|
else
|
|
{
|
|
//this usually means the text service is not installed
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
|
|
return S_OK;
|
|
}
|