2 * ITfThreadMgr implementation
4 * Copyright 2008 Aric Stewart, CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/debug.h"
37 #include "wine/unicode.h"
38 #include "wine/list.h"
41 #include "msctf_internal.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(msctf
);
45 typedef struct tagThreadMgrSink
{
50 /* ITfActiveLanguageProfileNotifySink *pITfActiveLanguageProfileNotifySink; */
51 /* ITfDisplayAttributeNotifySink *pITfDisplayAttributeNotifySink; */
52 /* ITfKeyTraceEventSink *pITfKeyTraceEventSink; */
53 /* ITfPreservedKeyNotifySink *pITfPreservedKeyNotifySink; */
54 /* ITfThreadFocusSink *pITfThreadFocusSink; */
55 ITfThreadMgrEventSink
*pITfThreadMgrEventSink
;
59 typedef struct tagPreservedKey
63 TF_PRESERVEDKEY prekey
;
68 typedef struct tagDocumentMgrs
71 ITfDocumentMgr
*docmgr
;
74 typedef struct tagAssociatedWindow
78 ITfDocumentMgr
*docmgr
;
81 typedef struct tagACLMulti
{
82 ITfThreadMgr ITfThreadMgr_iface
;
83 ITfSource ITfSource_iface
;
84 ITfKeystrokeMgr ITfKeystrokeMgr_iface
;
85 ITfMessagePump ITfMessagePump_iface
;
86 ITfClientId ITfClientId_iface
;
87 /* const ITfThreadMgrExVtbl *ThreadMgrExVtbl; */
88 /* const ITfConfigureSystemKeystrokeFeedVtbl *ConfigureSystemKeystrokeFeedVtbl; */
89 /* const ITfLangBarItemMgrVtbl *LangBarItemMgrVtbl; */
90 /* const ITfUIElementMgrVtbl *UIElementMgrVtbl; */
91 ITfSourceSingle ITfSourceSingle_iface
;
95 ITfCompartmentMgr
*CompartmentMgr
;
97 ITfThreadMgrEventSink ITfThreadMgrEventSink_iface
; /* internal */
99 ITfDocumentMgr
*focus
;
100 LONG activationCount
;
102 ITfKeyEventSink
*forgroundKeyEventSink
;
103 CLSID forgroundTextService
;
105 struct list CurrentPreservedKeys
;
106 struct list CreatedDocumentMgrs
;
108 struct list AssociatedFocusWindows
;
111 /* kept as separate lists to reduce unnecessary iterations */
112 struct list ActiveLanguageProfileNotifySink
;
113 struct list DisplayAttributeNotifySink
;
114 struct list KeyTraceEventSink
;
115 struct list PreservedKeyNotifySink
;
116 struct list ThreadFocusSink
;
117 struct list ThreadMgrEventSink
;
120 typedef struct tagEnumTfDocumentMgr
{
121 IEnumTfDocumentMgrs IEnumTfDocumentMgrs_iface
;
128 static HRESULT
EnumTfDocumentMgr_Constructor(struct list
* head
, IEnumTfDocumentMgrs
**ppOut
);
130 static inline ThreadMgr
*impl_from_ITfThreadMgr(ITfThreadMgr
*iface
)
132 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfThreadMgr_iface
);
135 static inline ThreadMgr
*impl_from_ITfSource(ITfSource
*iface
)
137 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfSource_iface
);
140 static inline ThreadMgr
*impl_from_ITfKeystrokeMgr(ITfKeystrokeMgr
*iface
)
142 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfKeystrokeMgr_iface
);
145 static inline ThreadMgr
*impl_from_ITfMessagePump(ITfMessagePump
*iface
)
147 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfMessagePump_iface
);
150 static inline ThreadMgr
*impl_from_ITfClientId(ITfClientId
*iface
)
152 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfClientId_iface
);
155 static inline ThreadMgr
*impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink
*iface
)
157 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfThreadMgrEventSink_iface
);
160 static inline ThreadMgr
*impl_from_ITfSourceSingle(ITfSourceSingle
*iface
)
162 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfSourceSingle_iface
);
165 static inline EnumTfDocumentMgr
*impl_from_IEnumTfDocumentMgrs(IEnumTfDocumentMgrs
*iface
)
167 return CONTAINING_RECORD(iface
, EnumTfDocumentMgr
, IEnumTfDocumentMgrs_iface
);
170 static void free_sink(ThreadMgrSink
*sink
)
172 IUnknown_Release(sink
->interfaces
.pIUnknown
);
173 HeapFree(GetProcessHeap(),0,sink
);
176 static void ThreadMgr_Destructor(ThreadMgr
*This
)
178 struct list
*cursor
, *cursor2
;
180 /* unhook right away */
182 UnhookWindowsHookEx(This
->focusHook
);
184 TlsSetValue(tlsIndex
,NULL
);
185 TRACE("destroying %p\n", This
);
187 ITfDocumentMgr_Release(This
->focus
);
190 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ActiveLanguageProfileNotifySink
)
192 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
196 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->DisplayAttributeNotifySink
)
198 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
202 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->KeyTraceEventSink
)
204 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
208 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->PreservedKeyNotifySink
)
210 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
214 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ThreadFocusSink
)
216 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
220 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ThreadMgrEventSink
)
222 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
227 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->CurrentPreservedKeys
)
229 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
231 HeapFree(GetProcessHeap(),0,key
->description
);
232 HeapFree(GetProcessHeap(),0,key
);
235 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->CreatedDocumentMgrs
)
237 DocumentMgrEntry
*mgr
= LIST_ENTRY(cursor
,DocumentMgrEntry
,entry
);
239 FIXME("Left Over ITfDocumentMgr. Should we do something with it?\n");
240 HeapFree(GetProcessHeap(),0,mgr
);
243 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->AssociatedFocusWindows
)
245 AssociatedWindow
*wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
247 HeapFree(GetProcessHeap(),0,wnd
);
250 CompartmentMgr_Destructor(This
->CompartmentMgr
);
252 HeapFree(GetProcessHeap(),0,This
);
255 static HRESULT WINAPI
ThreadMgr_QueryInterface(ITfThreadMgr
*iface
, REFIID iid
, LPVOID
*ppvOut
)
257 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
260 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfThreadMgr
))
262 *ppvOut
= &This
->ITfThreadMgr_iface
;
264 else if (IsEqualIID(iid
, &IID_ITfSource
))
266 *ppvOut
= &This
->ITfSource_iface
;
268 else if (IsEqualIID(iid
, &IID_ITfKeystrokeMgr
))
270 *ppvOut
= &This
->ITfKeystrokeMgr_iface
;
272 else if (IsEqualIID(iid
, &IID_ITfMessagePump
))
274 *ppvOut
= &This
->ITfMessagePump_iface
;
276 else if (IsEqualIID(iid
, &IID_ITfClientId
))
278 *ppvOut
= &This
->ITfClientId_iface
;
280 else if (IsEqualIID(iid
, &IID_ITfCompartmentMgr
))
282 *ppvOut
= This
->CompartmentMgr
;
284 else if (IsEqualIID(iid
, &IID_ITfSourceSingle
))
286 *ppvOut
= &This
->ITfSourceSingle_iface
;
291 ITfThreadMgr_AddRef(iface
);
295 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
296 return E_NOINTERFACE
;
299 static ULONG WINAPI
ThreadMgr_AddRef(ITfThreadMgr
*iface
)
301 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
302 return InterlockedIncrement(&This
->refCount
);
305 static ULONG WINAPI
ThreadMgr_Release(ITfThreadMgr
*iface
)
307 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
310 ret
= InterlockedDecrement(&This
->refCount
);
312 ThreadMgr_Destructor(This
);
316 /*****************************************************
317 * ITfThreadMgr functions
318 *****************************************************/
320 static HRESULT WINAPI
ThreadMgr_fnActivate( ITfThreadMgr
* iface
, TfClientId
*ptid
)
322 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
324 TRACE("(%p) %p\n",This
, ptid
);
333 ITfClientId_GetClientId(&This
->ITfClientId_iface
, &guid
, &processId
);
336 activate_textservices(iface
);
337 This
->activationCount
++;
342 static HRESULT WINAPI
ThreadMgr_fnDeactivate( ITfThreadMgr
* iface
)
344 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
345 TRACE("(%p)\n",This
);
347 if (This
->activationCount
== 0)
350 This
->activationCount
--;
352 if (This
->activationCount
== 0)
356 ITfThreadMgrEventSink_OnSetFocus(&This
->ITfThreadMgrEventSink_iface
, 0, This
->focus
);
357 ITfDocumentMgr_Release(This
->focus
);
362 deactivate_textservices();
367 static HRESULT WINAPI
ThreadMgr_CreateDocumentMgr(ITfThreadMgr
* iface
, ITfDocumentMgr
**ppdim
)
369 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
370 DocumentMgrEntry
*mgrentry
;
373 TRACE("(%p)\n",iface
);
374 mgrentry
= HeapAlloc(GetProcessHeap(),0,sizeof(DocumentMgrEntry
));
375 if (mgrentry
== NULL
)
376 return E_OUTOFMEMORY
;
378 hr
= DocumentMgr_Constructor(&This
->ITfThreadMgrEventSink_iface
, ppdim
);
382 mgrentry
->docmgr
= *ppdim
;
383 list_add_head(&This
->CreatedDocumentMgrs
,&mgrentry
->entry
);
386 HeapFree(GetProcessHeap(),0,mgrentry
);
391 static HRESULT WINAPI
ThreadMgr_EnumDocumentMgrs( ITfThreadMgr
* iface
, IEnumTfDocumentMgrs
**ppEnum
)
393 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
394 TRACE("(%p) %p\n",This
,ppEnum
);
399 return EnumTfDocumentMgr_Constructor(&This
->CreatedDocumentMgrs
, ppEnum
);
402 static HRESULT WINAPI
ThreadMgr_GetFocus( ITfThreadMgr
* iface
, ITfDocumentMgr
405 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
406 TRACE("(%p)\n",This
);
411 *ppdimFocus
= This
->focus
;
413 TRACE("->%p\n",This
->focus
);
415 if (This
->focus
== NULL
)
418 ITfDocumentMgr_AddRef(This
->focus
);
423 static HRESULT WINAPI
ThreadMgr_SetFocus( ITfThreadMgr
* iface
, ITfDocumentMgr
*pdimFocus
)
425 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
426 ITfDocumentMgr
*check
;
428 TRACE("(%p) %p\n",This
,pdimFocus
);
432 else if (FAILED(ITfDocumentMgr_QueryInterface(pdimFocus
,&IID_ITfDocumentMgr
,(LPVOID
*) &check
)))
435 ITfThreadMgrEventSink_OnSetFocus(&This
->ITfThreadMgrEventSink_iface
, check
, This
->focus
);
438 ITfDocumentMgr_Release(This
->focus
);
444 static LRESULT CALLBACK
ThreadFocusHookProc(int nCode
, WPARAM wParam
, LPARAM lParam
)
448 This
= TlsGetValue(tlsIndex
);
451 ERR("Hook proc but no ThreadMgr for this thread. Serious Error\n");
454 if (!This
->focusHook
)
456 ERR("Hook proc but no ThreadMgr focus Hook. Serious Error\n");
460 if (nCode
== HCBT_SETFOCUS
) /* focus change within our thread */
464 LIST_FOR_EACH(cursor
, &This
->AssociatedFocusWindows
)
466 AssociatedWindow
*wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
467 if (wnd
->hwnd
== (HWND
)wParam
)
469 TRACE("Triggering Associated window focus\n");
470 if (This
->focus
!= wnd
->docmgr
)
471 ThreadMgr_SetFocus((ITfThreadMgr
*)This
, wnd
->docmgr
);
477 return CallNextHookEx(This
->focusHook
, nCode
, wParam
, lParam
);
480 static HRESULT
SetupWindowsHook(ThreadMgr
*This
)
482 if (!This
->focusHook
)
484 This
->focusHook
= SetWindowsHookExW(WH_CBT
, ThreadFocusHookProc
, 0,
485 GetCurrentThreadId());
486 if (!This
->focusHook
)
488 ERR("Unable to set focus hook\n");
496 static HRESULT WINAPI
ThreadMgr_AssociateFocus( ITfThreadMgr
* iface
, HWND hwnd
,
497 ITfDocumentMgr
*pdimNew
, ITfDocumentMgr
**ppdimPrev
)
499 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
500 struct list
*cursor
, *cursor2
;
501 AssociatedWindow
*wnd
;
503 TRACE("(%p) %p %p %p\n",This
,hwnd
,pdimNew
,ppdimPrev
);
510 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->AssociatedFocusWindows
)
512 wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
513 if (wnd
->hwnd
== hwnd
)
516 ITfDocumentMgr_AddRef(wnd
->docmgr
);
517 *ppdimPrev
= wnd
->docmgr
;
518 wnd
->docmgr
= pdimNew
;
519 if (GetFocus() == hwnd
)
520 ThreadMgr_SetFocus(iface
,pdimNew
);
525 wnd
= HeapAlloc(GetProcessHeap(),0,sizeof(AssociatedWindow
));
527 wnd
->docmgr
= pdimNew
;
528 list_add_head(&This
->AssociatedFocusWindows
,&wnd
->entry
);
530 if (GetFocus() == hwnd
)
531 ThreadMgr_SetFocus(iface
,pdimNew
);
533 SetupWindowsHook(This
);
538 static HRESULT WINAPI
ThreadMgr_IsThreadFocus( ITfThreadMgr
* iface
, BOOL
*pfThreadFocus
)
540 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
543 TRACE("(%p) %p\n",This
,pfThreadFocus
);
545 *pfThreadFocus
= (focus
== NULL
);
549 static HRESULT WINAPI
ThreadMgr_GetFunctionProvider( ITfThreadMgr
* iface
, REFCLSID clsid
,
550 ITfFunctionProvider
**ppFuncProv
)
552 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
553 FIXME("STUB:(%p)\n",This
);
557 static HRESULT WINAPI
ThreadMgr_EnumFunctionProviders( ITfThreadMgr
* iface
,
558 IEnumTfFunctionProviders
**ppEnum
)
560 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
561 FIXME("STUB:(%p)\n",This
);
565 static HRESULT WINAPI
ThreadMgr_GetGlobalCompartment( ITfThreadMgr
* iface
,
566 ITfCompartmentMgr
**ppCompMgr
)
568 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
570 TRACE("(%p) %p\n",This
, ppCompMgr
);
575 if (!globalCompartmentMgr
)
577 hr
= CompartmentMgr_Constructor(NULL
,&IID_ITfCompartmentMgr
,(IUnknown
**)&globalCompartmentMgr
);
582 ITfCompartmentMgr_AddRef(globalCompartmentMgr
);
583 *ppCompMgr
= globalCompartmentMgr
;
587 static const ITfThreadMgrVtbl ThreadMgrVtbl
=
589 ThreadMgr_QueryInterface
,
592 ThreadMgr_fnActivate
,
593 ThreadMgr_fnDeactivate
,
594 ThreadMgr_CreateDocumentMgr
,
595 ThreadMgr_EnumDocumentMgrs
,
598 ThreadMgr_AssociateFocus
,
599 ThreadMgr_IsThreadFocus
,
600 ThreadMgr_GetFunctionProvider
,
601 ThreadMgr_EnumFunctionProviders
,
602 ThreadMgr_GetGlobalCompartment
605 static HRESULT WINAPI
Source_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
607 ThreadMgr
*This
= impl_from_ITfSource(iface
);
608 return ITfThreadMgr_QueryInterface(&This
->ITfThreadMgr_iface
, iid
, ppvOut
);
611 static ULONG WINAPI
Source_AddRef(ITfSource
*iface
)
613 ThreadMgr
*This
= impl_from_ITfSource(iface
);
614 return ITfThreadMgr_AddRef(&This
->ITfThreadMgr_iface
);
617 static ULONG WINAPI
Source_Release(ITfSource
*iface
)
619 ThreadMgr
*This
= impl_from_ITfSource(iface
);
620 return ITfThreadMgr_Release(&This
->ITfThreadMgr_iface
);
623 /*****************************************************
624 * ITfSource functions
625 *****************************************************/
626 static HRESULT WINAPI
ThreadMgrSource_AdviseSink(ITfSource
*iface
,
627 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
629 ThreadMgr
*This
= impl_from_ITfSource(iface
);
632 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
634 if (!riid
|| !punk
|| !pdwCookie
)
637 if (IsEqualIID(riid
, &IID_ITfThreadMgrEventSink
))
639 tms
= HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink
));
641 return E_OUTOFMEMORY
;
642 if (FAILED(IUnknown_QueryInterface(punk
, riid
, (LPVOID
*)&tms
->interfaces
.pITfThreadMgrEventSink
)))
644 HeapFree(GetProcessHeap(),0,tms
);
645 return CONNECT_E_CANNOTCONNECT
;
647 list_add_head(&This
->ThreadMgrEventSink
,&tms
->entry
);
648 *pdwCookie
= generate_Cookie(COOKIE_MAGIC_TMSINK
, tms
);
652 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
656 TRACE("cookie %x\n",*pdwCookie
);
661 static HRESULT WINAPI
ThreadMgrSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
663 ThreadMgr
*This
= impl_from_ITfSource(iface
);
666 TRACE("(%p) %x\n",This
,pdwCookie
);
668 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_TMSINK
)
671 sink
= remove_Cookie(pdwCookie
);
673 return CONNECT_E_NOCONNECTION
;
675 list_remove(&sink
->entry
);
681 static const ITfSourceVtbl ThreadMgrSourceVtbl
=
683 Source_QueryInterface
,
686 ThreadMgrSource_AdviseSink
,
687 ThreadMgrSource_UnadviseSink
,
690 /*****************************************************
691 * ITfKeystrokeMgr functions
692 *****************************************************/
694 static HRESULT WINAPI
KeystrokeMgr_QueryInterface(ITfKeystrokeMgr
*iface
, REFIID iid
, LPVOID
*ppvOut
)
696 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
697 return ITfThreadMgr_QueryInterface(&This
->ITfThreadMgr_iface
, iid
, ppvOut
);
700 static ULONG WINAPI
KeystrokeMgr_AddRef(ITfKeystrokeMgr
*iface
)
702 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
703 return ITfThreadMgr_AddRef(&This
->ITfThreadMgr_iface
);
706 static ULONG WINAPI
KeystrokeMgr_Release(ITfKeystrokeMgr
*iface
)
708 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
709 return ITfThreadMgr_Release(&This
->ITfThreadMgr_iface
);
712 static HRESULT WINAPI
KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr
*iface
,
713 TfClientId tid
, ITfKeyEventSink
*pSink
, BOOL fForeground
)
715 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
717 ITfKeyEventSink
*check
= NULL
;
719 TRACE("(%p) %x %p %i\n",This
,tid
,pSink
,fForeground
);
724 textservice
= get_textservice_clsid(tid
);
725 if (IsEqualCLSID(&GUID_NULL
,&textservice
))
728 get_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
**)&check
);
730 return CONNECT_E_ADVISELIMIT
;
732 if (FAILED(ITfKeyEventSink_QueryInterface(pSink
,&IID_ITfKeyEventSink
,(LPVOID
*) &check
)))
735 set_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
*)check
);
739 if (This
->forgroundKeyEventSink
)
741 ITfKeyEventSink_OnSetFocus(This
->forgroundKeyEventSink
, FALSE
);
742 ITfKeyEventSink_Release(This
->forgroundKeyEventSink
);
744 ITfKeyEventSink_AddRef(check
);
745 ITfKeyEventSink_OnSetFocus(check
, TRUE
);
746 This
->forgroundKeyEventSink
= check
;
747 This
->forgroundTextService
= textservice
;
752 static HRESULT WINAPI
KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr
*iface
,
755 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
757 ITfKeyEventSink
*check
= NULL
;
758 TRACE("(%p) %x\n",This
,tid
);
763 textservice
= get_textservice_clsid(tid
);
764 if (IsEqualCLSID(&GUID_NULL
,&textservice
))
767 get_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
**)&check
);
770 return CONNECT_E_NOCONNECTION
;
772 set_textservice_sink(tid
, &IID_ITfKeyEventSink
, NULL
);
773 ITfKeyEventSink_Release(check
);
775 if (This
->forgroundKeyEventSink
== check
)
777 ITfKeyEventSink_Release(This
->forgroundKeyEventSink
);
778 This
->forgroundKeyEventSink
= NULL
;
779 This
->forgroundTextService
= GUID_NULL
;
784 static HRESULT WINAPI
KeystrokeMgr_GetForeground(ITfKeystrokeMgr
*iface
,
787 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
788 TRACE("(%p) %p\n",This
,pclsid
);
792 if (IsEqualCLSID(&This
->forgroundTextService
,&GUID_NULL
))
795 *pclsid
= This
->forgroundTextService
;
799 static HRESULT WINAPI
KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr
*iface
,
800 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
802 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
803 FIXME("STUB:(%p)\n",This
);
807 static HRESULT WINAPI
KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr
*iface
,
808 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
810 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
811 FIXME("STUB:(%p)\n",This
);
815 static HRESULT WINAPI
KeystrokeMgr_KeyDown(ITfKeystrokeMgr
*iface
,
816 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
818 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
819 FIXME("STUB:(%p)\n",This
);
823 static HRESULT WINAPI
KeystrokeMgr_KeyUp(ITfKeystrokeMgr
*iface
,
824 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
826 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
827 FIXME("STUB:(%p)\n",This
);
831 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr
*iface
,
832 ITfContext
*pic
, const TF_PRESERVEDKEY
*pprekey
, GUID
*pguid
)
834 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
835 FIXME("STUB:(%p)\n",This
);
839 static HRESULT WINAPI
KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr
*iface
,
840 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
, BOOL
*pfRegistered
)
842 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
845 TRACE("(%p) %s (%x %x) %p\n",This
,debugstr_guid(rguid
), (pprekey
)?pprekey
->uVKey
:0, (pprekey
)?pprekey
->uModifiers
:0, pfRegistered
);
847 if (!rguid
|| !pprekey
|| !pfRegistered
)
850 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
852 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
853 if (IsEqualGUID(rguid
,&key
->guid
) && pprekey
->uVKey
== key
->prekey
.uVKey
&& pprekey
->uModifiers
== key
->prekey
.uModifiers
)
855 *pfRegistered
= TRUE
;
860 *pfRegistered
= FALSE
;
864 static HRESULT WINAPI
KeystrokeMgr_PreserveKey(ITfKeystrokeMgr
*iface
,
865 TfClientId tid
, REFGUID rguid
, const TF_PRESERVEDKEY
*prekey
,
866 const WCHAR
*pchDesc
, ULONG cchDesc
)
868 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
870 PreservedKey
*newkey
;
872 TRACE("(%p) %x %s (%x,%x) %s\n",This
,tid
, debugstr_guid(rguid
),(prekey
)?prekey
->uVKey
:0,(prekey
)?prekey
->uModifiers
:0,debugstr_wn(pchDesc
,cchDesc
));
874 if (!tid
|| ! rguid
|| !prekey
|| (cchDesc
&& !pchDesc
))
877 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
879 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
880 if (IsEqualGUID(rguid
,&key
->guid
) && prekey
->uVKey
== key
->prekey
.uVKey
&& prekey
->uModifiers
== key
->prekey
.uModifiers
)
881 return TF_E_ALREADY_EXISTS
;
884 newkey
= HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey
));
886 return E_OUTOFMEMORY
;
888 newkey
->guid
= *rguid
;
889 newkey
->prekey
= *prekey
;
891 newkey
->description
= NULL
;
894 newkey
->description
= HeapAlloc(GetProcessHeap(),0,cchDesc
* sizeof(WCHAR
));
895 if (!newkey
->description
)
897 HeapFree(GetProcessHeap(),0,newkey
);
898 return E_OUTOFMEMORY
;
900 memcpy(newkey
->description
, pchDesc
, cchDesc
*sizeof(WCHAR
));
903 list_add_head(&This
->CurrentPreservedKeys
,&newkey
->entry
);
908 static HRESULT WINAPI
KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr
*iface
,
909 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
)
911 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
912 PreservedKey
* key
= NULL
;
914 TRACE("(%p) %s (%x %x)\n",This
,debugstr_guid(rguid
),(pprekey
)?pprekey
->uVKey
:0, (pprekey
)?pprekey
->uModifiers
:0);
916 if (!pprekey
|| !rguid
)
919 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
921 key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
922 if (IsEqualGUID(rguid
,&key
->guid
) && pprekey
->uVKey
== key
->prekey
.uVKey
&& pprekey
->uModifiers
== key
->prekey
.uModifiers
)
928 return CONNECT_E_NOCONNECTION
;
930 list_remove(&key
->entry
);
931 HeapFree(GetProcessHeap(),0,key
->description
);
932 HeapFree(GetProcessHeap(),0,key
);
937 static HRESULT WINAPI
KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
938 REFGUID rguid
, const WCHAR
*pchDesc
, ULONG cchDesc
)
940 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
941 FIXME("STUB:(%p)\n",This
);
945 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
946 REFGUID rguid
, BSTR
*pbstrDesc
)
948 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
949 FIXME("STUB:(%p)\n",This
);
953 static HRESULT WINAPI
KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr
*iface
,
954 ITfContext
*pic
, REFGUID rguid
, BOOL
*pfEaten
)
956 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
957 FIXME("STUB:(%p)\n",This
);
961 static const ITfKeystrokeMgrVtbl KeystrokeMgrVtbl
=
963 KeystrokeMgr_QueryInterface
,
965 KeystrokeMgr_Release
,
966 KeystrokeMgr_AdviseKeyEventSink
,
967 KeystrokeMgr_UnadviseKeyEventSink
,
968 KeystrokeMgr_GetForeground
,
969 KeystrokeMgr_TestKeyDown
,
970 KeystrokeMgr_TestKeyUp
,
971 KeystrokeMgr_KeyDown
,
973 KeystrokeMgr_GetPreservedKey
,
974 KeystrokeMgr_IsPreservedKey
,
975 KeystrokeMgr_PreserveKey
,
976 KeystrokeMgr_UnpreserveKey
,
977 KeystrokeMgr_SetPreservedKeyDescription
,
978 KeystrokeMgr_GetPreservedKeyDescription
,
979 KeystrokeMgr_SimulatePreservedKey
982 /*****************************************************
983 * ITfMessagePump functions
984 *****************************************************/
986 static HRESULT WINAPI
MessagePump_QueryInterface(ITfMessagePump
*iface
, REFIID iid
, LPVOID
*ppvOut
)
988 ThreadMgr
*This
= impl_from_ITfMessagePump(iface
);
989 return ITfThreadMgr_QueryInterface(&This
->ITfThreadMgr_iface
, iid
, ppvOut
);
992 static ULONG WINAPI
MessagePump_AddRef(ITfMessagePump
*iface
)
994 ThreadMgr
*This
= impl_from_ITfMessagePump(iface
);
995 return ITfThreadMgr_AddRef(&This
->ITfThreadMgr_iface
);
998 static ULONG WINAPI
MessagePump_Release(ITfMessagePump
*iface
)
1000 ThreadMgr
*This
= impl_from_ITfMessagePump(iface
);
1001 return ITfThreadMgr_Release(&This
->ITfThreadMgr_iface
);
1004 static HRESULT WINAPI
MessagePump_PeekMessageA(ITfMessagePump
*iface
,
1005 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1006 UINT wRemoveMsg
, BOOL
*pfResult
)
1009 return E_INVALIDARG
;
1010 *pfResult
= PeekMessageA(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
1014 static HRESULT WINAPI
MessagePump_GetMessageA(ITfMessagePump
*iface
,
1015 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1019 return E_INVALIDARG
;
1020 *pfResult
= GetMessageA(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
);
1024 static HRESULT WINAPI
MessagePump_PeekMessageW(ITfMessagePump
*iface
,
1025 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1026 UINT wRemoveMsg
, BOOL
*pfResult
)
1029 return E_INVALIDARG
;
1030 *pfResult
= PeekMessageW(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
1034 static HRESULT WINAPI
MessagePump_GetMessageW(ITfMessagePump
*iface
,
1035 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1039 return E_INVALIDARG
;
1040 *pfResult
= GetMessageW(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
);
1044 static const ITfMessagePumpVtbl MessagePumpVtbl
=
1046 MessagePump_QueryInterface
,
1048 MessagePump_Release
,
1049 MessagePump_PeekMessageA
,
1050 MessagePump_GetMessageA
,
1051 MessagePump_PeekMessageW
,
1052 MessagePump_GetMessageW
1055 /*****************************************************
1056 * ITfClientId functions
1057 *****************************************************/
1059 static HRESULT WINAPI
ClientId_QueryInterface(ITfClientId
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1061 ThreadMgr
*This
= impl_from_ITfClientId(iface
);
1062 return ITfThreadMgr_QueryInterface(&This
->ITfThreadMgr_iface
, iid
, ppvOut
);
1065 static ULONG WINAPI
ClientId_AddRef(ITfClientId
*iface
)
1067 ThreadMgr
*This
= impl_from_ITfClientId(iface
);
1068 return ITfThreadMgr_AddRef(&This
->ITfThreadMgr_iface
);
1071 static ULONG WINAPI
ClientId_Release(ITfClientId
*iface
)
1073 ThreadMgr
*This
= impl_from_ITfClientId(iface
);
1074 return ITfThreadMgr_Release(&This
->ITfThreadMgr_iface
);
1077 static HRESULT WINAPI
ClientId_GetClientId(ITfClientId
*iface
,
1078 REFCLSID rclsid
, TfClientId
*ptid
)
1081 ThreadMgr
*This
= impl_from_ITfClientId(iface
);
1083 ITfCategoryMgr
*catmgr
;
1085 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
1087 CategoryMgr_Constructor(NULL
,(IUnknown
**)&catmgr
);
1088 hr
= ITfCategoryMgr_RegisterGUID(catmgr
,rclsid
,ptid
);
1089 ITfCategoryMgr_Release(catmgr
);
1094 static const ITfClientIdVtbl ClientIdVtbl
=
1096 ClientId_QueryInterface
,
1099 ClientId_GetClientId
1102 /*****************************************************
1103 * ITfThreadMgrEventSink functions (internal)
1104 *****************************************************/
1105 static HRESULT WINAPI
ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1107 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1108 return ITfThreadMgr_QueryInterface(&This
->ITfThreadMgr_iface
, iid
, ppvOut
);
1111 static ULONG WINAPI
ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink
*iface
)
1113 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1114 return ITfThreadMgr_AddRef(&This
->ITfThreadMgr_iface
);
1117 static ULONG WINAPI
ThreadMgrEventSink_Release(ITfThreadMgrEventSink
*iface
)
1119 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1120 return ITfThreadMgr_Release(&This
->ITfThreadMgr_iface
);
1124 static HRESULT WINAPI
ThreadMgrEventSink_OnInitDocumentMgr(
1125 ITfThreadMgrEventSink
*iface
,ITfDocumentMgr
*pdim
)
1127 struct list
*cursor
;
1128 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1130 TRACE("(%p) %p\n",This
,pdim
);
1132 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1134 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1135 ITfThreadMgrEventSink_OnInitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
1141 static HRESULT WINAPI
ThreadMgrEventSink_OnUninitDocumentMgr(
1142 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdim
)
1144 struct list
*cursor
;
1145 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1147 TRACE("(%p) %p\n",This
,pdim
);
1149 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1151 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1152 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
1158 static HRESULT WINAPI
ThreadMgrEventSink_OnSetFocus(
1159 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdimFocus
,
1160 ITfDocumentMgr
*pdimPrevFocus
)
1162 struct list
*cursor
;
1163 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1165 TRACE("(%p) %p %p\n",This
,pdimFocus
, pdimPrevFocus
);
1167 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1169 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1170 ITfThreadMgrEventSink_OnSetFocus(sink
->interfaces
.pITfThreadMgrEventSink
, pdimFocus
, pdimPrevFocus
);
1176 static HRESULT WINAPI
ThreadMgrEventSink_OnPushContext(
1177 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
1179 struct list
*cursor
;
1180 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1182 TRACE("(%p) %p\n",This
,pic
);
1184 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1186 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1187 ITfThreadMgrEventSink_OnPushContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
1193 static HRESULT WINAPI
ThreadMgrEventSink_OnPopContext(
1194 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
1196 struct list
*cursor
;
1197 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1199 TRACE("(%p) %p\n",This
,pic
);
1201 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1203 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1204 ITfThreadMgrEventSink_OnPopContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
1210 static const ITfThreadMgrEventSinkVtbl ThreadMgrEventSinkVtbl
=
1212 ThreadMgrEventSink_QueryInterface
,
1213 ThreadMgrEventSink_AddRef
,
1214 ThreadMgrEventSink_Release
,
1215 ThreadMgrEventSink_OnInitDocumentMgr
,
1216 ThreadMgrEventSink_OnUninitDocumentMgr
,
1217 ThreadMgrEventSink_OnSetFocus
,
1218 ThreadMgrEventSink_OnPushContext
,
1219 ThreadMgrEventSink_OnPopContext
1222 /*****************************************************
1223 * ITfSourceSingle functions
1224 *****************************************************/
1225 static HRESULT WINAPI
ThreadMgrSourceSingle_QueryInterface(ITfSourceSingle
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1227 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1228 return ITfThreadMgr_QueryInterface(&This
->ITfThreadMgr_iface
, iid
, ppvOut
);
1231 static ULONG WINAPI
ThreadMgrSourceSingle_AddRef(ITfSourceSingle
*iface
)
1233 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1234 return ITfThreadMgr_AddRef(&This
->ITfThreadMgr_iface
);
1237 static ULONG WINAPI
ThreadMgrSourceSingle_Release(ITfSourceSingle
*iface
)
1239 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1240 return ITfThreadMgr_Release(&This
->ITfThreadMgr_iface
);
1243 static HRESULT WINAPI
ThreadMgrSourceSingle_AdviseSingleSink( ITfSourceSingle
*iface
,
1244 TfClientId tid
, REFIID riid
, IUnknown
*punk
)
1246 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1247 FIXME("STUB:(%p) %i %s %p\n",This
, tid
, debugstr_guid(riid
),punk
);
1251 static HRESULT WINAPI
ThreadMgrSourceSingle_UnadviseSingleSink( ITfSourceSingle
*iface
,
1252 TfClientId tid
, REFIID riid
)
1254 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1255 FIXME("STUB:(%p) %i %s\n",This
, tid
, debugstr_guid(riid
));
1259 static const ITfSourceSingleVtbl SourceSingleVtbl
=
1261 ThreadMgrSourceSingle_QueryInterface
,
1262 ThreadMgrSourceSingle_AddRef
,
1263 ThreadMgrSourceSingle_Release
,
1264 ThreadMgrSourceSingle_AdviseSingleSink
,
1265 ThreadMgrSourceSingle_UnadviseSingleSink
1268 HRESULT
ThreadMgr_Constructor(IUnknown
*pUnkOuter
, IUnknown
**ppOut
)
1272 return CLASS_E_NOAGGREGATION
;
1274 /* Only 1 ThreadMgr is created per thread */
1275 This
= TlsGetValue(tlsIndex
);
1278 ThreadMgr_AddRef(&This
->ITfThreadMgr_iface
);
1279 *ppOut
= (IUnknown
*)&This
->ITfThreadMgr_iface
;
1283 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ThreadMgr
));
1285 return E_OUTOFMEMORY
;
1287 This
->ITfThreadMgr_iface
.lpVtbl
= &ThreadMgrVtbl
;
1288 This
->ITfSource_iface
.lpVtbl
= &ThreadMgrSourceVtbl
;
1289 This
->ITfKeystrokeMgr_iface
.lpVtbl
= &KeystrokeMgrVtbl
;
1290 This
->ITfMessagePump_iface
.lpVtbl
= &MessagePumpVtbl
;
1291 This
->ITfClientId_iface
.lpVtbl
= &ClientIdVtbl
;
1292 This
->ITfThreadMgrEventSink_iface
.lpVtbl
= &ThreadMgrEventSinkVtbl
;
1293 This
->ITfSourceSingle_iface
.lpVtbl
= &SourceSingleVtbl
;
1295 TlsSetValue(tlsIndex
,This
);
1297 CompartmentMgr_Constructor((IUnknown
*)This
, &IID_IUnknown
, (IUnknown
**)&This
->CompartmentMgr
);
1299 list_init(&This
->CurrentPreservedKeys
);
1300 list_init(&This
->CreatedDocumentMgrs
);
1301 list_init(&This
->AssociatedFocusWindows
);
1303 list_init(&This
->ActiveLanguageProfileNotifySink
);
1304 list_init(&This
->DisplayAttributeNotifySink
);
1305 list_init(&This
->KeyTraceEventSink
);
1306 list_init(&This
->PreservedKeyNotifySink
);
1307 list_init(&This
->ThreadFocusSink
);
1308 list_init(&This
->ThreadMgrEventSink
);
1310 TRACE("returning %p\n", This
);
1311 *ppOut
= (IUnknown
*)&This
->ITfThreadMgr_iface
;
1315 /**************************************************
1316 * IEnumTfDocumentMgrs implementation
1317 **************************************************/
1318 static void EnumTfDocumentMgr_Destructor(EnumTfDocumentMgr
*This
)
1320 TRACE("destroying %p\n", This
);
1321 HeapFree(GetProcessHeap(),0,This
);
1324 static HRESULT WINAPI
EnumTfDocumentMgr_QueryInterface(IEnumTfDocumentMgrs
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1326 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1329 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumTfDocumentMgrs
))
1331 *ppvOut
= &This
->IEnumTfDocumentMgrs_iface
;
1336 IEnumTfDocumentMgrs_AddRef(iface
);
1340 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
1341 return E_NOINTERFACE
;
1344 static ULONG WINAPI
EnumTfDocumentMgr_AddRef(IEnumTfDocumentMgrs
*iface
)
1346 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1347 return InterlockedIncrement(&This
->refCount
);
1350 static ULONG WINAPI
EnumTfDocumentMgr_Release(IEnumTfDocumentMgrs
*iface
)
1352 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1355 ret
= InterlockedDecrement(&This
->refCount
);
1357 EnumTfDocumentMgr_Destructor(This
);
1361 static HRESULT WINAPI
EnumTfDocumentMgr_Next(IEnumTfDocumentMgrs
*iface
,
1362 ULONG ulCount
, ITfDocumentMgr
**rgDocumentMgr
, ULONG
*pcFetched
)
1364 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1367 TRACE("(%p)\n",This
);
1369 if (rgDocumentMgr
== NULL
) return E_POINTER
;
1371 while (fetched
< ulCount
)
1373 DocumentMgrEntry
*mgrentry
;
1374 if (This
->index
== NULL
)
1377 mgrentry
= LIST_ENTRY(This
->index
,DocumentMgrEntry
,entry
);
1378 if (mgrentry
== NULL
)
1381 *rgDocumentMgr
= mgrentry
->docmgr
;
1382 ITfDocumentMgr_AddRef(*rgDocumentMgr
);
1384 This
->index
= list_next(This
->head
, This
->index
);
1389 if (pcFetched
) *pcFetched
= fetched
;
1390 return fetched
== ulCount
? S_OK
: S_FALSE
;
1393 static HRESULT WINAPI
EnumTfDocumentMgr_Skip( IEnumTfDocumentMgrs
* iface
, ULONG celt
)
1395 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1398 TRACE("(%p)\n",This
);
1399 for(i
= 0; i
< celt
&& This
->index
!= NULL
; i
++)
1400 This
->index
= list_next(This
->head
, This
->index
);
1404 static HRESULT WINAPI
EnumTfDocumentMgr_Reset( IEnumTfDocumentMgrs
* iface
)
1406 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1407 TRACE("(%p)\n",This
);
1408 This
->index
= list_head(This
->head
);
1412 static HRESULT WINAPI
EnumTfDocumentMgr_Clone( IEnumTfDocumentMgrs
*iface
,
1413 IEnumTfDocumentMgrs
**ppenum
)
1415 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1418 TRACE("(%p)\n",This
);
1420 if (ppenum
== NULL
) return E_POINTER
;
1422 res
= EnumTfDocumentMgr_Constructor(This
->head
, ppenum
);
1425 EnumTfDocumentMgr
*new_This
= impl_from_IEnumTfDocumentMgrs(*ppenum
);
1426 new_This
->index
= This
->index
;
1431 static const IEnumTfDocumentMgrsVtbl EnumTfDocumentMgrsVtbl
=
1433 EnumTfDocumentMgr_QueryInterface
,
1434 EnumTfDocumentMgr_AddRef
,
1435 EnumTfDocumentMgr_Release
,
1436 EnumTfDocumentMgr_Clone
,
1437 EnumTfDocumentMgr_Next
,
1438 EnumTfDocumentMgr_Reset
,
1439 EnumTfDocumentMgr_Skip
1442 static HRESULT
EnumTfDocumentMgr_Constructor(struct list
* head
, IEnumTfDocumentMgrs
**ppOut
)
1444 EnumTfDocumentMgr
*This
;
1446 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(EnumTfDocumentMgr
));
1448 return E_OUTOFMEMORY
;
1450 This
->IEnumTfDocumentMgrs_iface
.lpVtbl
= &EnumTfDocumentMgrsVtbl
;
1453 This
->index
= list_head(This
->head
);
1455 TRACE("returning %p\n", This
);
1456 *ppOut
= (IEnumTfDocumentMgrs
*)This
;
1460 void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr
*iface
, ITfDocumentMgr
*mgr
)
1462 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
1463 struct list
*cursor
;
1464 LIST_FOR_EACH(cursor
, &This
->CreatedDocumentMgrs
)
1466 DocumentMgrEntry
*mgrentry
= LIST_ENTRY(cursor
,DocumentMgrEntry
,entry
);
1467 if (mgrentry
->docmgr
== mgr
)
1469 list_remove(cursor
);
1470 HeapFree(GetProcessHeap(),0,mgrentry
);
1474 FIXME("ITfDocumentMgr %p not found in this thread\n",mgr
);