2 #include "TSFHandler.h"
\r
5 #include "xkeymacsdll.h"
\r
9 #define DebugLog(fmt, ...) CUtils::Log(_T(__FUNCTION__ ## ": " ## 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 HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
\r
37 DebugLog("CoInitializeEx failed.");
\r
42 ITfThreadMgr *thread;
\r
43 if (FAILED(CoCreateInstance(CLSID_TF_ThreadMgr, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&thread)))) {
\r
44 DebugLog("CoCreateInstance for ThreadMgr failed.");
\r
47 TSFHandler *tsfh = new TSFHandler();
\r
48 TLS::PutTSFHandler(tsfh);
\r
49 tsfh->m_ThreadMgr = thread;
\r
51 if (FAILED(thread->QueryInterface(&src))) {
\r
52 DebugLog("ThreadMgr->QueryInterface failed.");
\r
56 if (FAILED(src->AdviseSink(IID_ITfThreadMgrEventSink, static_cast<ITfThreadMgrEventSink *>(tsfh), &cookie))) {
\r
57 DebugLog("Souece->AdviseSink failed.");
\r
68 STDMETHODIMP TSFHandler::QueryInterface(REFIID iid, void **obj)
\r
71 return E_INVALIDARG;
\r
73 if (IsEqualIID(iid, IID_IUnknown) || iid == IID_ITfThreadMgrEventSink)
\r
74 *obj = static_cast<ITfThreadMgrEventSink *>(this);
\r
75 else if (iid == IID_ITfTextEditSink)
\r
76 *obj = static_cast<ITfTextEditSink *>(this);
\r
78 return E_NOINTERFACE;
\r
83 STDMETHODIMP_(ULONG) TSFHandler::AddRef()
\r
85 return ++m_RefCount;
\r
88 STDMETHODIMP_(ULONG) TSFHandler::Release()
\r
90 if (--m_RefCount == 0)
\r
95 // ITfThreadMgrEventSink
\r
96 STDMETHODIMP TSFHandler::OnInitDocumentMgr(ITfDocumentMgr *)
\r
98 DebugLog("OnInitDocumentMgr");
\r
102 STDMETHODIMP TSFHandler::OnPopContext(ITfContext *)
\r
104 DebugLog("OnPopContext");
\r
108 STDMETHODIMP TSFHandler::OnPushContext(ITfContext *)
\r
110 DebugLog("OnPushContext");
\r
114 STDMETHODIMP TSFHandler::OnSetFocus(ITfDocumentMgr *docMgr, ITfDocumentMgr *)
\r
116 DebugLog("OnSetFocus");
\r
117 if (docMgr == nullptr)
\r
119 if (m_Cookie != TF_INVALID_COOKIE) {
\r
121 if (FAILED(m_Context->QueryInterface(&src))) {
\r
122 DebugLog("Context->QueryInterface:0 failed.");
\r
125 HRESULT hr = src->UnadviseSink(m_Cookie);
\r
128 DebugLog("Source->UnadviceThink failed.");
\r
131 m_Context->Release();
\r
132 m_Context = nullptr;
\r
133 m_Cookie = TF_INVALID_COOKIE;
\r
136 if (FAILED(docMgr->GetTop(&cxt))) {
\r
137 DebugLog("DocumentMgr->GetTop failed.");
\r
140 if (cxt == nullptr) {
\r
141 DebugLog("ITfContext is null.");
\r
145 if (FAILED(cxt->QueryInterface(&src))) {
\r
146 DebugLog("Context->QueryInterface:1 failed.");
\r
149 if (FAILED(src->AdviseSink(IID_ITfTextEditSink, static_cast<ITfTextEditSink *>(this), &m_Cookie))) {
\r
150 DebugLog("Source->AdviseSink(ITfTextEditSink) failed.");
\r
162 STDMETHODIMP TSFHandler::OnUninitDocumentMgr(ITfDocumentMgr *)
\r
164 DebugLog("OnUninitDocumentMgr");
\r
168 STDMETHODIMP TSFHandler::OnEndEdit(ITfContext *cxt, TfEditCookie, ITfEditRecord *)
\r
170 DebugLog("OnEndEdit");
\r
171 ITfContextComposition *comp;
\r
172 if (FAILED(cxt->QueryInterface(&comp))) {
\r
173 DebugLog("Context->QueryInterface(ITfContextComposition) failed.");
\r
176 IEnumITfCompositionView *enumCompView;
\r
177 if (FAILED(comp->EnumCompositions(&enumCompView))) {
\r
178 DebugLog("ContextComposition->EnumCompositions failed.");
\r
181 ITfCompositionView *view;
\r
183 HRESULT hr = enumCompView->Next(1, &view, &fetched);
\r
185 DebugLog("EnumCompositions->Next failed.");
\r
186 enumCompView->Release();
\r
189 DebugLog("EnumComposition->Next succeeded. fetched=%d", fetched);
\r
191 if (!m_CompositionState)
\r
192 CXkeymacsDll::SetIMEState(true);
\r
193 m_CompositionState = true;
\r
197 if (m_CompositionState)
\r
198 CXkeymacsDll::SetIMEState(false);
\r
199 m_CompositionState = false;
\r
201 enumCompView->Release();
\r