// // 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; }