You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
476 lines
12 KiB
476 lines
12 KiB
//
|
|
// computil.cpp
|
|
//
|
|
|
|
#include "private.h"
|
|
#include "computil.h"
|
|
#include "catutil.h"
|
|
#include "helpers.h"
|
|
|
|
ITfCategoryMgr *GetUIMCat();
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// GetCompartment
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HRESULT GetCompartment(IUnknown *punk, REFGUID rguidComp, ITfCompartment **ppComp, BOOL fGlobal)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
ITfCompartmentMgr *pCompMgr = NULL;
|
|
ITfThreadMgr *ptim = NULL;
|
|
|
|
Assert(ppComp);
|
|
*ppComp = NULL;
|
|
|
|
if (fGlobal)
|
|
{
|
|
if (FAILED(hr = punk->QueryInterface(IID_ITfThreadMgr,
|
|
(void **)&ptim)))
|
|
goto Exit;
|
|
|
|
if (FAILED(hr = ptim->GetGlobalCompartment(&pCompMgr)))
|
|
goto Exit;
|
|
|
|
}
|
|
else
|
|
{
|
|
if (FAILED(hr = punk->QueryInterface(IID_ITfCompartmentMgr,
|
|
(void **)&pCompMgr)))
|
|
goto Exit;
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && pCompMgr)
|
|
{
|
|
hr = pCompMgr->GetCompartment(rguidComp, ppComp);
|
|
pCompMgr->Release();
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
|
|
Exit:
|
|
if (ptim)
|
|
ptim->Release();
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// SetCompartmentDWORD
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HRESULT SetCompartmentDWORD(TfClientId tid, IUnknown *punk, REFGUID rguidComp, DWORD dw, BOOL fGlobal)
|
|
{
|
|
HRESULT hr;
|
|
ITfCompartment *pComp;
|
|
VARIANT var;
|
|
|
|
if (SUCCEEDED(hr = GetCompartment(punk, rguidComp, &pComp, fGlobal)))
|
|
{
|
|
var.vt = VT_I4;
|
|
var.lVal = dw;
|
|
hr = pComp->SetValue(tid, &var);
|
|
pComp->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// GetCompartmentDWORD
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HRESULT GetCompartmentDWORD(IUnknown *punk, REFGUID rguidComp, DWORD *pdw, BOOL fGlobal)
|
|
{
|
|
HRESULT hr;
|
|
ITfCompartment *pComp;
|
|
VARIANT var;
|
|
|
|
*pdw = 0;
|
|
if (SUCCEEDED(hr = GetCompartment(punk, rguidComp, &pComp, fGlobal)))
|
|
{
|
|
if ((hr = pComp->GetValue(&var)) == S_OK)
|
|
{
|
|
Assert(var.vt == VT_I4);
|
|
*pdw = var.lVal;
|
|
}
|
|
pComp->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// ToggleCompartmentDWORD
|
|
//
|
|
// Toggle DWORD value between 0 and 1.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HRESULT ToggleCompartmentDWORD(TfClientId tid, IUnknown *punk, REFGUID rguidComp, BOOL fGlobal)
|
|
{
|
|
HRESULT hr;
|
|
ITfCompartment *pComp;
|
|
VARIANT var;
|
|
|
|
if (SUCCEEDED(hr = GetCompartment(punk, rguidComp, &pComp, fGlobal)))
|
|
{
|
|
if ((hr = pComp->GetValue(&var)) == S_OK)
|
|
{
|
|
Assert(var.vt == VT_I4);
|
|
var.lVal = !var.lVal;
|
|
hr = pComp->SetValue(tid, &var);
|
|
}
|
|
else
|
|
{
|
|
var.vt = VT_I4;
|
|
var.lVal = 0x01;
|
|
hr = pComp->SetValue(tid, &var);
|
|
}
|
|
pComp->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// SetCompartmentGUIDATOM
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HRESULT SetCompartmentGUIDATOM(TfClientId tid, IUnknown *punk, REFGUID rguidComp, TfGuidAtom guidatom, BOOL fGlobal)
|
|
{
|
|
HRESULT hr;
|
|
ITfCompartment *pComp;
|
|
VARIANT var;
|
|
|
|
if (SUCCEEDED(hr = GetCompartment(punk, rguidComp, &pComp, fGlobal)))
|
|
{
|
|
var.vt = VT_I4;
|
|
var.lVal = guidatom;
|
|
hr = pComp->SetValue(tid, &var);
|
|
pComp->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// GetCompartmentGUIDATOM
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HRESULT GetCompartmentGUIDATOM(IUnknown *punk, REFGUID rguidComp, TfGuidAtom *pga, BOOL fGlobal)
|
|
{
|
|
HRESULT hr;
|
|
ITfCompartment *pComp;
|
|
VARIANT var;
|
|
|
|
*pga = 0;
|
|
if (SUCCEEDED(hr = GetCompartment(punk, rguidComp, &pComp, fGlobal)))
|
|
{
|
|
if ((hr = pComp->GetValue(&var)) == S_OK)
|
|
{
|
|
Assert(var.vt == VT_I4);
|
|
*pga = (TfGuidAtom)var.lVal;;
|
|
}
|
|
pComp->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// SetCompartmentGUID
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HRESULT SetCompartmentGUID(LIBTHREAD *plt, TfClientId tid, IUnknown *punk, REFGUID rguidComp, REFGUID rguid, BOOL fGlobal)
|
|
{
|
|
TfGuidAtom ga;
|
|
|
|
if (!GetGUIDATOMFromGUID(plt, rguid, &ga))
|
|
return E_FAIL;
|
|
|
|
if (FAILED(SetCompartmentGUIDATOM(tid, punk, rguidComp, ga, fGlobal)))
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// GetCompartmentGUID
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HRESULT GetCompartmentGUID(LIBTHREAD *plt, IUnknown *punk, REFGUID rguidComp, GUID *pguid, BOOL fGlobal)
|
|
{
|
|
TfGuidAtom ga;
|
|
if (FAILED(GetCompartmentGUIDATOM(punk, rguidComp, &ga, fGlobal)))
|
|
return E_FAIL;
|
|
|
|
if (GetGUIDFromGUIDATOM(plt, ga, pguid))
|
|
return S_OK;
|
|
|
|
return E_FAIL;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// GetCompartmentUnknown
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HRESULT GetCompartmentUnknown(IUnknown *punk, REFGUID rguidComp, IUnknown **ppunk)
|
|
{
|
|
HRESULT hr;
|
|
ITfCompartment *pComp;
|
|
VARIANT var;
|
|
|
|
*ppunk = NULL;
|
|
if (SUCCEEDED(hr = GetCompartment(punk, rguidComp, &pComp, FALSE)))
|
|
{
|
|
if ((hr = pComp->GetValue(&var)) == S_OK)
|
|
{
|
|
Assert(var.vt == VT_UNKNOWN);
|
|
*ppunk = var.punkVal;
|
|
}
|
|
pComp->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// SetCompartmentUnknown
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HRESULT SetCompartmentUnknown(TfClientId tid, IUnknown *punk, REFGUID rguidComp, IUnknown *punkPriv)
|
|
{
|
|
HRESULT hr;
|
|
ITfCompartment *pComp;
|
|
VARIANT var;
|
|
|
|
if (SUCCEEDED(hr = GetCompartment(punk, rguidComp, &pComp, FALSE)))
|
|
{
|
|
var.vt = VT_UNKNOWN;
|
|
var.punkVal = punkPriv;
|
|
hr = pComp->SetValue(tid, &var);
|
|
pComp->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// ClearCompartment
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HRESULT ClearCompartment(TfClientId tid, IUnknown *punk, REFGUID rguidComp, BOOL fGlobal)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
ITfCompartmentMgr *pCompMgr = NULL;
|
|
ITfThreadMgr *ptim = NULL;
|
|
|
|
if (fGlobal)
|
|
{
|
|
if (FAILED(hr = punk->QueryInterface(IID_ITfThreadMgr,
|
|
(void **)&ptim)))
|
|
goto Exit;
|
|
|
|
if (FAILED(hr = ptim->GetGlobalCompartment(&pCompMgr)))
|
|
goto Exit;
|
|
|
|
}
|
|
else
|
|
{
|
|
if (FAILED(hr = punk->QueryInterface(IID_ITfCompartmentMgr,
|
|
(void **)&pCompMgr)))
|
|
goto Exit;
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && pCompMgr)
|
|
{
|
|
hr = pCompMgr->ClearCompartment(tid, rguidComp);
|
|
pCompMgr->Release();
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
|
|
Exit:
|
|
if (ptim)
|
|
ptim->Release();
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CCompartmentEventSink
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// IUnknown
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CCompartmentEventSink::QueryInterface(REFIID riid, void **ppvObj)
|
|
{
|
|
*ppvObj = NULL;
|
|
|
|
if (IsEqualIID(riid, IID_IUnknown) ||
|
|
IsEqualIID(riid, IID_ITfCompartmentEventSink))
|
|
{
|
|
*ppvObj = SAFECAST(this, ITfCompartmentEventSink *);
|
|
}
|
|
|
|
if (*ppvObj)
|
|
{
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
STDAPI_(ULONG) CCompartmentEventSink::AddRef()
|
|
{
|
|
return ++_cRef;
|
|
}
|
|
|
|
STDAPI_(ULONG) CCompartmentEventSink::Release()
|
|
{
|
|
long cr;
|
|
|
|
cr = --_cRef;
|
|
Assert(cr >= 0);
|
|
|
|
if (cr == 0)
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
return cr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// ctor
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CCompartmentEventSink::CCompartmentEventSink(CESCALLBACK pfnCallback, void *pv)
|
|
{
|
|
Dbg_MemSetThisName(TEXT("CCompartmentEventSink"));
|
|
|
|
_cRef = 1;
|
|
|
|
_pfnCallback = pfnCallback;
|
|
_pv = pv;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// OnChange
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CCompartmentEventSink::OnChange(REFGUID rguid)
|
|
{
|
|
return _pfnCallback(_pv, rguid);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// CCompartmentEventSink::Advise
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HRESULT CCompartmentEventSink::_Advise(IUnknown *punk, REFGUID rguidComp, BOOL fGlobal)
|
|
{
|
|
HRESULT hr;
|
|
ITfSource *pSource = NULL;
|
|
CESMAP *pcesmap;
|
|
pcesmap = _rgcesmap.Append(1);
|
|
if (!pcesmap)
|
|
return E_OUTOFMEMORY;
|
|
|
|
hr = E_FAIL;
|
|
|
|
if (FAILED(hr = GetCompartment(punk, rguidComp, &pcesmap->pComp, fGlobal)))
|
|
goto Exit;
|
|
|
|
if (FAILED(hr = pcesmap->pComp->QueryInterface(IID_ITfSource, (void **)&pSource)))
|
|
goto Exit;
|
|
|
|
if (FAILED(hr = pSource->AdviseSink(IID_ITfCompartmentEventSink, (ITfCompartmentEventSink *)this, &pcesmap->dwCookie)))
|
|
goto Exit;
|
|
|
|
hr = S_OK;
|
|
|
|
Exit:
|
|
if (FAILED(hr))
|
|
{
|
|
int nCnt;
|
|
SafeReleaseClear(pcesmap->pComp);
|
|
nCnt = _rgcesmap.Count();
|
|
_rgcesmap.Remove(nCnt - 1, 1);
|
|
}
|
|
|
|
SafeRelease(pSource);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// CCompartmentEventSink::Unadvise
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HRESULT CCompartmentEventSink::_Unadvise()
|
|
{
|
|
HRESULT hr;
|
|
int nCnt;
|
|
CESMAP *pcesmap;
|
|
|
|
hr = E_FAIL;
|
|
|
|
|
|
nCnt = _rgcesmap.Count();
|
|
pcesmap = _rgcesmap.GetPtr(0);
|
|
|
|
while (nCnt)
|
|
{
|
|
ITfSource *pSource = NULL;
|
|
if (FAILED(pcesmap->pComp->QueryInterface(IID_ITfSource, (void **)&pSource)))
|
|
goto Next;
|
|
|
|
if (FAILED(pSource->UnadviseSink(pcesmap->dwCookie)))
|
|
goto Next;
|
|
|
|
Next:
|
|
SafeReleaseClear(pcesmap->pComp);
|
|
SafeRelease(pSource);
|
|
nCnt--;
|
|
pcesmap++;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
return hr;
|
|
}
|