Aric Stewart : msctf: Implement ITfInputProcessorProfiles:: EnumInputProcessorInfo.

Alexandre Julliard julliard at winehq.org
Mon Feb 23 10:00:37 CST 2009


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

Author: Aric Stewart <aric at codeweavers.com>
Date:   Fri Feb 20 13:52:55 2009 -0600

msctf: Implement ITfInputProcessorProfiles::EnumInputProcessorInfo.

---

 dlls/msctf/inputprocessor.c       |  164 ++++++++++++++++++++++++++++++++++++-
 dlls/msctf/tests/inputprocessor.c |   19 ++++
 2 files changed, 181 insertions(+), 2 deletions(-)

diff --git a/dlls/msctf/inputprocessor.c b/dlls/msctf/inputprocessor.c
index 3950a94..b098169 100644
--- a/dlls/msctf/inputprocessor.c
+++ b/dlls/msctf/inputprocessor.c
@@ -52,6 +52,16 @@ typedef struct tagInputProcessorProfiles {
     LANGID  currentLanguage;
 } InputProcessorProfiles;
 
+typedef struct tagProfilesEnumGuid {
+    const IEnumGUIDVtbl *Vtbl;
+    LONG refCount;
+
+    HKEY key;
+    DWORD next_index;
+} ProfilesEnumGuid;
+
+static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut);
+
 static void InputProcessorProfiles_Destructor(InputProcessorProfiles *This)
 {
     TRACE("destroying %p\n", This);
@@ -236,8 +246,8 @@ static HRESULT WINAPI InputProcessorProfiles_EnumInputProcessorInfo(
         ITfInputProcessorProfiles *iface, IEnumGUID **ppEnum)
 {
     InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
-    FIXME("STUB:(%p)\n",This);
-    return E_NOTIMPL;
+    TRACE("(%p) %p\n",This,ppEnum);
+    return ProfilesEnumGuid_Constructor(ppEnum);
 }
 
 static HRESULT WINAPI InputProcessorProfiles_GetDefaultLanguageProfile(
@@ -485,3 +495,153 @@ HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut
     *ppOut = (IUnknown *)This;
     return S_OK;
 }
+
+/**************************************************
+ * IEnumGUID implementaion for ITfInputProcessorProfiles::EnumInputProcessorInfo
+ **************************************************/
+static void ProfilesEnumGuid_Destructor(ProfilesEnumGuid *This)
+{
+    TRACE("destroying %p\n", This);
+    RegCloseKey(This->key);
+    HeapFree(GetProcessHeap(),0,This);
+}
+
+static HRESULT WINAPI ProfilesEnumGuid_QueryInterface(IEnumGUID *iface, REFIID iid, LPVOID *ppvOut)
+{
+    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
+    *ppvOut = NULL;
+
+    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumGUID))
+    {
+        *ppvOut = This;
+    }
+
+    if (*ppvOut)
+    {
+        IUnknown_AddRef(iface);
+        return S_OK;
+    }
+
+    WARN("unsupported interface: %s\n", debugstr_guid(iid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ProfilesEnumGuid_AddRef(IEnumGUID *iface)
+{
+    ProfilesEnumGuid *This = (ProfilesEnumGuid*)iface;
+    return InterlockedIncrement(&This->refCount);
+}
+
+static ULONG WINAPI ProfilesEnumGuid_Release(IEnumGUID *iface)
+{
+    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
+    ULONG ret;
+
+    ret = InterlockedDecrement(&This->refCount);
+    if (ret == 0)
+        ProfilesEnumGuid_Destructor(This);
+    return ret;
+}
+
+/*****************************************************
+ * IEnumGuid functions
+ *****************************************************/
+static HRESULT WINAPI ProfilesEnumGuid_Next( LPENUMGUID iface,
+    ULONG celt, GUID *rgelt, ULONG *pceltFetched)
+{
+    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
+    ULONG fetched = 0;
+
+    TRACE("(%p)\n",This);
+
+    if (rgelt == NULL) return E_POINTER;
+
+    if (This->key) while (fetched < celt)
+    {
+        LSTATUS res;
+        HRESULT hr;
+        WCHAR catid[39];
+        DWORD cName = 39;
+
+        res = RegEnumKeyExW(This->key, This->next_index, catid, &cName,
+                    NULL, NULL, NULL, NULL);
+        if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
+        ++(This->next_index);
+
+        hr = CLSIDFromString(catid, rgelt);
+        if (FAILED(hr)) continue;
+
+        ++fetched;
+        ++rgelt;
+    }
+
+    if (pceltFetched) *pceltFetched = fetched;
+    return fetched == celt ? S_OK : S_FALSE;
+}
+
+static HRESULT WINAPI ProfilesEnumGuid_Skip( LPENUMGUID iface, ULONG celt)
+{
+    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
+    TRACE("(%p)\n",This);
+
+    This->next_index += celt;
+    return S_OK;
+}
+
+static HRESULT WINAPI ProfilesEnumGuid_Reset( LPENUMGUID iface)
+{
+    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
+    TRACE("(%p)\n",This);
+    This->next_index = 0;
+    return S_OK;
+}
+
+static HRESULT WINAPI ProfilesEnumGuid_Clone( LPENUMGUID iface,
+    IEnumGUID **ppenum)
+{
+    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
+    HRESULT res;
+
+    TRACE("(%p)\n",This);
+
+    if (ppenum == NULL) return E_POINTER;
+
+    res = ProfilesEnumGuid_Constructor(ppenum);
+    if (SUCCEEDED(res))
+    {
+        ProfilesEnumGuid *new_This = (ProfilesEnumGuid *)*ppenum;
+        new_This->next_index = This->next_index;
+    }
+    return res;
+}
+
+static const IEnumGUIDVtbl IEnumGUID_Vtbl ={
+    ProfilesEnumGuid_QueryInterface,
+    ProfilesEnumGuid_AddRef,
+    ProfilesEnumGuid_Release,
+
+    ProfilesEnumGuid_Next,
+    ProfilesEnumGuid_Skip,
+    ProfilesEnumGuid_Reset,
+    ProfilesEnumGuid_Clone
+};
+
+static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut)
+{
+    ProfilesEnumGuid *This;
+
+    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ProfilesEnumGuid));
+    if (This == NULL)
+        return E_OUTOFMEMORY;
+
+    This->Vtbl= &IEnumGUID_Vtbl;
+    This->refCount = 1;
+
+    if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szwSystemTIPKey, 0, NULL, 0,
+                    KEY_READ | KEY_WRITE, NULL, &This->key, NULL) != ERROR_SUCCESS)
+        return E_FAIL;
+
+    TRACE("returning %p\n", This);
+    *ppOut = (IEnumGUID*)This;
+    return S_OK;
+}
diff --git a/dlls/msctf/tests/inputprocessor.c b/dlls/msctf/tests/inputprocessor.c
index 34e47e5..0520e49 100644
--- a/dlls/msctf/tests/inputprocessor.c
+++ b/dlls/msctf/tests/inputprocessor.c
@@ -84,6 +84,24 @@ static void test_Unregister(void)
     ok(SUCCEEDED(hr),"Unable to unregister text service(%x)\n",hr);
 }
 
+static void test_EnumInputProcessorInfo(void)
+{
+    IEnumGUID *ppEnum;
+    BOOL found = FALSE;
+
+    if (SUCCEEDED(ITfInputProcessorProfiles_EnumInputProcessorInfo(g_ipp, &ppEnum)))
+    {
+        ULONG fetched;
+        GUID g;
+        while (IEnumGUID_Next(ppEnum, 1, &g, &fetched) == S_OK)
+        {
+            if(IsEqualGUID(&g,&CLSID_FakeService))
+                found = TRUE;
+        }
+    }
+    ok(found,"Did not find registered text service\n");
+}
+
 static void test_RegisterCategory(void)
 {
     HRESULT hr;
@@ -105,6 +123,7 @@ START_TEST(inputprocessor)
         gLangid = GetUserDefaultLCID();
         test_Register();
         test_RegisterCategory();
+        test_EnumInputProcessorInfo();
         test_UnregisterCategory();
         test_Unregister();
     }




More information about the wine-cvs mailing list