Aric Stewart : msctf: Implement ITfThreadMgr::EnumDocumentMgrs.

Alexandre Julliard julliard at winehq.org
Fri Jul 10 08:52:07 CDT 2009


Module: wine
Branch: master
Commit: 844fd9220081703a0d6983332e87b16bcb0dbf9c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=844fd9220081703a0d6983332e87b16bcb0dbf9c

Author: Aric Stewart <aric at codeweavers.com>
Date:   Fri Jul 10 07:38:20 2009 -0500

msctf: Implement ITfThreadMgr::EnumDocumentMgrs.

---

 dlls/msctf/threadmgr.c |  162 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 160 insertions(+), 2 deletions(-)

diff --git a/dlls/msctf/threadmgr.c b/dlls/msctf/threadmgr.c
index da2c74a..9fb1b5d 100644
--- a/dlls/msctf/threadmgr.c
+++ b/dlls/msctf/threadmgr.c
@@ -107,6 +107,16 @@ typedef struct tagACLMulti {
     struct list     ThreadMgrEventSink;
 } ThreadMgr;
 
+typedef struct tagEnumTfDocumentMgr {
+    const IEnumTfDocumentMgrsVtbl *Vtbl;
+    LONG refCount;
+
+    struct list *index;
+    struct list *head;
+} EnumTfDocumentMgr;
+
+static HRESULT EnumTfDocumentMgr_Constructor(struct list* head, IEnumTfDocumentMgrs **ppOut);
+
 static inline ThreadMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
 {
     return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,SourceVtbl));
@@ -343,8 +353,12 @@ static HRESULT WINAPI ThreadMgr_EnumDocumentMgrs( ITfThreadMgr* iface, IEnumTfDo
 **ppEnum)
 {
     ThreadMgr *This = (ThreadMgr *)iface;
-    FIXME("STUB:(%p)\n",This);
-    return E_NOTIMPL;
+    TRACE("(%p) %p\n",This,ppEnum);
+
+    if (!ppEnum)
+        return E_INVALIDARG;
+
+    return EnumTfDocumentMgr_Constructor(&This->CreatedDocumentMgrs, ppEnum);
 }
 
 static HRESULT WINAPI ThreadMgr_GetFocus( ITfThreadMgr* iface, ITfDocumentMgr
@@ -1129,6 +1143,150 @@ HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
     return S_OK;
 }
 
+/**************************************************
+ * IEnumTfDocumentMgrs implementaion
+ **************************************************/
+static void EnumTfDocumentMgr_Destructor(EnumTfDocumentMgr *This)
+{
+    TRACE("destroying %p\n", This);
+    HeapFree(GetProcessHeap(),0,This);
+}
+
+static HRESULT WINAPI EnumTfDocumentMgr_QueryInterface(IEnumTfDocumentMgrs *iface, REFIID iid, LPVOID *ppvOut)
+{
+    EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
+    *ppvOut = NULL;
+
+    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumTfDocumentMgrs))
+    {
+        *ppvOut = This;
+    }
+
+    if (*ppvOut)
+    {
+        IUnknown_AddRef(iface);
+        return S_OK;
+    }
+
+    WARN("unsupported interface: %s\n", debugstr_guid(iid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI EnumTfDocumentMgr_AddRef(IEnumTfDocumentMgrs *iface)
+{
+    EnumTfDocumentMgr *This = (EnumTfDocumentMgr*)iface;
+    return InterlockedIncrement(&This->refCount);
+}
+
+static ULONG WINAPI EnumTfDocumentMgr_Release(IEnumTfDocumentMgrs *iface)
+{
+    EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
+    ULONG ret;
+
+    ret = InterlockedDecrement(&This->refCount);
+    if (ret == 0)
+        EnumTfDocumentMgr_Destructor(This);
+    return ret;
+}
+
+static HRESULT WINAPI EnumTfDocumentMgr_Next(IEnumTfDocumentMgrs *iface,
+    ULONG ulCount, ITfDocumentMgr **rgDocumentMgr, ULONG *pcFetched)
+{
+    EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
+    ULONG fetched = 0;
+
+    TRACE("(%p)\n",This);
+
+    if (rgDocumentMgr == NULL) return E_POINTER;
+
+    while (fetched < ulCount)
+    {
+        DocumentMgrEntry *mgrentry;
+        if (This->index == NULL)
+            break;
+
+        mgrentry = LIST_ENTRY(This->index,DocumentMgrEntry,entry);
+        if (mgrentry == NULL)
+            break;
+
+        *rgDocumentMgr = mgrentry->docmgr;
+        ITfDocumentMgr_AddRef(*rgDocumentMgr);
+
+        This->index = list_next(This->head, This->index);
+        ++fetched;
+        ++rgDocumentMgr;
+    }
+
+    if (pcFetched) *pcFetched = fetched;
+    return fetched == ulCount ? S_OK : S_FALSE;
+}
+
+static HRESULT WINAPI EnumTfDocumentMgr_Skip( IEnumTfDocumentMgrs* iface, ULONG celt)
+{
+    INT i;
+    EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
+    TRACE("(%p)\n",This);
+    for(i = 0; i < celt && This->index != NULL; i++)
+        This->index = list_next(This->head, This->index);
+    return S_OK;
+}
+
+static HRESULT WINAPI EnumTfDocumentMgr_Reset( IEnumTfDocumentMgrs* iface)
+{
+    EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
+    TRACE("(%p)\n",This);
+    This->index = list_head(This->head);
+    return S_OK;
+}
+
+static HRESULT WINAPI EnumTfDocumentMgr_Clone( IEnumTfDocumentMgrs *iface,
+    IEnumTfDocumentMgrs **ppenum)
+{
+    EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
+    HRESULT res;
+
+    TRACE("(%p)\n",This);
+
+    if (ppenum == NULL) return E_POINTER;
+
+    res = EnumTfDocumentMgr_Constructor(This->head, ppenum);
+    if (SUCCEEDED(res))
+    {
+        EnumTfDocumentMgr *new_This = (EnumTfDocumentMgr *)*ppenum;
+        new_This->index = This->index;
+    }
+    return res;
+}
+
+static const IEnumTfDocumentMgrsVtbl IEnumTfDocumentMgrs_Vtbl ={
+    EnumTfDocumentMgr_QueryInterface,
+    EnumTfDocumentMgr_AddRef,
+    EnumTfDocumentMgr_Release,
+
+    EnumTfDocumentMgr_Clone,
+    EnumTfDocumentMgr_Next,
+    EnumTfDocumentMgr_Reset,
+    EnumTfDocumentMgr_Skip
+};
+
+static HRESULT EnumTfDocumentMgr_Constructor(struct list* head, IEnumTfDocumentMgrs **ppOut)
+{
+    EnumTfDocumentMgr *This;
+
+    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EnumTfDocumentMgr));
+    if (This == NULL)
+        return E_OUTOFMEMORY;
+
+    This->Vtbl= &IEnumTfDocumentMgrs_Vtbl;
+    This->refCount = 1;
+    This->head = head;
+    This->index = list_head(This->head);
+
+    TRACE("returning %p\n", This);
+    *ppOut = (IEnumTfDocumentMgrs*)This;
+    return S_OK;
+}
+
 void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr *tm, ITfDocumentMgr *mgr)
 {
     ThreadMgr *This = (ThreadMgr *)tm;




More information about the wine-cvs mailing list