diff --git a/dlls/msctf/categorymgr.c b/dlls/msctf/categorymgr.c index 23580724286..648352af85a 100644 --- a/dlls/msctf/categorymgr.c +++ b/dlls/msctf/categorymgr.c @@ -168,9 +168,67 @@ static HRESULT WINAPI CategoryMgr_EnumItemsInCategory ( ITfCategoryMgr *iface, static HRESULT WINAPI CategoryMgr_FindClosestCategory ( ITfCategoryMgr *iface, REFGUID rguid, GUID *pcatid, const GUID **ppcatidList, ULONG ulCount) { + static const WCHAR fmt[] = { '%','s','\\','%','s','\\','C','a','t','e','g','o','r','y','\\','I','t','e','m','\\','%','s',0}; + + WCHAR fullkey[110]; + WCHAR buf[39]; + HKEY key; + HRESULT hr = S_FALSE; + INT index = 0; CategoryMgr *This = (CategoryMgr*)iface; - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; + + TRACE("(%p)\n",This); + + if (!pcatid || (ulCount && ppcatidList == NULL)) + return E_INVALIDARG; + + StringFromGUID2(rguid, buf, 39); + sprintfW(fullkey,fmt,szwSystemTIPKey,buf,buf); + *pcatid = GUID_NULL; + + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, KEY_READ, &key ) != + ERROR_SUCCESS) + return S_FALSE; + + while (1) + { + HRESULT hr2; + ULONG res; + GUID guid; + WCHAR catid[39]; + DWORD cName; + + cName = 39; + res = RegEnumKeyExW(key, index, catid, &cName, NULL, NULL, NULL, NULL); + if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break; + index ++; + + hr2 = CLSIDFromString(catid, &guid); + if (FAILED(hr2)) continue; + + if (ulCount) + { + int j; + BOOL found = FALSE; + for (j = 0; j < ulCount; j++) + if (IsEqualGUID(&guid, ppcatidList[j])) + { + found = TRUE; + *pcatid = guid; + hr = S_OK; + break; + } + if (found) break; + } + else + { + *pcatid = guid; + hr = S_OK; + break; + } + } + + return hr; } static HRESULT WINAPI CategoryMgr_RegisterGUIDDescription ( diff --git a/dlls/msctf/tests/inputprocessor.c b/dlls/msctf/tests/inputprocessor.c index b7e2695b38d..2d324138f5a 100644 --- a/dlls/msctf/tests/inputprocessor.c +++ b/dlls/msctf/tests/inputprocessor.c @@ -128,6 +128,8 @@ static void test_RegisterCategory(void) HRESULT hr; hr = ITfCategoryMgr_RegisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_TIP_KEYBOARD, &CLSID_FakeService); ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterCategory failed\n"); + hr = ITfCategoryMgr_RegisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_FakeService); + ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterCategory failed\n"); } static void test_UnregisterCategory(void) @@ -135,6 +137,27 @@ static void test_UnregisterCategory(void) HRESULT hr; hr = ITfCategoryMgr_UnregisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_TIP_KEYBOARD, &CLSID_FakeService); todo_wine ok(SUCCEEDED(hr),"ITfCategoryMgr_UnregisterCategory failed\n"); + hr = ITfCategoryMgr_UnregisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_FakeService); + todo_wine ok(SUCCEEDED(hr),"ITfCategoryMgr_UnregisterCategory failed\n"); +} + +static void test_FindClosestCategory(void) +{ + GUID output; + HRESULT hr; + const GUID *list[3] = {&GUID_TFCAT_TIP_SPEECH, &GUID_TFCAT_TIP_KEYBOARD, &GUID_TFCAT_TIP_HANDWRITING}; + + hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, NULL, 0); + ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr); + ok(IsEqualGUID(&output,&GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER),"Wrong GUID\n"); + + hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, list, 1); + ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr); + ok(IsEqualGUID(&output,&GUID_NULL),"Wrong GUID\n"); + + hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, list, 3); + ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr); + ok(IsEqualGUID(&output,&GUID_TFCAT_TIP_KEYBOARD),"Wrong GUID\n"); } START_TEST(inputprocessor) @@ -146,6 +169,7 @@ START_TEST(inputprocessor) test_RegisterCategory(); test_EnumInputProcessorInfo(); test_EnumLanguageProfiles(); + test_FindClosestCategory(); test_UnregisterCategory(); test_Unregister(); }