ReactOS 0.4.15-dev-8390-g075894b
sinks.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS msctfime.ime
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: The sinks of msctfime.ime
5 * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#include "msctfime.h"
9
11
14 : m_array()
15 , m_cRefs(1)
16 , m_fnEventSink(fnEventSink)
17 , m_pUserData(pUserData)
18{
19}
20
23{
24}
25
28{
29 static const QITAB c_tab[] =
30 {
32 { NULL }
33 };
34 return ::QISearch(this, c_tab, riid, ppvObj);
35}
36
39{
40 return ::InterlockedIncrement(&m_cRefs);
41}
42
45{
47 {
48 delete this;
49 return 0;
50 }
51 return m_cRefs;
52}
53
56{
57 return m_fnEventSink(m_pUserData, rguid);
58}
59
63{
64 CESMAP *pCesMap = m_array.Append(1);
65 if (!pCesMap)
66 return E_OUTOFMEMORY;
67
68 ITfSource *pSource = NULL;
69
70 HRESULT hr = GetCompartment(pUnknown, rguid, &pCesMap->m_pComp, bThread);
71 if (FAILED(hr))
72 {
73 hr = pCesMap->m_pComp->QueryInterface(IID_ITfSource, (void **)&pSource);
74 if (FAILED(hr))
75 {
76 hr = pSource->AdviseSink(IID_ITfCompartmentEventSink, this, &pCesMap->m_dwCookie);
77 if (FAILED(hr))
78 {
79 if (pCesMap->m_pComp)
80 {
81 pCesMap->m_pComp->Release();
82 pCesMap->m_pComp = NULL;
83 }
84 m_array.Remove(m_array.size() - 1, 1);
85 }
86 else
87 {
88 hr = S_OK;
89 }
90 }
91 }
92
93 if (pSource)
94 pSource->Release();
95
96 return hr;
97}
98
101{
102 CESMAP *pCesMap = m_array.data();
103 size_t cItems = m_array.size();
104 if (!cItems)
105 return S_OK;
106
107 do
108 {
109 ITfSource *pSource = NULL;
110 HRESULT hr = pCesMap->m_pComp->QueryInterface(IID_ITfSource, (void **)&pSource);
111 if (SUCCEEDED(hr))
112 pSource->UnadviseSink(pCesMap->m_dwCookie);
113
114 if (pCesMap->m_pComp)
115 {
116 pCesMap->m_pComp->Release();
117 pCesMap->m_pComp = NULL;
118 }
119
120 if (pSource)
121 pSource->Release();
122
123 ++pCesMap;
124 --cItems;
125 } while (cItems);
126
127 return S_OK;
128}
129
130/***********************************************************************/
131
134{
135 m_cRefs = 1;
140 m_fnEndEdit = fnEndEdit;
141 m_pCallbackPV = pCallbackPV;
142}
143
146{
147}
148
151{
152 static const QITAB c_tab[] =
153 {
156 { NULL }
157 };
158 return ::QISearch(this, c_tab, riid, ppvObj);
159}
160
163{
164 return ::InterlockedIncrement(&m_cRefs);
165}
166
169{
171 {
172 delete this;
173 return 0;
174 }
175 return m_cRefs;
176}
177
179{
183};
184
187 ITfContext *pic,
188 TfEditCookie ecReadOnly,
189 ITfEditRecord *pEditRecord)
190{
191 TEXT_EVENT_SINK_END_EDIT Data = { ecReadOnly, pEditRecord, pic };
192 return m_fnEndEdit(1, m_pCallbackPV, (LPVOID)&Data);
193}
194
197 ITfContext *pContext,
198 TfLayoutCode lcode,
199 ITfContextView *pContextView)
200{
201 switch (lcode)
202 {
203 case TF_LC_CREATE:
204 return m_fnLayoutChange(3, m_fnEndEdit, pContextView);
205 case TF_LC_CHANGE:
206 return m_fnLayoutChange(2, m_fnEndEdit, pContextView);
207 case TF_LC_DESTROY:
208 return m_fnLayoutChange(4, m_fnEndEdit, pContextView);
209 default:
210 return E_INVALIDARG;
211 }
212}
213
216{
219
220 ITfSource *pSource = NULL;
221 HRESULT hr = pUnknown->QueryInterface(IID_ITfSource, (void**)&pSource);
222 if (SUCCEEDED(hr))
223 {
224 ITfTextEditSink *pSink = static_cast<ITfTextEditSink*>(this);
225 if (uFlags & 1)
226 hr = pSource->AdviseSink(IID_ITfTextEditSink, pSink, &m_dwEditSinkCookie);
227 if (SUCCEEDED(hr) && (uFlags & 2))
228 hr = pSource->AdviseSink(IID_ITfTextLayoutSink, pSink, &m_dwLayoutSinkCookie);
229
230 if (SUCCEEDED(hr))
231 {
233 pUnknown->AddRef();
234 }
235 else
236 {
238 }
239 }
240
241 if (pSource)
242 pSource->Release();
243
244 return hr;
245}
246
249{
250 if (!m_pUnknown)
251 return E_FAIL;
252
253 ITfSource *pSource = NULL;
254 HRESULT hr = m_pUnknown->QueryInterface(IID_ITfSource, (void**)&pSource);
255 if (SUCCEEDED(hr))
256 {
257 if (m_uFlags & 1)
259 if (m_uFlags & 2)
261
262 pSource->Release();
263 }
264
267
268 return E_NOTIMPL;
269}
270
271/***********************************************************************/
272
275 _In_ FN_INITDOCMGR fnInit,
276 _In_ FN_PUSHPOP fnPushPop,
277 _Inout_ LPVOID pvCallbackPV)
278{
279 m_fnInit = fnInit;
280 m_fnPushPop = fnPushPop;
281 m_pCallbackPV = pvCallbackPV;
282 m_cRefs = 1;
283}
284
287{
288 static const QITAB c_tab[] =
289 {
291 { NULL }
292 };
293 return ::QISearch(this, c_tab, riid, ppvObj);
294}
295
298{
299 return ::InterlockedIncrement(&m_cRefs);
300}
301
304{
306 {
307 delete this;
308 return 0;
309 }
310 return m_cRefs;
311}
312
315 UINT nCode,
316 ITfDocumentMgr *pDocMgr1,
317 ITfDocumentMgr *pDocMgr2,
318 LPVOID pUserData)
319{
320 return E_NOTIMPL;
321}
322
324{
325 if (!m_fnInit)
326 return S_OK;
327 return m_fnInit(0, pdim, NULL, m_pCallbackPV);
328}
329
331{
332 if (!m_fnInit)
333 return S_OK;
334 return m_fnInit(1, pdim, NULL, m_pCallbackPV);
335}
336
339{
340 if (!m_fnInit)
341 return S_OK;
342 return m_fnInit(2, pdimFocus, pdimPrevFocus, m_pCallbackPV);
343}
344
346{
347 if (!m_fnPushPop)
348 return S_OK;
349 return m_fnPushPop(3, pic, m_pCallbackPV);
350}
351
353{
354 if (!m_fnPushPop)
355 return S_OK;
356 return m_fnPushPop(4, pic, m_pCallbackPV);
357}
358
360{
361 if (!m_pCallbackPV)
362 m_pCallbackPV = pv;
363}
364
366{
368
369 HRESULT hr = E_FAIL;
370 ITfSource *pSource = NULL;
371 if (pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource) == S_OK &&
372 pSource->AdviseSink(IID_ITfThreadMgrEventSink, this, &m_dwCookie) == S_OK)
373 {
374 m_pThreadMgr = pThreadMgr;
375 pThreadMgr->AddRef();
376 hr = S_OK;
377 }
378
379 if (pSource)
380 pSource->Release();
381
382 return hr;
383}
384
386{
387 HRESULT hr = E_FAIL;
388 ITfSource *pSource = NULL;
389
390 if (m_pThreadMgr)
391 {
392 if (m_pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource) == S_OK &&
393 pSource->UnadviseSink(m_dwCookie) == S_OK)
394 {
395 hr = S_OK;
396 }
397
398 if (pSource)
399 pSource->Release();
400 }
401
402 if (m_pThreadMgr)
403 {
406 }
407
408 return hr;
409}
410
411/***********************************************************************/
412
415 _In_ FN_COMPARE fnCompare,
416 _Inout_opt_ void *pUserData)
417{
418 m_dwConnection = (DWORD)-1;
419 m_fnCompare = fnCompare;
420 m_cRefs = 1;
421 m_pUserData = pUserData;
422}
423
426{
427}
428
431{
432 static const QITAB c_tab[] =
433 {
435 { NULL }
436 };
437 return ::QISearch(this, c_tab, riid, ppvObj);
438}
439
442{
443 return ::InterlockedIncrement(&m_cRefs);
444}
445
448{
450 {
451 delete this;
452 return 0;
453 }
454 return m_cRefs;
455}
456
462 BOOL fActivated)
463{
464 if (!m_fnCompare)
465 return 0;
466
467 return m_fnCompare(clsid, guidProfile, fActivated, m_pUserData);
468}
469
473 ITfThreadMgr *pThreadMgr)
474{
476
477 ITfSource *pSource = NULL;
478 HRESULT hr = pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource);
479 if (FAILED(hr))
480 return E_FAIL;
481
482 hr = pSource->AdviseSink(IID_ITfActiveLanguageProfileNotifySink, this, &m_dwConnection);
483 if (SUCCEEDED(hr))
484 {
485 m_pThreadMgr = pThreadMgr;
486 pThreadMgr->AddRef();
487 hr = S_OK;
488 }
489 else
490 {
491 hr = E_FAIL;
492 }
493
494 if (pSource)
495 pSource->Release();
496
497 return hr;
498}
499
503{
504 if (!m_pThreadMgr)
505 return E_FAIL;
506
507 ITfSource *pSource = NULL;
508 HRESULT hr = m_pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource);
509 if (SUCCEEDED(hr))
510 {
511 hr = pSource->UnadviseSink(m_dwConnection);
512 if (SUCCEEDED(hr))
513 hr = S_OK;
514 }
515
516 if (pSource)
517 pSource->Release();
518
519 if (m_pThreadMgr)
520 {
523 }
524
525 return hr;
526}
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define STDMETHODIMP
Definition: basetyps.h:43
#define STDMETHODIMP_(t)
Definition: basetyps.h:44
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObj) override
@implemented
Definition: sinks.cpp:430
ITfThreadMgr * m_pThreadMgr
Definition: sinks.h:143
HRESULT _Advise(ITfThreadMgr *pThreadMgr)
@implemented
Definition: sinks.cpp:472
virtual ~CActiveLanguageProfileNotifySink()
@implemented
Definition: sinks.cpp:425
CActiveLanguageProfileNotifySink(_In_ FN_COMPARE fnCompare, _Inout_opt_ void *pUserData)
@implemented
Definition: sinks.cpp:414
STDMETHODIMP OnActivated(REFCLSID clsid, REFGUID guidProfile, BOOL fActivated) override
@implemented
Definition: sinks.cpp:459
HRESULT _Unadvise()
@implemented
Definition: sinks.cpp:502
LPVOID m_pUserData
Definition: sinks.h:25
FN_EVENTSINK m_fnEventSink
Definition: sinks.h:24
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObj) override
@implemented
Definition: sinks.cpp:27
CicArray< CESMAP > m_array
Definition: sinks.h:22
HRESULT _Advise(IUnknown *pUnknown, REFGUID rguid, BOOL bThread)
@implemented
Definition: sinks.cpp:62
HRESULT _Unadvise()
@implemented
Definition: sinks.cpp:100
virtual ~CCompartmentEventSink()
@implemented
Definition: sinks.cpp:22
STDMETHODIMP OnChange(REFGUID rguid) override
@implemented
Definition: sinks.cpp:55
CCompartmentEventSink(FN_EVENTSINK fnEventSink, LPVOID pUserData)
@implemented
Definition: sinks.cpp:13
IUnknown * m_pUnknown
Definition: sinks.h:52
DWORD m_dwLayoutSinkCookie
Definition: sinks.h:54
HRESULT _Unadvise()
@implemented
Definition: sinks.cpp:248
HRESULT _Advise(IUnknown *pUnknown, UINT uFlags)
@implemented
Definition: sinks.cpp:215
LONG m_cRefs
Definition: sinks.h:51
DWORD m_dwEditSinkCookie
Definition: sinks.h:53
STDMETHODIMP OnLayoutChange(ITfContext *pContext, TfLayoutCode lcode, ITfContextView *pContextView) override
@implemented
Definition: sinks.cpp:196
CTextEventSink(FN_ENDEDIT fnEndEdit, LPVOID pCallbackPV)
@implemented
Definition: sinks.cpp:133
FN_LAYOUTCHANGE m_fnLayoutChange
Definition: sinks.h:58
virtual ~CTextEventSink()
@implemented
Definition: sinks.cpp:145
UINT m_uFlags
Definition: sinks.h:57
LPVOID m_pCallbackPV
Definition: sinks.h:61
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObj) override
@implemented
Definition: sinks.cpp:150
FN_ENDEDIT m_fnEndEdit
Definition: sinks.h:60
STDMETHODIMP OnEndEdit(ITfContext *pic, TfEditCookie ecReadOnly, ITfEditRecord *pEditRecord) override
@implemented
Definition: sinks.cpp:186
FN_INITDOCMGR m_fnInit
Definition: sinks.h:99
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObj) override
@implemented
Definition: sinks.cpp:286
STDMETHODIMP OnInitDocumentMgr(ITfDocumentMgr *pdim) override
Definition: sinks.cpp:323
STDMETHODIMP OnUninitDocumentMgr(ITfDocumentMgr *pdim) override
Definition: sinks.cpp:330
ITfThreadMgr * m_pThreadMgr
Definition: sinks.h:97
HRESULT _Unadvise()
Definition: sinks.cpp:385
FN_PUSHPOP m_fnPushPop
Definition: sinks.h:100
DWORD m_dwCookie
Definition: sinks.h:98
STDMETHODIMP OnPushContext(ITfContext *pic) override
Definition: sinks.cpp:345
static INT CALLBACK DIMCallback(UINT nCode, ITfDocumentMgr *pDocMgr1, ITfDocumentMgr *pDocMgr2, LPVOID pUserData)
Definition: sinks.cpp:314
LPVOID m_pCallbackPV
Definition: sinks.h:102
CThreadMgrEventSink(_In_ FN_INITDOCMGR fnInit, _In_ FN_PUSHPOP fnPushPop=NULL, _Inout_ LPVOID pvCallbackPV=NULL)
@implemented
Definition: sinks.cpp:274
STDMETHODIMP OnSetFocus(ITfDocumentMgr *pdimFocus, ITfDocumentMgr *pdimPrevFocus) override
Definition: sinks.cpp:338
STDMETHODIMP OnPopContext(ITfContext *pic) override
Definition: sinks.cpp:352
void SetCallbackPV(_Inout_ LPVOID pv)
Definition: sinks.cpp:359
HRESULT _Advise(ITfThreadMgr *pThreadMgr)
Definition: sinks.cpp:365
void Remove(size_t iItem, size_t cRemove=1)
Definition: cicarray.cpp:57
size_t size() const
Definition: cicarray.h:34
T_ITEM * Append(size_t cGrow)
Definition: cicarray.h:52
T_ITEM * data() const
Definition: cicarray.h:33
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
HRESULT GetCompartment(IUnknown *pUnknown, REFGUID rguid, ITfCompartment **ppComp, BOOL bThread)
@implemented
Definition: misc.cpp:219
UINT uFlags
Definition: api.c:59
#define CALLBACK
Definition: compat.h:35
_In_ PUNKNOWN pUnknown
Definition: drmk.h:76
unsigned int BOOL
Definition: ntddk_ex.h:94
REFIID riid
Definition: atlbase.h:39
HRESULT AdviseSink([in] REFIID riid, [in, iid_is(riid)] IUnknown *punk, [out] DWORD *pdwCookie)
HRESULT UnadviseSink([in] DWORD dwCookie)
ULONG AddRef()
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
ULONG Release()
nsrefcnt Release()
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define _Inout_
Definition: ms_sal.h:378
#define _Inout_opt_
Definition: ms_sal.h:379
#define _In_
Definition: ms_sal.h:308
REFCLSID clsid
Definition: msctf.c:82
GUID guidProfile
Definition: msctf.idl:646
DWORD TfEditCookie
Definition: msctf.idl:104
unsigned int UINT
Definition: ndis.h:50
#define DWORD
Definition: nt_native.h:44
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
HRESULT hr
Definition: shlfolder.c:183
#define QITABENT(Cthis, Ifoo)
Definition: shlwapi.h:2094
INT(CALLBACK * FN_PUSHPOP)(UINT, ITfContext *, LPVOID)
Definition: sinks.h:92
INT(CALLBACK * FN_ENDEDIT)(INT, LPVOID, LPVOID)
Definition: sinks.h:45
INT(CALLBACK * FN_INITDOCMGR)(UINT, ITfDocumentMgr *, ITfDocumentMgr *, LPVOID)
Definition: sinks.h:91
INT(CALLBACK * FN_EVENTSINK)(LPVOID, REFGUID)
Definition: sinks.h:18
Definition: sinks.h:13
DWORD m_dwCookie
Definition: sinks.h:15
ITfCompartment * m_pComp
Definition: sinks.h:14
ITfEditRecord * m_pEditRecord
Definition: sinks.cpp:181
TfEditCookie m_ecReadOnly
Definition: sinks.cpp:180
ITfContext * m_pContext
Definition: sinks.cpp:182
Definition: scsiwmi.h:51
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59