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 ITfThreadMgr *thread;
\r
36 HRESULT hr = CoCreateInstance(CLSID_TF_ThreadMgr, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&thread));
\r
37 if (hr == CO_E_NOTINITIALIZED) {
\r
38 hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
\r
40 DebugLog("CoInitializeEx failed.");
\r
45 hr = CoCreateInstance(CLSID_TF_ThreadMgr, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&thread));
\r
48 DebugLog("CoCreateInstance for ThreadMgr failed.");
\r
51 TSFHandler *tsfh = new TSFHandler();
\r
52 TLS::PutTSFHandler(tsfh);
\r
53 tsfh->m_ThreadMgr = thread;
\r
55 if (FAILED(thread->QueryInterface(&src))) {
\r
56 DebugLog("ThreadMgr->QueryInterface failed.");
\r
60 if (FAILED(src->AdviseSink(IID_ITfThreadMgrEventSink, static_cast<ITfThreadMgrEventSink *>(tsfh), &cookie))) {
\r
61 DebugLog("Souece->AdviseSink failed.");
\r
72 STDMETHODIMP TSFHandler::QueryInterface(REFIID iid, void **obj)
\r
75 return E_INVALIDARG;
\r
77 if (IsEqualIID(iid, IID_IUnknown) || iid == IID_ITfThreadMgrEventSink)
\r
78 *obj = static_cast<ITfThreadMgrEventSink *>(this);
\r
79 else if (iid == IID_ITfTextEditSink)
\r
80 *obj = static_cast<ITfTextEditSink *>(this);
\r
82 return E_NOINTERFACE;
\r
87 STDMETHODIMP_(ULONG) TSFHandler::AddRef()
\r
89 return ++m_RefCount;
\r
92 STDMETHODIMP_(ULONG) TSFHandler::Release()
\r
94 if (--m_RefCount == 0)
\r
99 // ITfThreadMgrEventSink
\r
100 STDMETHODIMP TSFHandler::OnInitDocumentMgr(ITfDocumentMgr *)
\r
102 DebugLog("OnInitDocumentMgr");
\r
106 STDMETHODIMP TSFHandler::OnPopContext(ITfContext *)
\r
108 DebugLog("OnPopContext");
\r
112 STDMETHODIMP TSFHandler::OnPushContext(ITfContext *)
\r
114 DebugLog("OnPushContext");
\r
118 STDMETHODIMP TSFHandler::OnSetFocus(ITfDocumentMgr *docMgr, ITfDocumentMgr *)
\r
120 DebugLog("OnSetFocus");
\r
121 if (docMgr == nullptr)
\r
123 if (m_Cookie != TF_INVALID_COOKIE) {
\r
125 if (FAILED(m_Context->QueryInterface(&src))) {
\r
126 DebugLog("Context->QueryInterface:0 failed.");
\r
129 HRESULT hr = src->UnadviseSink(m_Cookie);
\r
132 DebugLog("Source->UnadviceThink failed.");
\r
135 m_Context->Release();
\r
136 m_Context = nullptr;
\r
137 m_Cookie = TF_INVALID_COOKIE;
\r
140 if (FAILED(docMgr->GetTop(&cxt))) {
\r
141 DebugLog("DocumentMgr->GetTop failed.");
\r
144 if (cxt == nullptr) {
\r
145 DebugLog("ITfContext is null.");
\r
149 if (FAILED(cxt->QueryInterface(&src))) {
\r
150 DebugLog("Context->QueryInterface:1 failed.");
\r
153 if (FAILED(src->AdviseSink(IID_ITfTextEditSink, static_cast<ITfTextEditSink *>(this), &m_Cookie))) {
\r
154 DebugLog("Source->AdviseSink(ITfTextEditSink) failed.");
\r
166 STDMETHODIMP TSFHandler::OnUninitDocumentMgr(ITfDocumentMgr *)
\r
168 DebugLog("OnUninitDocumentMgr");
\r
172 STDMETHODIMP TSFHandler::OnEndEdit(ITfContext *cxt, TfEditCookie, ITfEditRecord *)
\r
174 DebugLog("OnEndEdit");
\r
175 ITfContextComposition *comp;
\r
176 if (FAILED(cxt->QueryInterface(&comp))) {
\r
177 DebugLog("Context->QueryInterface(ITfContextComposition) failed.");
\r
180 IEnumITfCompositionView *enumCompView;
\r
181 if (FAILED(comp->EnumCompositions(&enumCompView))) {
\r
182 DebugLog("ContextComposition->EnumCompositions failed.");
\r
185 ITfCompositionView *view;
\r
187 HRESULT hr = enumCompView->Next(1, &view, &fetched);
\r
189 DebugLog("EnumCompositions->Next failed.");
\r
190 enumCompView->Release();
\r
193 DebugLog("EnumComposition->Next succeeded. fetched=%d", fetched);
\r
195 if (!m_CompositionState)
\r
196 CXkeymacsDll::SetIMEState(true);
\r
197 m_CompositionState = true;
\r
201 if (m_CompositionState)
\r
202 CXkeymacsDll::SetIMEState(false);
\r
203 m_CompositionState = false;
\r
205 enumCompView->Release();
\r