msctf: Implement ITfInputProcessorProfiles::EnumLanguageProfiles.
This commit is contained in:
parent
4d38c952d1
commit
7d1952b689
|
@ -60,7 +60,22 @@ typedef struct tagProfilesEnumGuid {
|
|||
DWORD next_index;
|
||||
} ProfilesEnumGuid;
|
||||
|
||||
typedef struct tagEnumTfLanguageProfiles {
|
||||
const IEnumTfLanguageProfilesVtbl *Vtbl;
|
||||
LONG refCount;
|
||||
|
||||
HKEY tipkey;
|
||||
DWORD tip_index;
|
||||
WCHAR szwCurrentClsid[39];
|
||||
|
||||
HKEY langkey;
|
||||
DWORD lang_index;
|
||||
|
||||
LANGID langid;
|
||||
} EnumTfLanguageProfiles;
|
||||
|
||||
static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut);
|
||||
static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut);
|
||||
|
||||
static void InputProcessorProfiles_Destructor(InputProcessorProfiles *This)
|
||||
{
|
||||
|
@ -330,8 +345,8 @@ static HRESULT WINAPI InputProcessorProfiles_EnumLanguageProfiles(
|
|||
IEnumTfLanguageProfiles **ppEnum)
|
||||
{
|
||||
InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p) %x %p\n",This,langid,ppEnum);
|
||||
return EnumTfLanguageProfiles_Constructor(langid, ppEnum);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfile(
|
||||
|
@ -645,3 +660,226 @@ static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut)
|
|||
*ppOut = (IEnumGUID*)This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* IEnumTfLanguageProfiles implementaion
|
||||
**************************************************/
|
||||
static void EnumTfLanguageProfiles_Destructor(EnumTfLanguageProfiles *This)
|
||||
{
|
||||
TRACE("destroying %p\n", This);
|
||||
RegCloseKey(This->tipkey);
|
||||
if (This->langkey)
|
||||
RegCloseKey(This->langkey);
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI EnumTfLanguageProfiles_QueryInterface(IEnumTfLanguageProfiles *iface, REFIID iid, LPVOID *ppvOut)
|
||||
{
|
||||
EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
|
||||
*ppvOut = NULL;
|
||||
|
||||
if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumTfLanguageProfiles))
|
||||
{
|
||||
*ppvOut = This;
|
||||
}
|
||||
|
||||
if (*ppvOut)
|
||||
{
|
||||
IUnknown_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("unsupported interface: %s\n", debugstr_guid(iid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI EnumTfLanguageProfiles_AddRef(IEnumTfLanguageProfiles *iface)
|
||||
{
|
||||
EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles*)iface;
|
||||
return InterlockedIncrement(&This->refCount);
|
||||
}
|
||||
|
||||
static ULONG WINAPI EnumTfLanguageProfiles_Release(IEnumTfLanguageProfiles *iface)
|
||||
{
|
||||
EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
|
||||
ULONG ret;
|
||||
|
||||
ret = InterlockedDecrement(&This->refCount);
|
||||
if (ret == 0)
|
||||
EnumTfLanguageProfiles_Destructor(This);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* IEnumGuid functions
|
||||
*****************************************************/
|
||||
static INT next_LanguageProfile(EnumTfLanguageProfiles *This, CLSID clsid, TF_LANGUAGEPROFILE *tflp)
|
||||
{
|
||||
WCHAR fullkey[168];
|
||||
ULONG res;
|
||||
WCHAR profileid[39];
|
||||
DWORD cName = 39;
|
||||
GUID profile;
|
||||
|
||||
static const WCHAR fmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
|
||||
|
||||
if (This->langkey == NULL)
|
||||
{
|
||||
sprintfW(fullkey,fmt,This->szwCurrentClsid,szwLngp,This->langid);
|
||||
res = RegOpenKeyExW(This->tipkey, fullkey, 0, KEY_READ | KEY_WRITE, &This->langkey);
|
||||
if (res)
|
||||
{
|
||||
This->langkey = NULL;
|
||||
return -1;
|
||||
}
|
||||
This->lang_index = 0;
|
||||
}
|
||||
res = RegEnumKeyExW(This->langkey, This->lang_index, profileid, &cName,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
|
||||
{
|
||||
RegCloseKey(This->langkey);
|
||||
This->langkey = NULL;
|
||||
return -1;
|
||||
}
|
||||
++(This->lang_index);
|
||||
|
||||
if (tflp)
|
||||
{
|
||||
res = CLSIDFromString(profileid, &profile);
|
||||
if (FAILED(res)) return 0;
|
||||
|
||||
tflp->clsid = clsid;
|
||||
tflp->langid = This->langid;
|
||||
/* FIXME */
|
||||
tflp->fActive = FALSE;
|
||||
tflp->guidProfile = profile;
|
||||
/* FIXME set catid */
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI EnumTfLanguageProfiles_Next(IEnumTfLanguageProfiles *iface,
|
||||
ULONG ulCount, TF_LANGUAGEPROFILE *pProfile, ULONG *pcFetch)
|
||||
{
|
||||
EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
|
||||
ULONG fetched = 0;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
if (pProfile == NULL) return E_POINTER;
|
||||
|
||||
if (This->tipkey) while (fetched < ulCount)
|
||||
{
|
||||
LSTATUS res;
|
||||
HRESULT hr;
|
||||
DWORD cName = 39;
|
||||
GUID clsid;
|
||||
|
||||
res = RegEnumKeyExW(This->tipkey, This->tip_index,
|
||||
This->szwCurrentClsid, &cName, NULL, NULL, NULL, NULL);
|
||||
if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
|
||||
++(This->tip_index);
|
||||
hr = CLSIDFromString(This->szwCurrentClsid, &clsid);
|
||||
if (FAILED(hr)) continue;
|
||||
|
||||
while ( fetched < ulCount)
|
||||
{
|
||||
INT res = next_LanguageProfile(This, clsid, pProfile);
|
||||
if (res == 1)
|
||||
{
|
||||
++fetched;
|
||||
++pProfile;
|
||||
}
|
||||
else if (res == -1)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (pcFetch) *pcFetch = fetched;
|
||||
return fetched == ulCount ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI EnumTfLanguageProfiles_Skip( IEnumTfLanguageProfiles* iface, ULONG celt)
|
||||
{
|
||||
EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
|
||||
FIXME("STUB (%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI EnumTfLanguageProfiles_Reset( IEnumTfLanguageProfiles* iface)
|
||||
{
|
||||
EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
|
||||
TRACE("(%p)\n",This);
|
||||
This->tip_index = 0;
|
||||
if (This->langkey)
|
||||
RegCloseKey(This->langkey);
|
||||
This->langkey = NULL;
|
||||
This->lang_index = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI EnumTfLanguageProfiles_Clone( IEnumTfLanguageProfiles *iface,
|
||||
IEnumTfLanguageProfiles **ppenum)
|
||||
{
|
||||
EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
|
||||
HRESULT res;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
if (ppenum == NULL) return E_POINTER;
|
||||
|
||||
res = EnumTfLanguageProfiles_Constructor(This->langid, ppenum);
|
||||
if (SUCCEEDED(res))
|
||||
{
|
||||
EnumTfLanguageProfiles *new_This = (EnumTfLanguageProfiles *)*ppenum;
|
||||
new_This->tip_index = This->tip_index;
|
||||
lstrcpynW(new_This->szwCurrentClsid,This->szwCurrentClsid,39);
|
||||
|
||||
if (This->langkey)
|
||||
{
|
||||
WCHAR fullkey[168];
|
||||
static const WCHAR fmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
|
||||
|
||||
sprintfW(fullkey,fmt,This->szwCurrentClsid,szwLngp,This->langid);
|
||||
res = RegOpenKeyExW(new_This->tipkey, fullkey, 0, KEY_READ | KEY_WRITE, &This->langkey);
|
||||
new_This->lang_index = This->lang_index;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static const IEnumTfLanguageProfilesVtbl IEnumTfLanguageProfiles_Vtbl ={
|
||||
EnumTfLanguageProfiles_QueryInterface,
|
||||
EnumTfLanguageProfiles_AddRef,
|
||||
EnumTfLanguageProfiles_Release,
|
||||
|
||||
EnumTfLanguageProfiles_Clone,
|
||||
EnumTfLanguageProfiles_Next,
|
||||
EnumTfLanguageProfiles_Reset,
|
||||
EnumTfLanguageProfiles_Skip
|
||||
};
|
||||
|
||||
static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut)
|
||||
{
|
||||
EnumTfLanguageProfiles *This;
|
||||
|
||||
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EnumTfLanguageProfiles));
|
||||
if (This == NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
This->Vtbl= &IEnumTfLanguageProfiles_Vtbl;
|
||||
This->refCount = 1;
|
||||
This->langid = langid;
|
||||
|
||||
if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szwSystemTIPKey, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL, &This->tipkey, NULL) != ERROR_SUCCESS)
|
||||
return E_FAIL;
|
||||
|
||||
TRACE("returning %p\n", This);
|
||||
*ppOut = (IEnumTfLanguageProfiles*)This;
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -102,6 +102,27 @@ static void test_EnumInputProcessorInfo(void)
|
|||
ok(found,"Did not find registered text service\n");
|
||||
}
|
||||
|
||||
static void test_EnumLanguageProfiles(void)
|
||||
{
|
||||
BOOL found = FALSE;
|
||||
IEnumTfLanguageProfiles *ppEnum;
|
||||
if (SUCCEEDED(ITfInputProcessorProfiles_EnumLanguageProfiles(g_ipp,gLangid,&ppEnum)))
|
||||
{
|
||||
TF_LANGUAGEPROFILE profile;
|
||||
while (IEnumTfLanguageProfiles_Next(ppEnum,1,&profile,NULL)==S_OK)
|
||||
{
|
||||
if (IsEqualGUID(&profile.clsid,&CLSID_FakeService))
|
||||
{
|
||||
found = TRUE;
|
||||
ok(profile.langid == gLangid, "LangId Incorrect\n");
|
||||
todo_wine ok(IsEqualGUID(&profile.catid,&GUID_TFCAT_TIP_KEYBOARD), "CatId Incorrect\n");
|
||||
ok(IsEqualGUID(&profile.guidProfile,&CLSID_FakeService), "guidProfile Incorrect\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
ok(found,"Registered text service not found\n");
|
||||
}
|
||||
|
||||
static void test_RegisterCategory(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
@ -124,6 +145,7 @@ START_TEST(inputprocessor)
|
|||
test_Register();
|
||||
test_RegisterCategory();
|
||||
test_EnumInputProcessorInfo();
|
||||
test_EnumLanguageProfiles();
|
||||
test_UnregisterCategory();
|
||||
test_Unregister();
|
||||
}
|
||||
|
|
|
@ -450,3 +450,24 @@ interface ITfContextOwnerCompositionSink : IUnknown
|
|||
HRESULT OnEndComposition(
|
||||
[in] ITfCompositionView *pComposition);
|
||||
};
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(3d61bf11-ac5f-42c8-a4cb-931bcc28c744),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface IEnumTfLanguageProfiles : IUnknown
|
||||
{
|
||||
HRESULT Clone(
|
||||
[out] IEnumTfLanguageProfiles **ppEnum);
|
||||
|
||||
HRESULT Next(
|
||||
[in] ULONG ulCount,
|
||||
[out, size_is(ulCount), length_is(*pcFetch)] TF_LANGUAGEPROFILE *pProfile,
|
||||
[out] ULONG *pcFetch);
|
||||
|
||||
HRESULT Reset();
|
||||
|
||||
HRESULT Skip(
|
||||
[in] ULONG ulCount);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue