2 #include "TSFHandler.h"
\r
5 #include "xkeymacsdll.h"
\r
9 #define DebugLog(fmt, ...) CUtils::Log(fmt, __VA_ARGS__)
\r
11 #define DebugLog(fmt, ...)
\r
14 TSFHandler::TSFHandler()
\r
17 m_ThreadMgr = nullptr;
\r
18 m_Cookie = TF_INVALID_COOKIE;
\r
19 m_Context = nullptr;
\r
20 m_CompositionState = false;
\r
23 TSFHandler::~TSFHandler()
\r
26 m_ThreadMgr->Release();
\r
28 m_Context->Release();
\r
31 void TSFHandler::InitSink()
\r
33 if (TLS::GetTSFHandler())
\r
35 TSFHandler *tsfh = new TSFHandler();
\r
36 TLS::PutTSFHandler(tsfh);
\r
38 HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
\r
40 DebugLog(_T("CoInitializeEx failed."));
\r
45 ITfThreadMgr *thread;
\r
46 if (FAILED(CoCreateInstance(CLSID_TF_ThreadMgr, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&thread)))) {
\r
47 DebugLog(_T("CoCreateInstance for ThreadMgr failed."));
\r
50 tsfh->m_ThreadMgr = thread;
\r
52 if (FAILED(thread->QueryInterface(&src))) {
\r
53 DebugLog(_T("ThreadMgr->QueryInterface failed."));
\r
57 if (FAILED(src->AdviseSink(IID_ITfThreadMgrEventSink, static_cast<ITfThreadMgrEventSink *>(tsfh), &cookie))) {
\r
58 DebugLog(_T("Souece->AdviseSink failed."));
\r
69 STDMETHODIMP TSFHandler::QueryInterface(REFIID iid, void **obj)
\r
72 return E_INVALIDARG;
\r
74 if (IsEqualIID(iid, IID_IUnknown) || iid == IID_ITfThreadMgrEventSink)
\r
75 *obj = static_cast<ITfThreadMgrEventSink *>(this);
\r
76 else if (iid == IID_ITfTextEditSink)
\r
77 *obj = static_cast<ITfTextEditSink *>(this);
\r
79 return E_NOINTERFACE;
\r
84 STDMETHODIMP_(ULONG) TSFHandler::AddRef()
\r
86 return ++m_RefCount;
\r
89 STDMETHODIMP_(ULONG) TSFHandler::Release()
\r
91 if (--m_RefCount == 0)
\r
96 // ITfThreadMgrEventSink
\r
97 STDMETHODIMP TSFHandler::OnInitDocumentMgr(ITfDocumentMgr *)
\r
99 DebugLog(_T("OnInitDocumentMgr"));
\r
103 STDMETHODIMP TSFHandler::OnPopContext(ITfContext *)
\r
105 DebugLog(_T("OnPopContext"));
\r
109 STDMETHODIMP TSFHandler::OnPushContext(ITfContext *)
\r
111 DebugLog(_T("OnPushContext"));
\r
115 STDMETHODIMP TSFHandler::OnSetFocus(ITfDocumentMgr *docMgr, ITfDocumentMgr *)
\r
117 DebugLog(_T("OnSetFocus"));
\r
118 if (docMgr == nullptr)
\r
120 if (m_Cookie != TF_INVALID_COOKIE) {
\r
122 if (FAILED(m_Context->QueryInterface(&src))) {
\r
123 DebugLog(_T("Context->QueryInterface:0 failed."));
\r
126 HRESULT hr = src->UnadviseSink(m_Cookie);
\r
129 DebugLog(_T("Source->UnadviceThink failed."));
\r
132 m_Context->Release();
\r
133 m_Context = nullptr;
\r
134 m_Cookie = TF_INVALID_COOKIE;
\r
137 if (FAILED(docMgr->GetTop(&cxt))) {
\r
138 DebugLog(_T("DocumentMgr->GetTop failed."));
\r
141 if (cxt == nullptr) {
\r
142 DebugLog(_T("ITfContext is null."));
\r
146 if (FAILED(cxt->QueryInterface(&src))) {
\r
147 DebugLog(_T("Context->QueryInterface:1 failed."));
\r
150 if (FAILED(src->AdviseSink(IID_ITfTextEditSink, static_cast<ITfTextEditSink *>(this), &m_Cookie))) {
\r
151 DebugLog(_T("Source->AdviseSink(ITfTextEditSink) failed."));
\r
163 STDMETHODIMP TSFHandler::OnUninitDocumentMgr(ITfDocumentMgr *)
\r
165 DebugLog(_T("OnUninitDocumentMgr"));
\r
169 STDMETHODIMP TSFHandler::OnEndEdit(ITfContext *cxt, TfEditCookie, ITfEditRecord *)
\r
171 DebugLog(_T("OnEndEdit"));
\r
172 ITfContextComposition *comp;
\r
173 if (FAILED(cxt->QueryInterface(&comp))) {
\r
174 DebugLog(_T("Context->QueryInterface(ITfContextComposition) failed."));
\r
177 IEnumITfCompositionView *enumCompView;
\r
178 if (FAILED(comp->EnumCompositions(&enumCompView))) {
\r
179 DebugLog(_T("ContextComposition->EnumCompositions failed."));
\r
182 ITfCompositionView *view;
\r
184 HRESULT hr = enumCompView->Next(1, &view, &fetched);
\r
186 DebugLog(_T("EnumCompositions->Next failed."));
\r
187 enumCompView->Release();
\r
190 DebugLog(_T("EnumComposition->Next succeeded. fetched=%d"), fetched);
\r
192 if (!m_CompositionState)
\r
193 CXkeymacsDll::SetIMEState(true);
\r
194 m_CompositionState = true;
\r
198 if (m_CompositionState)
\r
199 CXkeymacsDll::SetIMEState(false);
\r
200 m_CompositionState = false;
\r
202 enumCompView->Release();
\r