2 * ITfInputProcessorProfiles implementation
4 * Copyright 2009 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"
36 #include "wine/unicode.h"
39 #include "msctf_internal.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(msctf);
43 static const WCHAR szwLngp[] = {'L','a','n','g','u','a','g','e','P','r','o','f','i','l','e',0};
44 static const WCHAR szwEnabled[] = {'E','n','a','b','l','e','d',0};
45 static const WCHAR szwTipfmt[] = {'%','s','\\','%','s',0};
46 static const WCHAR szwFullLangfmt[] = {'%','s','\\','%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
48 typedef struct tagInputProcessorProfiles {
49 const ITfInputProcessorProfilesVtbl *InputProcessorProfilesVtbl;
52 LANGID currentLanguage;
53 } InputProcessorProfiles;
55 typedef struct tagProfilesEnumGuid {
56 const IEnumGUIDVtbl *Vtbl;
63 typedef struct tagEnumTfLanguageProfiles {
64 const IEnumTfLanguageProfilesVtbl *Vtbl;
69 WCHAR szwCurrentClsid[39];
75 } EnumTfLanguageProfiles;
77 static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut);
78 static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut);
80 static void InputProcessorProfiles_Destructor(InputProcessorProfiles *This)
82 TRACE("destroying %p\n", This);
83 HeapFree(GetProcessHeap(),0,This);
86 static void add_userkey( REFCLSID rclsid, LANGID langid,
93 DWORD disposition = 0;
98 StringFromGUID2(rclsid, buf, 39);
99 StringFromGUID2(guidProfile, buf2, 39);
100 sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
102 res = RegCreateKeyExW(HKEY_CURRENT_USER,fullkey, 0, NULL, 0,
103 KEY_READ | KEY_WRITE, NULL, &key, &disposition);
105 if (!res && disposition == REG_CREATED_NEW_KEY)
108 RegSetValueExW(key, szwEnabled, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD));
115 static HRESULT WINAPI InputProcessorProfiles_QueryInterface(ITfInputProcessorProfiles *iface, REFIID iid, LPVOID *ppvOut)
117 InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
120 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfInputProcessorProfiles))
127 IUnknown_AddRef(iface);
131 WARN("unsupported interface: %s\n", debugstr_guid(iid));
132 return E_NOINTERFACE;
135 static ULONG WINAPI InputProcessorProfiles_AddRef(ITfInputProcessorProfiles *iface)
137 InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
138 return InterlockedIncrement(&This->refCount);
141 static ULONG WINAPI InputProcessorProfiles_Release(ITfInputProcessorProfiles *iface)
143 InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
146 ret = InterlockedDecrement(&This->refCount);
148 InputProcessorProfiles_Destructor(This);
152 /*****************************************************
153 * ITfInputProcessorProfiles functions
154 *****************************************************/
155 static HRESULT WINAPI InputProcessorProfiles_Register(
156 ITfInputProcessorProfiles *iface, REFCLSID rclsid)
158 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
163 TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
165 StringFromGUID2(rclsid, buf, 39);
166 sprintfW(fullkey,szwTipfmt,szwSystemTIPKey,buf);
168 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, NULL, 0,
169 KEY_READ | KEY_WRITE, NULL, &tipkey, NULL) != ERROR_SUCCESS)
177 static HRESULT WINAPI InputProcessorProfiles_Unregister(
178 ITfInputProcessorProfiles *iface, REFCLSID rclsid)
182 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
184 TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
186 StringFromGUID2(rclsid, buf, 39);
187 sprintfW(fullkey,szwTipfmt,szwSystemTIPKey,buf);
189 RegDeleteTreeW(HKEY_LOCAL_MACHINE, fullkey);
190 RegDeleteTreeW(HKEY_CURRENT_USER, fullkey);
195 static HRESULT WINAPI InputProcessorProfiles_AddLanguageProfile(
196 ITfInputProcessorProfiles *iface, REFCLSID rclsid,
197 LANGID langid, REFGUID guidProfile, const WCHAR *pchDesc,
198 ULONG cchDesc, const WCHAR *pchIconFile, ULONG cchFile,
205 DWORD disposition = 0;
207 static const WCHAR fmt2[] = {'%','s','\\','0','x','%','0','8','x','\\','%','s',0};
208 static const WCHAR desc[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
209 static const WCHAR icnf[] = {'I','c','o','n','F','i','l','e',0};
210 static const WCHAR icni[] = {'I','c','o','n','I','n','d','e','x',0};
212 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
214 TRACE("(%p) %s %x %s %s %s %i\n",This,debugstr_guid(rclsid), langid,
215 debugstr_guid(guidProfile), debugstr_wn(pchDesc,cchDesc),
216 debugstr_wn(pchIconFile,cchFile),uIconIndex);
218 StringFromGUID2(rclsid, buf, 39);
219 sprintfW(fullkey,szwTipfmt,szwSystemTIPKey,buf);
221 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, KEY_READ | KEY_WRITE,
222 &tipkey ) != ERROR_SUCCESS)
225 StringFromGUID2(guidProfile, buf, 39);
226 sprintfW(fullkey,fmt2,szwLngp,langid,buf);
228 res = RegCreateKeyExW(tipkey,fullkey, 0, NULL, 0, KEY_READ | KEY_WRITE,
229 NULL, &fmtkey, &disposition);
234 RegSetValueExW(fmtkey, desc, 0, REG_SZ, (LPBYTE)pchDesc, cchDesc * sizeof(WCHAR));
235 RegSetValueExW(fmtkey, icnf, 0, REG_SZ, (LPBYTE)pchIconFile, cchFile * sizeof(WCHAR));
236 RegSetValueExW(fmtkey, icni, 0, REG_DWORD, (LPBYTE)&uIconIndex, sizeof(DWORD));
237 if (disposition == REG_CREATED_NEW_KEY)
238 RegSetValueExW(fmtkey, szwEnabled, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD));
241 add_userkey(rclsid, langid, guidProfile);
251 static HRESULT WINAPI InputProcessorProfiles_RemoveLanguageProfile(
252 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
255 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
256 FIXME("STUB:(%p)\n",This);
260 static HRESULT WINAPI InputProcessorProfiles_EnumInputProcessorInfo(
261 ITfInputProcessorProfiles *iface, IEnumGUID **ppEnum)
263 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
264 TRACE("(%p) %p\n",This,ppEnum);
265 return ProfilesEnumGuid_Constructor(ppEnum);
268 static HRESULT WINAPI InputProcessorProfiles_GetDefaultLanguageProfile(
269 ITfInputProcessorProfiles *iface, LANGID langid, REFGUID catid,
270 CLSID *pclsid, GUID *pguidProfile)
272 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
273 FIXME("STUB:(%p)\n",This);
277 static HRESULT WINAPI InputProcessorProfiles_SetDefaultLanguageProfile(
278 ITfInputProcessorProfiles *iface, LANGID langid, REFCLSID rclsid,
279 REFGUID guidProfiles)
281 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
282 FIXME("STUB:(%p)\n",This);
286 static HRESULT WINAPI InputProcessorProfiles_ActivateLanguageProfile(
287 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
288 REFGUID guidProfiles)
290 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
291 FIXME("STUB:(%p)\n",This);
295 static HRESULT WINAPI InputProcessorProfiles_GetActiveLanguageProfile(
296 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID *plangid,
299 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
300 FIXME("STUB:(%p)\n",This);
304 static HRESULT WINAPI InputProcessorProfiles_GetLanguageProfileDescription(
305 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
306 REFGUID guidProfile, BSTR *pbstrProfile)
308 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
309 FIXME("STUB:(%p)\n",This);
313 static HRESULT WINAPI InputProcessorProfiles_GetCurrentLanguage(
314 ITfInputProcessorProfiles *iface, LANGID *plangid)
316 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
317 TRACE("(%p) 0x%x\n",This,This->currentLanguage);
322 *plangid = This->currentLanguage;
327 static HRESULT WINAPI InputProcessorProfiles_ChangeCurrentLanguage(
328 ITfInputProcessorProfiles *iface, LANGID langid)
330 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
331 FIXME("STUB:(%p)\n",This);
335 static HRESULT WINAPI InputProcessorProfiles_GetLanguageList(
336 ITfInputProcessorProfiles *iface, LANGID **ppLangId, ULONG *pulCount)
338 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
339 FIXME("STUB:(%p)\n",This);
343 static HRESULT WINAPI InputProcessorProfiles_EnumLanguageProfiles(
344 ITfInputProcessorProfiles *iface, LANGID langid,
345 IEnumTfLanguageProfiles **ppEnum)
347 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
348 TRACE("(%p) %x %p\n",This,langid,ppEnum);
349 return EnumTfLanguageProfiles_Constructor(langid, ppEnum);
352 static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfile(
353 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
354 REFGUID guidProfile, BOOL fEnable)
362 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
363 TRACE("(%p) %s %x %s %i\n",This, debugstr_guid(rclsid), langid, debugstr_guid(guidProfile), fEnable);
365 StringFromGUID2(rclsid, buf, 39);
366 StringFromGUID2(guidProfile, buf2, 39);
367 sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
369 res = RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE, &key);
373 RegSetValueExW(key, szwEnabled, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD));
382 static HRESULT WINAPI InputProcessorProfiles_IsEnabledLanguageProfile(
383 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
384 REFGUID guidProfile, BOOL *pfEnable)
392 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
393 TRACE("(%p) %s, %i, %s, %p\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfile),pfEnable);
398 StringFromGUID2(rclsid, buf, 39);
399 StringFromGUID2(guidProfile, buf2, 39);
400 sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
402 res = RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE, &key);
406 DWORD count = sizeof(DWORD);
407 res = RegQueryValueExW(key, szwEnabled, 0, NULL, (LPBYTE)pfEnable, &count);
411 if (res) /* Try Default */
413 res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | KEY_WRITE, &key);
417 DWORD count = sizeof(DWORD);
418 res = RegQueryValueExW(key, szwEnabled, 0, NULL, (LPBYTE)pfEnable, &count);
429 static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfileByDefault(
430 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
431 REFGUID guidProfile, BOOL fEnable)
439 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
440 TRACE("(%p) %s %x %s %i\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfile),fEnable);
442 StringFromGUID2(rclsid, buf, 39);
443 StringFromGUID2(guidProfile, buf2, 39);
444 sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
446 res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | KEY_WRITE, &key);
450 RegSetValueExW(key, szwEnabled, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD));
459 static HRESULT WINAPI InputProcessorProfiles_SubstituteKeyboardLayout(
460 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
461 REFGUID guidProfile, HKL hKL)
463 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
464 FIXME("STUB:(%p)\n",This);
469 static const ITfInputProcessorProfilesVtbl InputProcessorProfiles_InputProcessorProfilesVtbl =
471 InputProcessorProfiles_QueryInterface,
472 InputProcessorProfiles_AddRef,
473 InputProcessorProfiles_Release,
475 InputProcessorProfiles_Register,
476 InputProcessorProfiles_Unregister,
477 InputProcessorProfiles_AddLanguageProfile,
478 InputProcessorProfiles_RemoveLanguageProfile,
479 InputProcessorProfiles_EnumInputProcessorInfo,
480 InputProcessorProfiles_GetDefaultLanguageProfile,
481 InputProcessorProfiles_SetDefaultLanguageProfile,
482 InputProcessorProfiles_ActivateLanguageProfile,
483 InputProcessorProfiles_GetActiveLanguageProfile,
484 InputProcessorProfiles_GetLanguageProfileDescription,
485 InputProcessorProfiles_GetCurrentLanguage,
486 InputProcessorProfiles_ChangeCurrentLanguage,
487 InputProcessorProfiles_GetLanguageList,
488 InputProcessorProfiles_EnumLanguageProfiles,
489 InputProcessorProfiles_EnableLanguageProfile,
490 InputProcessorProfiles_IsEnabledLanguageProfile,
491 InputProcessorProfiles_EnableLanguageProfileByDefault,
492 InputProcessorProfiles_SubstituteKeyboardLayout
495 HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
497 InputProcessorProfiles *This;
499 return CLASS_E_NOAGGREGATION;
501 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputProcessorProfiles));
503 return E_OUTOFMEMORY;
505 This->InputProcessorProfilesVtbl= &InputProcessorProfiles_InputProcessorProfilesVtbl;
507 This->currentLanguage = GetUserDefaultLCID();
509 TRACE("returning %p\n", This);
510 *ppOut = (IUnknown *)This;
514 /**************************************************
515 * IEnumGUID implementaion for ITfInputProcessorProfiles::EnumInputProcessorInfo
516 **************************************************/
517 static void ProfilesEnumGuid_Destructor(ProfilesEnumGuid *This)
519 TRACE("destroying %p\n", This);
520 RegCloseKey(This->key);
521 HeapFree(GetProcessHeap(),0,This);
524 static HRESULT WINAPI ProfilesEnumGuid_QueryInterface(IEnumGUID *iface, REFIID iid, LPVOID *ppvOut)
526 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
529 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumGUID))
536 IUnknown_AddRef(iface);
540 WARN("unsupported interface: %s\n", debugstr_guid(iid));
541 return E_NOINTERFACE;
544 static ULONG WINAPI ProfilesEnumGuid_AddRef(IEnumGUID *iface)
546 ProfilesEnumGuid *This = (ProfilesEnumGuid*)iface;
547 return InterlockedIncrement(&This->refCount);
550 static ULONG WINAPI ProfilesEnumGuid_Release(IEnumGUID *iface)
552 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
555 ret = InterlockedDecrement(&This->refCount);
557 ProfilesEnumGuid_Destructor(This);
561 /*****************************************************
562 * IEnumGuid functions
563 *****************************************************/
564 static HRESULT WINAPI ProfilesEnumGuid_Next( LPENUMGUID iface,
565 ULONG celt, GUID *rgelt, ULONG *pceltFetched)
567 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
570 TRACE("(%p)\n",This);
572 if (rgelt == NULL) return E_POINTER;
574 if (This->key) while (fetched < celt)
581 res = RegEnumKeyExW(This->key, This->next_index, catid, &cName,
582 NULL, NULL, NULL, NULL);
583 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
584 ++(This->next_index);
586 hr = CLSIDFromString(catid, rgelt);
587 if (FAILED(hr)) continue;
593 if (pceltFetched) *pceltFetched = fetched;
594 return fetched == celt ? S_OK : S_FALSE;
597 static HRESULT WINAPI ProfilesEnumGuid_Skip( LPENUMGUID iface, ULONG celt)
599 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
600 TRACE("(%p)\n",This);
602 This->next_index += celt;
606 static HRESULT WINAPI ProfilesEnumGuid_Reset( LPENUMGUID iface)
608 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
609 TRACE("(%p)\n",This);
610 This->next_index = 0;
614 static HRESULT WINAPI ProfilesEnumGuid_Clone( LPENUMGUID iface,
617 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
620 TRACE("(%p)\n",This);
622 if (ppenum == NULL) return E_POINTER;
624 res = ProfilesEnumGuid_Constructor(ppenum);
627 ProfilesEnumGuid *new_This = (ProfilesEnumGuid *)*ppenum;
628 new_This->next_index = This->next_index;
633 static const IEnumGUIDVtbl IEnumGUID_Vtbl ={
634 ProfilesEnumGuid_QueryInterface,
635 ProfilesEnumGuid_AddRef,
636 ProfilesEnumGuid_Release,
638 ProfilesEnumGuid_Next,
639 ProfilesEnumGuid_Skip,
640 ProfilesEnumGuid_Reset,
641 ProfilesEnumGuid_Clone
644 static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut)
646 ProfilesEnumGuid *This;
648 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ProfilesEnumGuid));
650 return E_OUTOFMEMORY;
652 This->Vtbl= &IEnumGUID_Vtbl;
655 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szwSystemTIPKey, 0, NULL, 0,
656 KEY_READ | KEY_WRITE, NULL, &This->key, NULL) != ERROR_SUCCESS)
659 TRACE("returning %p\n", This);
660 *ppOut = (IEnumGUID*)This;
664 /**************************************************
665 * IEnumTfLanguageProfiles implementaion
666 **************************************************/
667 static void EnumTfLanguageProfiles_Destructor(EnumTfLanguageProfiles *This)
669 TRACE("destroying %p\n", This);
670 RegCloseKey(This->tipkey);
672 RegCloseKey(This->langkey);
673 HeapFree(GetProcessHeap(),0,This);
676 static HRESULT WINAPI EnumTfLanguageProfiles_QueryInterface(IEnumTfLanguageProfiles *iface, REFIID iid, LPVOID *ppvOut)
678 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
681 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumTfLanguageProfiles))
688 IUnknown_AddRef(iface);
692 WARN("unsupported interface: %s\n", debugstr_guid(iid));
693 return E_NOINTERFACE;
696 static ULONG WINAPI EnumTfLanguageProfiles_AddRef(IEnumTfLanguageProfiles *iface)
698 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles*)iface;
699 return InterlockedIncrement(&This->refCount);
702 static ULONG WINAPI EnumTfLanguageProfiles_Release(IEnumTfLanguageProfiles *iface)
704 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
707 ret = InterlockedDecrement(&This->refCount);
709 EnumTfLanguageProfiles_Destructor(This);
713 /*****************************************************
714 * IEnumGuid functions
715 *****************************************************/
716 static INT next_LanguageProfile(EnumTfLanguageProfiles *This, CLSID clsid, TF_LANGUAGEPROFILE *tflp)
724 static const WCHAR fmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
726 if (This->langkey == NULL)
728 sprintfW(fullkey,fmt,This->szwCurrentClsid,szwLngp,This->langid);
729 res = RegOpenKeyExW(This->tipkey, fullkey, 0, KEY_READ | KEY_WRITE, &This->langkey);
732 This->langkey = NULL;
735 This->lang_index = 0;
737 res = RegEnumKeyExW(This->langkey, This->lang_index, profileid, &cName,
738 NULL, NULL, NULL, NULL);
739 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
741 RegCloseKey(This->langkey);
742 This->langkey = NULL;
745 ++(This->lang_index);
749 res = CLSIDFromString(profileid, &profile);
750 if (FAILED(res)) return 0;
753 tflp->langid = This->langid;
755 tflp->fActive = FALSE;
756 tflp->guidProfile = profile;
757 /* FIXME set catid */
763 static HRESULT WINAPI EnumTfLanguageProfiles_Next(IEnumTfLanguageProfiles *iface,
764 ULONG ulCount, TF_LANGUAGEPROFILE *pProfile, ULONG *pcFetch)
766 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
769 TRACE("(%p)\n",This);
771 if (pProfile == NULL) return E_POINTER;
773 if (This->tipkey) while (fetched < ulCount)
780 res = RegEnumKeyExW(This->tipkey, This->tip_index,
781 This->szwCurrentClsid, &cName, NULL, NULL, NULL, NULL);
782 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
784 hr = CLSIDFromString(This->szwCurrentClsid, &clsid);
785 if (FAILED(hr)) continue;
787 while ( fetched < ulCount)
789 INT res = next_LanguageProfile(This, clsid, pProfile);
802 if (pcFetch) *pcFetch = fetched;
803 return fetched == ulCount ? S_OK : S_FALSE;
806 static HRESULT WINAPI EnumTfLanguageProfiles_Skip( IEnumTfLanguageProfiles* iface, ULONG celt)
808 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
809 FIXME("STUB (%p)\n",This);
813 static HRESULT WINAPI EnumTfLanguageProfiles_Reset( IEnumTfLanguageProfiles* iface)
815 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
816 TRACE("(%p)\n",This);
819 RegCloseKey(This->langkey);
820 This->langkey = NULL;
821 This->lang_index = 0;
825 static HRESULT WINAPI EnumTfLanguageProfiles_Clone( IEnumTfLanguageProfiles *iface,
826 IEnumTfLanguageProfiles **ppenum)
828 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
831 TRACE("(%p)\n",This);
833 if (ppenum == NULL) return E_POINTER;
835 res = EnumTfLanguageProfiles_Constructor(This->langid, ppenum);
838 EnumTfLanguageProfiles *new_This = (EnumTfLanguageProfiles *)*ppenum;
839 new_This->tip_index = This->tip_index;
840 lstrcpynW(new_This->szwCurrentClsid,This->szwCurrentClsid,39);
845 static const WCHAR fmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
847 sprintfW(fullkey,fmt,This->szwCurrentClsid,szwLngp,This->langid);
848 res = RegOpenKeyExW(new_This->tipkey, fullkey, 0, KEY_READ | KEY_WRITE, &This->langkey);
849 new_This->lang_index = This->lang_index;
855 static const IEnumTfLanguageProfilesVtbl IEnumTfLanguageProfiles_Vtbl ={
856 EnumTfLanguageProfiles_QueryInterface,
857 EnumTfLanguageProfiles_AddRef,
858 EnumTfLanguageProfiles_Release,
860 EnumTfLanguageProfiles_Clone,
861 EnumTfLanguageProfiles_Next,
862 EnumTfLanguageProfiles_Reset,
863 EnumTfLanguageProfiles_Skip
866 static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut)
868 EnumTfLanguageProfiles *This;
870 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EnumTfLanguageProfiles));
872 return E_OUTOFMEMORY;
874 This->Vtbl= &IEnumTfLanguageProfiles_Vtbl;
876 This->langid = langid;
878 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szwSystemTIPKey, 0, NULL, 0,
879 KEY_READ | KEY_WRITE, NULL, &This->tipkey, NULL) != ERROR_SUCCESS)
882 TRACE("returning %p\n", This);
883 *ppOut = (IEnumTfLanguageProfiles*)This;