void TextService::setCompositionString(EditSession* session, const wchar_t* str, int len) { ITfContext* context = session->context(); if(context) { TfEditCookie editCookie = session->editCookie(); TF_SELECTION selection; ULONG selectionNum; // get current selection/insertion point if(context->GetSelection(editCookie, TF_DEFAULT_SELECTION, 1, &selection, &selectionNum) == S_OK) { ComPtr<ITfRange> compositionRange; if(composition_->GetRange(&compositionRange) == S_OK) { bool selPosInComposition = true; // if current insertion point is not covered by composition, we cannot insert text here. if(selPosInComposition) { // replace context of composion area with the new string. compositionRange->SetText(editCookie, TF_ST_CORRECTION, str, len); // move the insertion point to end of the composition string selection.range->Collapse(editCookie, TF_ANCHOR_END); context->SetSelection(editCookie, 1, &selection); } // set display attribute to the composition range ComPtr<ITfProperty> dispAttrProp; if(context->GetProperty(GUID_PROP_ATTRIBUTE, &dispAttrProp) == S_OK) { VARIANT val; val.vt = VT_I4; val.lVal = module_->inputAttrib()->atom(); dispAttrProp->SetValue(editCookie, compositionRange, &val); } } selection.range->Release(); } } }
// callback from edit session for starting composition HRESULT TextService::doStartCompositionEditSession(TfEditCookie cookie, StartCompositionEditSession* session) { ITfContext* context = session->context(); ITfContextComposition* contextComposition; if(context->QueryInterface(IID_ITfContextComposition, (void**)&contextComposition) == S_OK) { // get current insertion point in the current context ITfRange* range = NULL; ITfInsertAtSelection* insertAtSelection; if(context->QueryInterface(IID_ITfInsertAtSelection, (void **)&insertAtSelection) == S_OK) { // get current selection range & insertion position (query only, did not insert any text) insertAtSelection->InsertTextAtSelection(cookie, TF_IAS_QUERYONLY, NULL, 0, &range); insertAtSelection->Release(); } if(range) { if(contextComposition->StartComposition(cookie, range, (ITfCompositionSink*)this, &composition_) == S_OK) { // according to the TSF sample provided by M$, we need to reset current // selection here. (maybe the range is altered by StartComposition()? // So mysterious. TSF is absolutely overly-engineered! TF_SELECTION selection; selection.range = range; selection.style.ase = TF_AE_NONE; selection.style.fInterimChar = FALSE; context->SetSelection(cookie, 1, &selection); // we did not release composition_ object. we store it for use later } range->Release(); } contextComposition->Release(); } return S_OK; }
void CMarkTextService::_ClearCompositionDisplayAttributes(TfEditCookie ec) { ITfRange *pRangeComposition; ITfContext *pContext; ITfProperty *pDisplayAttributeProperty; // we need a range and the context it lives in if (_pComposition->GetRange(&pRangeComposition) != S_OK) return; if (pRangeComposition->GetContext(&pContext) != S_OK) { pContext = NULL; goto Exit; } // get our the display attribute property if (pContext->GetProperty(GUID_PROP_ATTRIBUTE, &pDisplayAttributeProperty) != S_OK) goto Exit; // clear the value over the range pDisplayAttributeProperty->Clear(ec, pRangeComposition); pDisplayAttributeProperty->Release(); Exit: pRangeComposition->Release(); SafeRelease(pContext); }
/* static */ void CMarkTextService::_Menu_OnComposition(CMarkTextService *_this) { ITfDocumentMgr *pFocusDoc; ITfContext *pContext; CCompositionEditSession *pCompositionEditSession; HRESULT hr; // get the focus document if (_this->_pThreadMgr->GetFocus(&pFocusDoc) != S_OK) return; // we want the topmost context, since the main doc context could be // superceded by a modal tip context if (pFocusDoc->GetTop(&pContext) != S_OK) { pContext = NULL; goto Exit; } if (pCompositionEditSession = new CCompositionEditSession(pContext, _this)) { // we need a document write lock // the CCompositionEditSession will do all the work when the // CCompositionEditSession::DoEditSession method is called by the context pContext->RequestEditSession(_this->_tfClientId, pCompositionEditSession, TF_ES_READWRITE | TF_ES_ASYNCDONTCARE, &hr); pCompositionEditSession->Release(); } Exit: SafeRelease(pContext); pFocusDoc->Release(); }
STDAPI CDIME::OnCompositionTerminated(TfEditCookie ecWrite, _In_ ITfComposition *pComposition) { debugPrint(L"CDIME::OnCompositionTerminated()"); HRESULT hr = S_OK; ITfContext* pContext = _pContext; // Clear dummy composition _RemoveDummyCompositionForComposing(ecWrite, pComposition); // Clear display attribute and end composition, _EndComposition will release composition for us if (pContext) { pContext->AddRef(); } _EndComposition(pContext); _DeleteCandidateList(TRUE, pContext); if (pContext) { pContext->Release(); pContext = nullptr; } return hr; }
void CTextService::InsertHello() { ITfDocumentMgr *pDocMgrFocus; ITfContext *pContext; CInsertHelloEditSession *pInsertHelloEditSession; HRESULT hr; // get the focus document if (_pThreadMgr->GetFocus(&pDocMgrFocus) != S_OK) return; // we want the topmost context, since the main doc context could be // superceded by a modal tip context if (pDocMgrFocus->GetTop(&pContext) != S_OK) { pContext = NULL; goto Exit; } if (pInsertHelloEditSession = new CInsertHelloEditSession(pContext)) { // we need a document write lock to insert text // the CInsertHelloEditSession will do all the work when the // CInsertHelloEditSession::DoEditSession method is called by the context pContext->RequestEditSession(_tfClientId, pInsertHelloEditSession, TF_ES_READWRITE | TF_ES_ASYNCDONTCARE, &hr); pInsertHelloEditSession->Release(); } Exit: if (pContext) pContext->Release(); pDocMgrFocus->Release(); }
STDAPI CExtentMonitorTextService::OnSetFocus(ITfDocumentMgr *pDocMgrFocus, ITfDocumentMgr *pDocMgrPrevFocus) { // // Whenever focus is changed, we initialize the TextEditSink. // ITfDocumentMgr *pDocMgrTarget = NULL; if (GetNonTransitoryDim(pDocMgrFocus, &pDocMgrTarget) != S_OK) { if (pDocMgrFocus) { pDocMgrTarget = pDocMgrFocus; pDocMgrTarget->AddRef(); } } _InitTextEditSink(pDocMgrTarget); if (pDocMgrTarget) { ITfContext *pContext; if (SUCCEEDED(pDocMgrTarget->GetBase(&pContext))) { DumpExtent(pContext, DE_EVENTID_ONSETFOCUS); pContext->Release(); } pDocMgrTarget->Release(); } return S_OK; }
void CTextService::_StartInputModeWindow() { switch(inputmode) { case im_default: case im_hiragana: case im_katakana: case im_katakana_ank: case im_jlatin: case im_ascii: _EndInputModeWindow(); ITfDocumentMgr *pDocumentMgr; if((_pThreadMgr->GetFocus(&pDocumentMgr) == S_OK) && (pDocumentMgr != nullptr)) { ITfContext *pContext; if((pDocumentMgr->GetTop(&pContext) == S_OK) && (pContext != nullptr)) { try { _pInputModeWindow = new CInputModeWindow(); if(_pInputModeWindow->_Create(this, pContext, FALSE, nullptr)) { HRESULT hr = E_FAIL; HRESULT hrSession = E_FAIL; try { CInputModeWindowEditSession *pEditSession = new CInputModeWindowEditSession(this, pContext, _pInputModeWindow); // Asynchronous, read-only hr = pContext->RequestEditSession(_ClientId, pEditSession, TF_ES_ASYNC | TF_ES_READ, &hrSession); SafeRelease(&pEditSession); // It is possible that asynchronous requests are treated as synchronous requests. if(hr != S_OK || (hrSession != TF_S_ASYNC && hrSession != S_OK)) { _EndInputModeWindow(); } } catch(...) { } } } catch(...) { } SafeRelease(&pContext); } SafeRelease(&pDocumentMgr); } break; default: break; } }
HRESULT CCandidateListUIPresenter::_CandidateChangeNotification(_In_ enum CANDWND_ACTION action) { HRESULT hr = E_FAIL; TfClientId tfClientId = _pTextService->_GetClientId(); ITfThreadMgr* pThreadMgr = nullptr; ITfDocumentMgr* pDocumentMgr = nullptr; ITfContext* pContext = nullptr; _KEYSTROKE_STATE KeyState; KeyState.Category = _Category; KeyState.Function = FUNCTION_FINALIZE_CANDIDATELIST; if (CAND_ITEM_SELECT != action) { goto Exit; } pThreadMgr = _pTextService->_GetThreadMgr(); if (nullptr == pThreadMgr) { goto Exit; } hr = pThreadMgr->GetFocus(&pDocumentMgr); if (FAILED(hr)) { goto Exit; } hr = pDocumentMgr->GetTop(&pContext); if (FAILED(hr)) { pDocumentMgr->Release(); goto Exit; } CKeyHandlerEditSession *pEditSession = new (std::nothrow) CKeyHandlerEditSession(_pTextService, pContext, 0, 0, KeyState); if (nullptr != pEditSession) { HRESULT hrSession = S_OK; hr = pContext->RequestEditSession(tfClientId, pEditSession, TF_ES_SYNC | TF_ES_READWRITE, &hrSession); if (hrSession == TF_E_SYNCHRONOUS || hrSession == TS_E_READONLY) { hr = pContext->RequestEditSession(tfClientId, pEditSession, TF_ES_ASYNC | TF_ES_READWRITE, &hrSession); } pEditSession->Release(); } pContext->Release(); pDocumentMgr->Release(); Exit: return hr; }
void CExtentMonitorTextService::DumpExtentFocusContext(UINT nEventId) { ITfDocumentMgr *pDocMgrFocus; if ((_pThreadMgr->GetFocus(&pDocMgrFocus) == S_OK) && (pDocMgrFocus != NULL)) { ITfContext *pContext; if (SUCCEEDED(pDocMgrFocus->GetBase(&pContext))) { DumpExtent(pContext, nEventId); pContext->Release(); } pDocMgrFocus->Release(); } }
void CIME::_UpdateLanguageBarOnSetFocus(_In_ ITfDocumentMgr *pDocMgrFocus) { BOOL needDisableButtons = FALSE; if (!pDocMgrFocus) { needDisableButtons = TRUE; } else { IEnumTfContexts* pEnumContext = nullptr; if (FAILED(pDocMgrFocus->EnumContexts(&pEnumContext)) || !pEnumContext) { needDisableButtons = TRUE; } else { ULONG fetched = 0; ITfContext* pContext = nullptr; if (FAILED(pEnumContext->Next(1, &pContext, &fetched)) || fetched != 1) { needDisableButtons = TRUE; } if (!pContext) { // context is not associated needDisableButtons = TRUE; } else { pContext->Release(); } } if (pEnumContext) { pEnumContext->Release(); } } CCompositionProcessorEngine* pCompositionProcessorEngine = nullptr; pCompositionProcessorEngine = _pCompositionProcessorEngine; pCompositionProcessorEngine->SetLanguageBarStatus(TF_LBI_STATUS_DISABLED, needDisableButtons); }
BOOL CDIME::_UpdateLanguageBarOnSetFocus(_In_ ITfDocumentMgr *pDocMgrFocus) { debugPrint(L"_UpdateLanguageBarOnSetFocus()"); BOOL needDisableButtons = FALSE; if (!pDocMgrFocus) { needDisableButtons = TRUE; } else { IEnumTfContexts* pEnumContext = nullptr; if (FAILED(pDocMgrFocus->EnumContexts(&pEnumContext)) || !pEnumContext) { needDisableButtons = TRUE; } else { ULONG fetched = 0; ITfContext* pContext = nullptr; if (FAILED(pEnumContext->Next(1, &pContext, &fetched)) || fetched != 1) { needDisableButtons = TRUE; } if (pContext == nullptr) { // context is not associated needDisableButtons = TRUE; } else { pContext->Release(); } } if (pEnumContext) { pEnumContext->Release(); } } SetLanguageBarStatus(TF_LBI_STATUS_DISABLED, needDisableButtons); return needDisableButtons; }
STDAPI CSampleIME::OnSetFocus(_In_ ITfDocumentMgr *pDocMgrFocus, _In_ ITfDocumentMgr *pDocMgrPrevFocus) { pDocMgrPrevFocus; _InitTextEditSink(pDocMgrFocus); _UpdateLanguageBarOnSetFocus(pDocMgrFocus); // // We have to hide/unhide candidate list depending on whether they are // associated with pDocMgrFocus. // if (_pCandidateListUIPresenter) { ITfDocumentMgr* pCandidateListDocumentMgr = nullptr; ITfContext* pTfContext = _pCandidateListUIPresenter->_GetContextDocument(); if ((nullptr != pTfContext) && SUCCEEDED(pTfContext->GetDocumentMgr(&pCandidateListDocumentMgr))) { if (pCandidateListDocumentMgr != pDocMgrFocus) { _pCandidateListUIPresenter->OnKillThreadFocus(); } else { _pCandidateListUIPresenter->OnSetThreadFocus(); } pCandidateListDocumentMgr->Release(); } } if (_pDocMgrLastFocused) { _pDocMgrLastFocused->Release(); _pDocMgrLastFocused = nullptr; } _pDocMgrLastFocused = pDocMgrFocus; if (_pDocMgrLastFocused) { _pDocMgrLastFocused->AddRef(); } return S_OK; }
ComPtr<ITfCompartment> TextService::contextCompartment(const GUID& key, ITfContext* context) { ITfContext* curContext = NULL; if(!context) { curContext = currentContext(); context = curContext; } if(context) { ComQIPtr<ITfCompartmentMgr> compartmentMgr = context; if(compartmentMgr) { ComPtr<ITfCompartment> compartment; compartmentMgr->GetCompartment(key, &compartment); return compartment; } } if(curContext) curContext->Release(); return NULL; }
// called when the keyboard is opened or closed // virtual void TextService::onKeyboardStatusChanged(bool opened) { Ime::TextService::onKeyboardStatusChanged(opened); if(client_) client_->onKeyboardStatusChanged(opened); if(opened) { // keyboard is opened } else { // keyboard is closed if(isComposing()) { // end current composition if needed ITfContext* context = currentContext(); if(context) { endComposition(context); context->Release(); } } if(showingCandidates()) // disable candidate window if it's opened hideCandidates(); hideMessage(); // hide message window, if there's any } }
STDAPI CIME::OnSetThreadFocus() { if (_pCandidateListUIPresenter) { ITfDocumentMgr* pCandidateListDocumentMgr = nullptr; ITfContext* pTfContext = _pCandidateListUIPresenter->_GetContextDocument(); if ((nullptr != pTfContext) && SUCCEEDED(pTfContext->GetDocumentMgr(&pCandidateListDocumentMgr))) { if (pCandidateListDocumentMgr == _pDocMgrLastFocused) { _pCandidateListUIPresenter->OnSetThreadFocus(); } pCandidateListDocumentMgr->Release(); } } return S_OK; }
BOOL CMarkTextService::_SetCompositionDisplayAttributes(TfEditCookie ec) { ITfRange *pRangeComposition; ITfContext *pContext; ITfProperty *pDisplayAttributeProperty; VARIANT var; HRESULT hr; // we need a range and the context it lives in if (_pComposition->GetRange(&pRangeComposition) != S_OK) return FALSE; hr = E_FAIL; if (pRangeComposition->GetContext(&pContext) != S_OK) { pContext = NULL; goto Exit; } // get our the display attribute property if (pContext->GetProperty(GUID_PROP_ATTRIBUTE, &pDisplayAttributeProperty) != S_OK) goto Exit; // set the value over the range // the application will use this guid atom to lookup the acutal rendering information var.vt = VT_I4; // we're going to set a TfGuidAtom var.lVal = _gaDisplayAttribute; // our cached guid atom for c_guidMarkDisplayAttribute hr = pDisplayAttributeProperty->SetValue(ec, pRangeComposition, &var); pDisplayAttributeProperty->Release(); Exit: pRangeComposition->Release(); SafeRelease(pContext); return (hr == S_OK); }
void CTextService::_AttachStaticProperty(WCHAR *psz) { ITfDocumentMgr *pDocMgrFocus; ITfContext *pContext; if ((_pThreadMgr->GetFocus(&pDocMgrFocus) == S_OK) && (pDocMgrFocus != NULL)) { if (pDocMgrFocus->GetTop(&pContext) == S_OK) { CStaticPropertyEditSession *pEditSession; if (pEditSession = new CStaticPropertyEditSession(this, pContext, psz)) { HRESULT hr; pContext->RequestEditSession(_tfClientId, pEditSession, TF_ES_ASYNCDONTCARE | TF_ES_READWRITE, &hr); pEditSession->Release(); } pContext->Release(); } pDocMgrFocus->Release(); } return; }
STDAPI CSampleIME::OnCompositionTerminated(TfEditCookie ecWrite, _In_ ITfComposition *pComposition) { // Clear dummy composition _RemoveDummyCompositionForComposing(ecWrite, pComposition); // Clear display attribute and end composition, _EndComposition will release composition for us ITfContext* pContext = _pContext; if (pContext) { pContext->AddRef(); } _EndComposition(_pContext); _DeleteCandidateList(FALSE, pContext); if (pContext) { pContext->Release(); pContext = nullptr; } return S_OK; }
STDAPI CSampleIME::OnKillThreadFocus() { if (_pCandidateListUIPresenter) { ITfDocumentMgr* pCandidateListDocumentMgr = nullptr; ITfContext* pTfContext = _pCandidateListUIPresenter->_GetContextDocument(); if ((nullptr != pTfContext) && SUCCEEDED(pTfContext->GetDocumentMgr(&pCandidateListDocumentMgr))) { if (_pDocMgrLastFocused) { _pDocMgrLastFocused->Release(); _pDocMgrLastFocused = nullptr; } _pDocMgrLastFocused = pCandidateListDocumentMgr; if (_pDocMgrLastFocused) { _pDocMgrLastFocused->AddRef(); } } _pCandidateListUIPresenter->OnKillThreadFocus(); } return S_OK; }
STDAPI CMarkTextService::OnEndEdit(ITfContext *pContext, TfEditCookie ecReadOnly, ITfEditRecord *pEditRecord) { ITfRange *pRangeComposition; IEnumTfRanges *pEnumRanges; ITfRange *pRange; ITfContext *pCompositionContext; TF_SELECTION tfSelection; BOOL fResult; BOOL fCancelComposition; ULONG cFetched; if (_pComposition == NULL) return S_OK; // are we responsible for the edit? if (pContext->InWriteSession(_tfClientId, &fResult) == S_OK && fResult) return S_OK; // is this the context our composition lives in? if (_pComposition->GetRange(&pRangeComposition) != S_OK) return S_OK; if (pRangeComposition->GetContext(&pCompositionContext) != S_OK) goto Exit; fResult = IsEqualUnknown(pCompositionContext, pContext); pCompositionContext->Release(); if (!fResult) goto Exit; // different context fCancelComposition = FALSE; // we're composing in this context, cancel the composition if anything suspicious happened // did the selection move outside the composition? if (pEditRecord->GetSelectionStatus(&fResult) == S_OK && fResult) { if (pContext->GetSelection(ecReadOnly, TF_DEFAULT_SELECTION, 1, &tfSelection, &cFetched) == S_OK && cFetched == 1) { if (_pComposition->GetRange(&pRangeComposition) == S_OK) { fResult = IsRangeCovered(ecReadOnly, tfSelection.range, pRangeComposition); pRangeComposition->Release(); if (!fResult) { fCancelComposition = TRUE; } } tfSelection.range->Release(); } } if (fCancelComposition) goto CancelComposition; // did someone else edit the document text? if (pEditRecord->GetTextAndPropertyUpdates(TF_GTP_INCL_TEXT, NULL, 0, &pEnumRanges) == S_OK) { // is the enumerator empty? if (pEnumRanges->Next(1, &pRange, NULL) == S_OK) { pRange->Release(); fCancelComposition = TRUE; } pEnumRanges->Release(); } if (fCancelComposition) { CancelComposition: // we need a write edit session to cancel the composition _TerminateCompositionInContext(pContext); } Exit: pRangeComposition->Release(); return S_OK; }
STDAPI CCompositionEditSession::DoEditSession(TfEditCookie ec) { ITfInsertAtSelection *pInsertAtSelection; ITfContextComposition *pContextComposition; ITfComposition *pComposition; ITfRange *pRangeComposition; ITfRange *pRangeInsert; ITfContext *pCompositionContext; HRESULT hr; BOOL fEqualContexts; // get an interface on the context we can use to deal with compositions if (_pContext->QueryInterface(IID_ITfContextComposition, (void **)&pContextComposition) != S_OK) return E_FAIL; hr = E_FAIL; pInsertAtSelection = NULL; if (_pMark->_IsComposing()) { // we have a composition, let's terminate it // it's possible our current composition is in another context...let's find out fEqualContexts = TRUE; if (_pMark->_GetComposition()->GetRange(&pRangeComposition) == S_OK) { if (pRangeComposition->GetContext(&pCompositionContext) == S_OK) { fEqualContexts = IsEqualUnknown(pCompositionContext, _pContext); if (!fEqualContexts) { // need an edit session in the composition context _pMark->_TerminateCompositionInContext(pCompositionContext); } pCompositionContext->Release(); } pRangeComposition->Release(); } // if the composition is in pContext, we already have an edit cookie if (fEqualContexts) { _pMark->_TerminateComposition(ec); } } else { // let's start a new composition over the current selection // this is totally contrived, a real text service would have // some meaningful logic to trigger this // first, test where a keystroke would go in the document if we did an insert // we need a special interface to insert text at the selection if (_pContext->QueryInterface(IID_ITfInsertAtSelection, (void **)&pInsertAtSelection) != S_OK) { pInsertAtSelection = NULL; goto Exit; } if (pInsertAtSelection->InsertTextAtSelection(ec, TF_IAS_QUERYONLY, NULL, 0, &pRangeInsert) != S_OK) goto Exit; // start the composition if (pContextComposition->StartComposition(ec, pRangeInsert, _pMark, &pComposition) != S_OK) { pComposition = NULL; } pRangeInsert->Release(); // _pComposition may be NULL even if StartComposition return S_OK, this mean the application // rejected the composition if (pComposition != NULL) { _pMark->_SetComposition(pComposition); // underline the composition text to give the user some feedback UI _pMark->_SetCompositionDisplayAttributes(ec); } } // if we make it here, we've succeeded hr = S_OK; Exit: SafeRelease(pInsertAtSelection); pContextComposition->Release(); return hr; }
STDMETHODIMP TextService::Deactivate() { //::MessageBox(0, L"Deactivate", 0, 0); // terminate composition properly if(isComposing()) { ITfContext* context = currentContext(); if(context) { endComposition(context); context->Release(); } } onDeactivate(); // uninitialize language bar if(!langBarButtons_.empty()) { ComPtr<ITfLangBarItemMgr> langBarItemMgr; if(threadMgr_->QueryInterface(IID_ITfLangBarItemMgr, (void**)&langBarItemMgr) == S_OK) { for(vector<LangBarButton*>::iterator it = langBarButtons_.begin(); it != langBarButtons_.end(); ++it) { LangBarButton* button = *it; langBarItemMgr->RemoveItem(button); } } } if(langBarMgr_) { langBarMgr_->UnadviseEventSink(langBarSinkCookie_); langBarSinkCookie_ = TF_INVALID_COOKIE; langBarMgr_ = NULL; } // unadvice event sinks // ITfThreadMgrEventSink ComQIPtr<ITfSource> source = threadMgr_; if(source) { source->UnadviseSink(threadMgrEventSinkCookie_); source->UnadviseSink(activateLanguageProfileNotifySinkCookie_); threadMgrEventSinkCookie_ = TF_INVALID_COOKIE; activateLanguageProfileNotifySinkCookie_ = TF_INVALID_COOKIE; } // ITfTextEditSink, // ITfKeyEventSink ComQIPtr<ITfKeystrokeMgr> keystrokeMgr = threadMgr_; if(keystrokeMgr) { keystrokeMgr->UnadviseKeyEventSink(clientId_); // unregister preserved keys if(!preservedKeys_.empty()) { vector<PreservedKey>::iterator it; for(it = preservedKeys_.begin(); it != preservedKeys_.end(); ++it) { PreservedKey& preservedKey = *it; keystrokeMgr->UnpreserveKey(preservedKey.guid, &preservedKey); } } } // ITfCompositionSink // ITfCompartmentEventSink // thread specific compartment ComPtr<ITfCompartment> compartment = threadCompartment(GUID_COMPARTMENT_KEYBOARD_OPENCLOSE); if(compartment) { ComQIPtr<ITfSource> compartmentSource = compartment; if(compartmentSource) compartmentSource->UnadviseSink(keyboardOpenEventSinkCookie_); keyboardOpenEventSinkCookie_ = TF_INVALID_COOKIE; } /* // global compartment compartment = globalCompartment(XXX_GUID); if(compartment) { ComQIPtr<ITfSource> compartmentSource = compartment; if(compartmentSource) compartmentSource->UnadviseSink(globalCompartmentEventSinkCookie_); globalCompartmentEventSinkCookie_ = TF_INVALID_COOKIE; } */ threadMgr_ = NULL; clientId_ = TF_CLIENTID_NULL; activateFlags_ = 0; return S_OK; }
BOOL CTextService::_IsKeyboardDisabled() { ITfCompartmentMgr *pCompMgr = NULL; ITfDocumentMgr *pDocMgrFocus = NULL; ITfContext *pContext = NULL; BOOL fDisabled = FALSE; if ((_pThreadMgr->GetFocus(&pDocMgrFocus) != S_OK) || (pDocMgrFocus == NULL)) { // if there is no focus document manager object, the keyboard // is disabled. fDisabled = TRUE; goto Exit; } if ((pDocMgrFocus->GetTop(&pContext) != S_OK) || (pContext == NULL)) { // if there is no context object, the keyboard is disabled. fDisabled = TRUE; goto Exit; } if (pContext->QueryInterface(IID_ITfCompartmentMgr, (void **)&pCompMgr) == S_OK) { ITfCompartment *pCompartmentDisabled; ITfCompartment *pCompartmentEmptyContext; // Check GUID_COMPARTMENT_KEYBOARD_DISABLED. if (pCompMgr->GetCompartment(GUID_COMPARTMENT_KEYBOARD_DISABLED, &pCompartmentDisabled) == S_OK) { VARIANT var; if (S_OK == pCompartmentDisabled->GetValue(&var)) { if (var.vt == VT_I4) // Even VT_EMPTY, GetValue() can succeed { fDisabled = (BOOL)var.lVal; } } pCompartmentDisabled->Release(); } // Check GUID_COMPARTMENT_EMPTYCONTEXT. if (pCompMgr->GetCompartment(GUID_COMPARTMENT_EMPTYCONTEXT, &pCompartmentEmptyContext) == S_OK) { VARIANT var; if (S_OK == pCompartmentEmptyContext->GetValue(&var)) { if (var.vt == VT_I4) // Even VT_EMPTY, GetValue() can succeed { fDisabled = (BOOL)var.lVal; } } pCompartmentEmptyContext->Release(); } pCompMgr->Release(); } Exit: if (pContext) pContext->Release(); if (pDocMgrFocus) pDocMgrFocus->Release(); return fDisabled; }