comparison EXCLUDE/GLTSF/src/TSF.cpp @ 4739:f51a9f01b508

Starting to implement ITextStoreACP. It's very incomplete and will probably change quite a bit but it's a start. ITextStoreACP is the minimum interface to be considered TSF-aware.
author dewyatt
date Mon, 21 Jun 2010 17:16:37 -0400
parents 0c7c67d4e6ee
children abf528de6d2e
comparison
equal deleted inserted replaced
4738:381d402a5e90 4739:f51a9f01b508
1 #include "TSF.hpp" 1 #include "TSF.hpp"
2 #include <stdexcept> 2 #include <stdexcept>
3 3
4 bool TSF::COM_Initialized = false; 4 bool TSF::COM_Initialized = false;
5 CComPtr<ITfThreadMgr> TSF::Thread_Manager; 5 CComPtr<ITfThreadMgr> TSF::Thread_Manager;
6 TfClientId TSF::Client_Id;
7 TSF::TSF_Text_Store *TSF::Text_Store = NULL;
6 8
7 void TSF::Initialize() 9 void TSF::Initialize()
8 { 10 {
9 if (!COM_Initialized) 11 if (!COM_Initialized)
10 { 12 {
17 if (!Thread_Manager) 19 if (!Thread_Manager)
18 { 20 {
19 if (FAILED(CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr, reinterpret_cast<void **>(&Thread_Manager)))) 21 if (FAILED(CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr, reinterpret_cast<void **>(&Thread_Manager))))
20 throw std::runtime_error("Failed to create ITfThreadMgr instance"); 22 throw std::runtime_error("Failed to create ITfThreadMgr instance");
21 23
22 TfClientId ClientId; 24 if (FAILED(Thread_Manager->Activate(&Client_Id)))
23 if (FAILED(Thread_Manager->Activate(&ClientId)))
24 throw std::runtime_error("ITfThreadMgr::Activate failed"); 25 throw std::runtime_error("ITfThreadMgr::Activate failed");
26
27 Text_Store = new TSF_Text_Store;
28 Text_Store->Initialize();
25 } 29 }
26 } 30 }
27 31
28 void TSF::Finalize() 32 void TSF::Finalize()
29 { 33 {
36 { 40 {
37 CoUninitialize(); 41 CoUninitialize();
38 COM_Initialized = false; 42 COM_Initialized = false;
39 } 43 }
40 } 44 }
45
46 STDMETHODIMP TSF::TSF_Text_Store::QueryInterface(REFIID riid, void **ppvObject)
47 {
48 *ppvObject = NULL;
49 if (IID_IUnknown == riid || IID_ITextStoreACP == riid)
50 *ppvObject = static_cast<ITextStoreACP *>(this);
51 else if (IID_ITfContextOwnerCompositionSink == riid)
52 *ppvObject = static_cast<ITfContextOwnerCompositionSink *>(this);
53
54 if (*ppvObject)
55 {
56 AddRef();
57 return S_OK;
58 }
59 return E_NOINTERFACE;
60 }
61
62 STDMETHODIMP_(ULONG) TSF::TSF_Text_Store::AddRef()
63 {
64 return ++my_Reference_Count;
65 }
66
67 STDMETHODIMP_(ULONG) TSF::TSF_Text_Store::Release()
68 {
69 --my_Reference_Count;
70 if (0 != my_Reference_Count)
71 return my_Reference_Count;
72
73 delete this;
74 return 0;
75 }
76
77 STDMETHODIMP TSF::TSF_Text_Store::AdviseSink(REFIID riid, IUnknown *punk, DWORD dwMask)
78 {
79 if (!punk || IID_ITextStoreACPSink != riid)
80 return E_INVALIDARG;
81
82 if (!my_Sink)
83 {
84 punk->QueryInterface(&my_Sink);
85 if (!my_Sink)
86 return E_UNEXPECTED;
87 }
88 else
89 {
90 CComPtr<IUnknown> Unknown_1, Unknown_2;
91 punk->QueryInterface(&Unknown_1);
92 my_Sink->QueryInterface(&Unknown_2);
93 if (Unknown_1 != Unknown_2)
94 return CONNECT_E_ADVISELIMIT;
95 }
96 my_Sink_Mask = dwMask;
97 return S_OK;
98 }
99
100 STDMETHODIMP TSF::TSF_Text_Store::UnadviseSink(IUnknown *punk)
101 {
102 if (!punk)
103 return E_INVALIDARG;
104
105 if (!my_Sink)
106 return CONNECT_E_NOCONNECTION;
107
108 CComPtr<IUnknown> Unknown_1, Unknown_2;
109 punk->QueryInterface(&Unknown_1);
110 my_Sink->QueryInterface(&Unknown_2);
111
112 if (Unknown_1 != Unknown_2)
113 return CONNECT_E_NOCONNECTION;
114
115 my_Sink = NULL;
116 my_Sink_Mask = 0;
117 return S_OK;
118 }
119
120 STDMETHODIMP TSF::TSF_Text_Store::RequestLock(DWORD dwLockFlags, HRESULT *phrSession)
121 {
122 if (!my_Sink)
123 return E_FAIL;
124
125 if (!phrSession)
126 return E_INVALIDARG;
127
128 if (my_Lock)
129 {
130 if (TS_LF_READ == (my_Lock & TS_LF_READWRITE)
131 && TS_LF_READWRITE == (dwLockFlags & TS_LF_READWRITE)
132 && !(dwLockFlags & TS_LF_SYNC))
133 {
134 *phrSession = TS_S_ASYNC;
135 my_Lock_Queued = dwLockFlags & (~TS_LF_SYNC);
136 }
137 else
138 {
139 *phrSession = TS_E_SYNCHRONOUS;
140 return E_FAIL;
141 }
142 }
143 else
144 {
145 my_Lock = dwLockFlags & (~TS_LF_SYNC);
146 *phrSession = my_Sink->OnLockGranted(my_Lock);
147 while (my_Lock_Queued)
148 {
149 my_Lock = my_Lock_Queued;
150 my_Lock_Queued = 0;
151 my_Sink->OnLockGranted(my_Lock);
152 }
153 my_Lock = 0;
154 }
155 return S_OK;
156 }
157
158 STDMETHODIMP TSF::TSF_Text_Store::GetStatus(TS_STATUS *pdcs)
159 {
160 if (!pdcs)
161 return E_INVALIDARG;
162
163 pdcs->dwDynamicFlags = 0;
164 pdcs->dwStaticFlags = TS_SS_NOHIDDENTEXT;
165 return S_OK;
166 }
167
168 STDMETHODIMP TSF::TSF_Text_Store::QueryInsert(LONG acpTestStart, LONG acpTestEnd, ULONG cch, LONG *pacpResultStart, LONG *pacpResultEnd)
169 {
170 if (acpTestStart < 0 || acpTestStart > acpTestEnd || !pacpResultStart || !pacpResultEnd)
171 return E_INVALIDARG;
172
173 *pacpResultStart = acpTestStart;
174 *pacpResultEnd = acpTestStart + cch;
175 return S_OK;
176 }
177
178 STDMETHODIMP TSF::TSF_Text_Store::GetSelection(ULONG ulIndex, ULONG ulCount, TS_SELECTION_ACP *pSelection, ULONG *pcFetched)
179 {
180 if (TS_LF_READ != (my_Lock & TS_LF_READ))
181 return TS_E_NOLOCK;
182
183 if (!ulCount || !pSelection || !pcFetched)
184 return E_INVALIDARG;
185
186 *pcFetched = 0;
187 if (TS_DEFAULT_SELECTION != ulIndex && 0 != ulIndex)
188 return TS_E_NOSELECTION;
189
190 if (my_Composition_View)
191 {
192 *pSelection = my_Composition_Selection;
193 }
194 else
195 {
196 //TODO
197 }
198 return S_OK;
199 }
200
201 STDMETHODIMP TSF::TSF_Text_Store::SetSelection(ULONG ulCount, const TS_SELECTION_ACP *pSelection)
202 {
203 return E_NOTIMPL;
204 }
205
206 STDMETHODIMP TSF::TSF_Text_Store::GetText(LONG acpStart, LONG acpEnd, WCHAR *pchPlain, ULONG cchPlainReq, ULONG *pcchPlainRet, TS_RUNINFO *prgRunInfo, ULONG cRunInfoReq, ULONG *pcRunInfoRet, LONG *pacpNext)
207 {
208 return E_NOTIMPL;
209 }
210
211 STDMETHODIMP TSF::TSF_Text_Store::SetText(DWORD dwFlags, LONG acpStart, LONG acpEnd, const WCHAR *pchText, ULONG cch, TS_TEXTCHANGE *pChange)
212 {
213 return E_NOTIMPL;
214 }
215
216 STDMETHODIMP TSF::TSF_Text_Store::GetFormattedText(LONG acpStart, LONG acpEnd, IDataObject **ppDataObject)
217 {
218 return E_NOTIMPL;
219 }
220
221 STDMETHODIMP TSF::TSF_Text_Store::GetEmbedded(LONG acpPos, REFGUID rguidService, REFIID riid, IUnknown **ppunk)
222 {
223 return E_NOTIMPL;
224 }
225
226 STDMETHODIMP TSF::TSF_Text_Store::QueryInsertEmbedded(const GUID *pguidService, const FORMATETC *pFormatEtc, BOOL *pfInsertable)
227 {
228 return E_NOTIMPL;
229 }
230
231 STDMETHODIMP TSF::TSF_Text_Store::InsertEmbedded(DWORD dwFlags, LONG acpStart, LONG acpEnd, IDataObject *pDataObject, TS_TEXTCHANGE *pChange)
232 {
233 return E_NOTIMPL;
234 }
235
236 STDMETHODIMP TSF::TSF_Text_Store::InsertTextAtSelection(DWORD dwFlags, const WCHAR *pchText, ULONG cch, LONG *pacpStart, LONG *pacpEnd, TS_TEXTCHANGE *pChange)
237 {
238 return E_NOTIMPL;
239 }
240
241 STDMETHODIMP TSF::TSF_Text_Store::InsertEmbeddedAtSelection(DWORD dwFlags, IDataObject *pDataObject, LONG *pacpStart, LONG *pacpEnd, TS_TEXTCHANGE *pChange)
242 {
243 return E_NOTIMPL;
244 }
245
246 STDMETHODIMP TSF::TSF_Text_Store::RequestSupportedAttrs(DWORD dwFlags, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs)
247 {
248 return E_NOTIMPL;
249 }
250
251 STDMETHODIMP TSF::TSF_Text_Store::RequestAttrsAtPosition(LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags)
252 {
253 return E_NOTIMPL;
254 }
255
256 STDMETHODIMP TSF::TSF_Text_Store::RequestAttrsTransitioningAtPosition(LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags)
257 {
258 return E_NOTIMPL;
259 }
260
261 STDMETHODIMP TSF::TSF_Text_Store::FindNextAttrTransition(LONG acpStart, LONG acpHalt, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags, LONG *pacpNext, BOOL *pfFound, LONG *plFoundOffset)
262 {
263 return E_NOTIMPL;
264 }
265
266 STDMETHODIMP TSF::TSF_Text_Store::RetrieveRequestedAttrs(ULONG ulCount, TS_ATTRVAL *paAttrVals, ULONG *pcFetched)
267 {
268 return E_NOTIMPL;
269 }
270
271 STDMETHODIMP TSF::TSF_Text_Store::GetEndACP(LONG *pacp)
272 {
273 return E_NOTIMPL;
274 }
275
276 STDMETHODIMP TSF::TSF_Text_Store::GetActiveView(TsViewCookie *pvcView)
277 {
278 return E_NOTIMPL;
279 }
280
281 STDMETHODIMP TSF::TSF_Text_Store::GetACPFromPoint(TsViewCookie vcView, const POINT *ptScreen, DWORD dwFlags, LONG *pacp)
282 {
283 return E_NOTIMPL;
284 }
285
286 STDMETHODIMP TSF::TSF_Text_Store::GetTextExt(TsViewCookie vcView, LONG acpStart, LONG acpEnd, RECT *prc, BOOL *pfClipped)
287 {
288 return E_NOTIMPL;
289 }
290
291 STDMETHODIMP TSF::TSF_Text_Store::GetScreenExt(TsViewCookie vcView, RECT *prc)
292 {
293 return E_NOTIMPL;
294 }
295
296 STDMETHODIMP TSF::TSF_Text_Store::GetWnd(TsViewCookie vcView, HWND *phwnd)
297 {
298 return E_NOTIMPL;
299 }
300
301 STDMETHODIMP TSF::TSF_Text_Store::OnStartComposition(ITfCompositionView *pComposition, BOOL *pfOk)
302 {
303 *pfOk = FALSE;
304 return S_OK;
305 }
306
307 STDMETHODIMP TSF::TSF_Text_Store::OnUpdateComposition(ITfCompositionView *pComposition, ITfRange *pRangeNew)
308 {
309 return E_NOTIMPL;
310 }
311
312 STDMETHODIMP TSF::TSF_Text_Store::OnEndComposition(ITfCompositionView *pComposition)
313 {
314 return E_NOTIMPL;
315 }
316
317 TSF::TSF_Text_Store::TSF_Text_Store() : my_Reference_Count(1),
318 my_Edit_Cookie(0),
319 my_Lock(0),
320 my_Lock_Queued(0)
321 {
322
323 }
324
325 TSF::TSF_Text_Store::~TSF_Text_Store()
326 {
327
328 }
329
330 void TSF::TSF_Text_Store::Initialize()
331 {
332 if (FAILED(Thread_Manager->CreateDocumentMgr(&my_Document_Manager)))
333 throw std::runtime_error("Failed to create document manager");
334
335 if (FAILED(my_Document_Manager->CreateContext(Client_Id, 0, static_cast<ITextStoreACP *>(this), &my_Context, &my_Edit_Cookie)))
336 throw std::runtime_error("Failed to create document context");
337
338 if (FAILED(my_Document_Manager->Push(my_Context)))
339 throw std::runtime_error("Failed to push context");
340 }
341
342 void TSF::TSF_Text_Store::Finalize()
343 {
344
345 }