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 ITfCategoryMgr *catmgr;
76 } EnumTfLanguageProfiles;
78 static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut);
79 static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut);
81 static void InputProcessorProfiles_Destructor(InputProcessorProfiles *This)
83 TRACE("destroying %p\n", This);
84 HeapFree(GetProcessHeap(),0,This);
87 static void add_userkey( REFCLSID rclsid, LANGID langid,
94 DWORD disposition = 0;
99 StringFromGUID2(rclsid, buf, 39);
100 StringFromGUID2(guidProfile, buf2, 39);
101 sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
103 res = RegCreateKeyExW(HKEY_CURRENT_USER,fullkey, 0, NULL, 0,
104 KEY_READ | KEY_WRITE, NULL, &key, &disposition);
106 if (!res && disposition == REG_CREATED_NEW_KEY)
109 RegSetValueExW(key, szwEnabled, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD));
116 static HRESULT WINAPI InputProcessorProfiles_QueryInterface(ITfInputProcessorProfiles *iface, REFIID iid, LPVOID *ppvOut)
118 InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
121 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfInputProcessorProfiles))
128 IUnknown_AddRef(iface);
132 WARN("unsupported interface: %s\n", debugstr_guid(iid));
133 return E_NOINTERFACE;
136 static ULONG WINAPI InputProcessorProfiles_AddRef(ITfInputProcessorProfiles *iface)
138 InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
139 return InterlockedIncrement(&This->refCount);
142 static ULONG WINAPI InputProcessorProfiles_Release(ITfInputProcessorProfiles *iface)
144 InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
147 ret = InterlockedDecrement(&This->refCount);
149 InputProcessorProfiles_Destructor(This);
153 /*****************************************************
154 * ITfInputProcessorProfiles functions
155 *****************************************************/
156 static HRESULT WINAPI InputProcessorProfiles_Register(
157 ITfInputProcessorProfiles *iface, REFCLSID rclsid)
159 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
164 TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
166 StringFromGUID2(rclsid, buf, 39);
167 sprintfW(fullkey,szwTipfmt,szwSystemTIPKey,buf);
169 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, NULL, 0,
170 KEY_READ | KEY_WRITE, NULL, &tipkey, NULL) != ERROR_SUCCESS)
178 static HRESULT WINAPI InputProcessorProfiles_Unregister(
179 ITfInputProcessorProfiles *iface, REFCLSID rclsid)
183 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
185 TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
187 StringFromGUID2(rclsid, buf, 39);
188 sprintfW(fullkey,szwTipfmt,szwSystemTIPKey,buf);
190 RegDeleteTreeW(HKEY_LOCAL_MACHINE, fullkey);
191 RegDeleteTreeW(HKEY_CURRENT_USER, fullkey);
196 static HRESULT WINAPI InputProcessorProfiles_AddLanguageProfile(
197 ITfInputProcessorProfiles *iface, REFCLSID rclsid,
198 LANGID langid, REFGUID guidProfile, const WCHAR *pchDesc,
199 ULONG cchDesc, const WCHAR *pchIconFile, ULONG cchFile,
206 DWORD disposition = 0;
208 static const WCHAR fmt2[] = {'%','s','\\','0','x','%','0','8','x','\\','%','s',0};
209 static const WCHAR desc[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
210 static const WCHAR icnf[] = {'I','c','o','n','F','i','l','e',0};
211 static const WCHAR icni[] = {'I','c','o','n','I','n','d','e','x',0};
213 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
215 TRACE("(%p) %s %x %s %s %s %i\n",This,debugstr_guid(rclsid), langid,
216 debugstr_guid(guidProfile), debugstr_wn(pchDesc,cchDesc),
217 debugstr_wn(pchIconFile,cchFile),uIconIndex);
219 StringFromGUID2(rclsid, buf, 39);
220 sprintfW(fullkey,szwTipfmt,szwSystemTIPKey,buf);
222 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, KEY_READ | KEY_WRITE,
223 &tipkey ) != ERROR_SUCCESS)
226 StringFromGUID2(guidProfile, buf, 39);
227 sprintfW(fullkey,fmt2,szwLngp,langid,buf);
229 res = RegCreateKeyExW(tipkey,fullkey, 0, NULL, 0, KEY_READ | KEY_WRITE,
230 NULL, &fmtkey, &disposition);
235 RegSetValueExW(fmtkey, desc, 0, REG_SZ, (LPBYTE)pchDesc, cchDesc * sizeof(WCHAR));
236 RegSetValueExW(fmtkey, icnf, 0, REG_SZ, (LPBYTE)pchIconFile, cchFile * sizeof(WCHAR));
237 RegSetValueExW(fmtkey, icni, 0, REG_DWORD, (LPBYTE)&uIconIndex, sizeof(DWORD));
238 if (disposition == REG_CREATED_NEW_KEY)
239 RegSetValueExW(fmtkey, szwEnabled, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD));
242 add_userkey(rclsid, langid, guidProfile);
252 static HRESULT WINAPI InputProcessorProfiles_RemoveLanguageProfile(
253 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
256 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
257 FIXME("STUB:(%p)\n",This);
261 static HRESULT WINAPI InputProcessorProfiles_EnumInputProcessorInfo(
262 ITfInputProcessorProfiles *iface, IEnumGUID **ppEnum)
264 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
265 TRACE("(%p) %p\n",This,ppEnum);
266 return ProfilesEnumGuid_Constructor(ppEnum);
269 static HRESULT WINAPI InputProcessorProfiles_GetDefaultLanguageProfile(
270 ITfInputProcessorProfiles *iface, LANGID langid, REFGUID catid,
271 CLSID *pclsid, GUID *pguidProfile)
273 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
274 FIXME("STUB:(%p)\n",This);
278 static HRESULT WINAPI InputProcessorProfiles_SetDefaultLanguageProfile(
279 ITfInputProcessorProfiles *iface, LANGID langid, REFCLSID rclsid,
280 REFGUID guidProfiles)
282 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
283 FIXME("STUB:(%p)\n",This);
287 static HRESULT WINAPI InputProcessorProfiles_ActivateLanguageProfile(
288 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
289 REFGUID guidProfiles)
291 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
292 FIXME("STUB:(%p)\n",This);
296 static HRESULT WINAPI InputProcessorProfiles_GetActiveLanguageProfile(
297 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID *plangid,
300 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
301 FIXME("STUB:(%p)\n",This);
305 static HRESULT WINAPI InputProcessorProfiles_GetLanguageProfileDescription(
306 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
307 REFGUID guidProfile, BSTR *pbstrProfile)
309 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
310 FIXME("STUB:(%p)\n",This);
314 static HRESULT WINAPI InputProcessorProfiles_GetCurrentLanguage(
315 ITfInputProcessorProfiles *iface, LANGID *plangid)
317 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
318 TRACE("(%p) 0x%x\n",This,This->currentLanguage);
323 *plangid = This->currentLanguage;
328 static HRESULT WINAPI InputProcessorProfiles_ChangeCurrentLanguage(
329 ITfInputProcessorProfiles *iface, LANGID langid)
331 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
332 FIXME("STUB:(%p)\n",This);
336 static HRESULT WINAPI InputProcessorProfiles_GetLanguageList(
337 ITfInputProcessorProfiles *iface, LANGID **ppLangId, ULONG *pulCount)
339 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
340 FIXME("STUB:(%p)\n",This);
344 static HRESULT WINAPI InputProcessorProfiles_EnumLanguageProfiles(
345 ITfInputProcessorProfiles *iface, LANGID langid,
346 IEnumTfLanguageProfiles **ppEnum)
348 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
349 TRACE("(%p) %x %p\n",This,langid,ppEnum);
350 return EnumTfLanguageProfiles_Constructor(langid, ppEnum);
353 static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfile(
354 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
355 REFGUID guidProfile, BOOL fEnable)
363 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
364 TRACE("(%p) %s %x %s %i\n",This, debugstr_guid(rclsid), langid, debugstr_guid(guidProfile), fEnable);
366 StringFromGUID2(rclsid, buf, 39);
367 StringFromGUID2(guidProfile, buf2, 39);
368 sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
370 res = RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE, &key);
374 RegSetValueExW(key, szwEnabled, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD));
383 static HRESULT WINAPI InputProcessorProfiles_IsEnabledLanguageProfile(
384 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
385 REFGUID guidProfile, BOOL *pfEnable)
393 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
394 TRACE("(%p) %s, %i, %s, %p\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfile),pfEnable);
399 StringFromGUID2(rclsid, buf, 39);
400 StringFromGUID2(guidProfile, buf2, 39);
401 sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
403 res = RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE, &key);
407 DWORD count = sizeof(DWORD);
408 res = RegQueryValueExW(key, szwEnabled, 0, NULL, (LPBYTE)pfEnable, &count);
412 if (res) /* Try Default */
414 res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | KEY_WRITE, &key);
418 DWORD count = sizeof(DWORD);
419 res = RegQueryValueExW(key, szwEnabled, 0, NULL, (LPBYTE)pfEnable, &count);
430 static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfileByDefault(
431 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
432 REFGUID guidProfile, BOOL fEnable)
440 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
441 TRACE("(%p) %s %x %s %i\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfile),fEnable);
443 StringFromGUID2(rclsid, buf, 39);
444 StringFromGUID2(guidProfile, buf2, 39);
445 sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
447 res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | KEY_WRITE, &key);
451 RegSetValueExW(key, szwEnabled, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD));
460 static HRESULT WINAPI InputProcessorProfiles_SubstituteKeyboardLayout(
461 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
462 REFGUID guidProfile, HKL hKL)
464 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
465 FIXME("STUB:(%p)\n",This);
470 static const ITfInputProcessorProfilesVtbl InputProcessorProfiles_InputProcessorProfilesVtbl =
472 InputProcessorProfiles_QueryInterface,
473 InputProcessorProfiles_AddRef,
474 InputProcessorProfiles_Release,
476 InputProcessorProfiles_Register,
477 InputProcessorProfiles_Unregister,
478 InputProcessorProfiles_AddLanguageProfile,
479 InputProcessorProfiles_RemoveLanguageProfile,
480 InputProcessorProfiles_EnumInputProcessorInfo,
481 InputProcessorProfiles_GetDefaultLanguageProfile,
482 InputProcessorProfiles_SetDefaultLanguageProfile,
483 InputProcessorProfiles_ActivateLanguageProfile,
484 InputProcessorProfiles_GetActiveLanguageProfile,
485 InputProcessorProfiles_GetLanguageProfileDescription,
486 InputProcessorProfiles_GetCurrentLanguage,
487 InputProcessorProfiles_ChangeCurrentLanguage,
488 InputProcessorProfiles_GetLanguageList,
489 InputProcessorProfiles_EnumLanguageProfiles,
490 InputProcessorProfiles_EnableLanguageProfile,
491 InputProcessorProfiles_IsEnabledLanguageProfile,
492 InputProcessorProfiles_EnableLanguageProfileByDefault,
493 InputProcessorProfiles_SubstituteKeyboardLayout
496 HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
498 InputProcessorProfiles *This;
500 return CLASS_E_NOAGGREGATION;
502 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputProcessorProfiles));
504 return E_OUTOFMEMORY;
506 This->InputProcessorProfilesVtbl= &InputProcessorProfiles_InputProcessorProfilesVtbl;
508 This->currentLanguage = GetUserDefaultLCID();
510 TRACE("returning %p\n", This);
511 *ppOut = (IUnknown *)This;
515 /**************************************************
516 * IEnumGUID implementaion for ITfInputProcessorProfiles::EnumInputProcessorInfo
517 **************************************************/
518 static void ProfilesEnumGuid_Destructor(ProfilesEnumGuid *This)
520 TRACE("destroying %p\n", This);
521 RegCloseKey(This->key);
522 HeapFree(GetProcessHeap(),0,This);
525 static HRESULT WINAPI ProfilesEnumGuid_QueryInterface(IEnumGUID *iface, REFIID iid, LPVOID *ppvOut)
527 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
530 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumGUID))
537 IUnknown_AddRef(iface);
541 WARN("unsupported interface: %s\n", debugstr_guid(iid));
542 return E_NOINTERFACE;
545 static ULONG WINAPI ProfilesEnumGuid_AddRef(IEnumGUID *iface)
547 ProfilesEnumGuid *This = (ProfilesEnumGuid*)iface;
548 return InterlockedIncrement(&This->refCount);
551 static ULONG WINAPI ProfilesEnumGuid_Release(IEnumGUID *iface)
553 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
556 ret = InterlockedDecrement(&This->refCount);
558 ProfilesEnumGuid_Destructor(This);
562 /*****************************************************
563 * IEnumGuid functions
564 *****************************************************/
565 static HRESULT WINAPI ProfilesEnumGuid_Next( LPENUMGUID iface,
566 ULONG celt, GUID *rgelt, ULONG *pceltFetched)
568 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
571 TRACE("(%p)\n",This);
573 if (rgelt == NULL) return E_POINTER;
575 if (This->key) while (fetched < celt)
582 res = RegEnumKeyExW(This->key, This->next_index, catid, &cName,
583 NULL, NULL, NULL, NULL);
584 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
585 ++(This->next_index);
587 hr = CLSIDFromString(catid, rgelt);
588 if (FAILED(hr)) continue;
594 if (pceltFetched) *pceltFetched = fetched;
595 return fetched == celt ? S_OK : S_FALSE;
598 static HRESULT WINAPI ProfilesEnumGuid_Skip( LPENUMGUID iface, ULONG celt)
600 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
601 TRACE("(%p)\n",This);
603 This->next_index += celt;
607 static HRESULT WINAPI ProfilesEnumGuid_Reset( LPENUMGUID iface)
609 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
610 TRACE("(%p)\n",This);
611 This->next_index = 0;
615 static HRESULT WINAPI ProfilesEnumGuid_Clone( LPENUMGUID iface,
618 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
621 TRACE("(%p)\n",This);
623 if (ppenum == NULL) return E_POINTER;
625 res = ProfilesEnumGuid_Constructor(ppenum);
628 ProfilesEnumGuid *new_This = (ProfilesEnumGuid *)*ppenum;
629 new_This->next_index = This->next_index;
634 static const IEnumGUIDVtbl IEnumGUID_Vtbl ={
635 ProfilesEnumGuid_QueryInterface,
636 ProfilesEnumGuid_AddRef,
637 ProfilesEnumGuid_Release,
639 ProfilesEnumGuid_Next,
640 ProfilesEnumGuid_Skip,
641 ProfilesEnumGuid_Reset,
642 ProfilesEnumGuid_Clone
645 static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut)
647 ProfilesEnumGuid *This;
649 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ProfilesEnumGuid));
651 return E_OUTOFMEMORY;
653 This->Vtbl= &IEnumGUID_Vtbl;
656 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szwSystemTIPKey, 0, NULL, 0,
657 KEY_READ | KEY_WRITE, NULL, &This->key, NULL) != ERROR_SUCCESS)
660 TRACE("returning %p\n", This);
661 *ppOut = (IEnumGUID*)This;
665 /**************************************************
666 * IEnumTfLanguageProfiles implementaion
667 **************************************************/
668 static void EnumTfLanguageProfiles_Destructor(EnumTfLanguageProfiles *This)
670 TRACE("destroying %p\n", This);
671 RegCloseKey(This->tipkey);
673 RegCloseKey(This->langkey);
674 ITfCategoryMgr_Release(This->catmgr);
675 HeapFree(GetProcessHeap(),0,This);
678 static HRESULT WINAPI EnumTfLanguageProfiles_QueryInterface(IEnumTfLanguageProfiles *iface, REFIID iid, LPVOID *ppvOut)
680 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
683 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumTfLanguageProfiles))
690 IUnknown_AddRef(iface);
694 WARN("unsupported interface: %s\n", debugstr_guid(iid));
695 return E_NOINTERFACE;
698 static ULONG WINAPI EnumTfLanguageProfiles_AddRef(IEnumTfLanguageProfiles *iface)
700 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles*)iface;
701 return InterlockedIncrement(&This->refCount);
704 static ULONG WINAPI EnumTfLanguageProfiles_Release(IEnumTfLanguageProfiles *iface)
706 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
709 ret = InterlockedDecrement(&This->refCount);
711 EnumTfLanguageProfiles_Destructor(This);
715 /*****************************************************
716 * IEnumGuid functions
717 *****************************************************/
718 static INT next_LanguageProfile(EnumTfLanguageProfiles *This, CLSID clsid, TF_LANGUAGEPROFILE *tflp)
726 static const WCHAR fmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
728 if (This->langkey == NULL)
730 sprintfW(fullkey,fmt,This->szwCurrentClsid,szwLngp,This->langid);
731 res = RegOpenKeyExW(This->tipkey, fullkey, 0, KEY_READ | KEY_WRITE, &This->langkey);
734 This->langkey = NULL;
737 This->lang_index = 0;
739 res = RegEnumKeyExW(This->langkey, This->lang_index, profileid, &cName,
740 NULL, NULL, NULL, NULL);
741 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
743 RegCloseKey(This->langkey);
744 This->langkey = NULL;
747 ++(This->lang_index);
751 static const GUID * tipcats[3] = { &GUID_TFCAT_TIP_KEYBOARD,
752 &GUID_TFCAT_TIP_SPEECH,
753 &GUID_TFCAT_TIP_HANDWRITING };
754 res = CLSIDFromString(profileid, &profile);
755 if (FAILED(res)) return 0;
758 tflp->langid = This->langid;
760 tflp->fActive = FALSE;
761 tflp->guidProfile = profile;
762 if (ITfCategoryMgr_FindClosestCategory(This->catmgr, &clsid,
763 &tflp->catid, tipcats, 3) != S_OK)
764 ITfCategoryMgr_FindClosestCategory(This->catmgr, &clsid,
765 &tflp->catid, NULL, 0);
771 static HRESULT WINAPI EnumTfLanguageProfiles_Next(IEnumTfLanguageProfiles *iface,
772 ULONG ulCount, TF_LANGUAGEPROFILE *pProfile, ULONG *pcFetch)
774 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
777 TRACE("(%p)\n",This);
779 if (pProfile == NULL) return E_POINTER;
781 if (This->tipkey) while (fetched < ulCount)
788 res = RegEnumKeyExW(This->tipkey, This->tip_index,
789 This->szwCurrentClsid, &cName, NULL, NULL, NULL, NULL);
790 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
792 hr = CLSIDFromString(This->szwCurrentClsid, &clsid);
793 if (FAILED(hr)) continue;
795 while ( fetched < ulCount)
797 INT res = next_LanguageProfile(This, clsid, pProfile);
810 if (pcFetch) *pcFetch = fetched;
811 return fetched == ulCount ? S_OK : S_FALSE;
814 static HRESULT WINAPI EnumTfLanguageProfiles_Skip( IEnumTfLanguageProfiles* iface, ULONG celt)
816 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
817 FIXME("STUB (%p)\n",This);
821 static HRESULT WINAPI EnumTfLanguageProfiles_Reset( IEnumTfLanguageProfiles* iface)
823 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
824 TRACE("(%p)\n",This);
827 RegCloseKey(This->langkey);
828 This->langkey = NULL;
829 This->lang_index = 0;
833 static HRESULT WINAPI EnumTfLanguageProfiles_Clone( IEnumTfLanguageProfiles *iface,
834 IEnumTfLanguageProfiles **ppenum)
836 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
839 TRACE("(%p)\n",This);
841 if (ppenum == NULL) return E_POINTER;
843 res = EnumTfLanguageProfiles_Constructor(This->langid, ppenum);
846 EnumTfLanguageProfiles *new_This = (EnumTfLanguageProfiles *)*ppenum;
847 new_This->tip_index = This->tip_index;
848 lstrcpynW(new_This->szwCurrentClsid,This->szwCurrentClsid,39);
853 static const WCHAR fmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
855 sprintfW(fullkey,fmt,This->szwCurrentClsid,szwLngp,This->langid);
856 res = RegOpenKeyExW(new_This->tipkey, fullkey, 0, KEY_READ | KEY_WRITE, &This->langkey);
857 new_This->lang_index = This->lang_index;
863 static const IEnumTfLanguageProfilesVtbl IEnumTfLanguageProfiles_Vtbl ={
864 EnumTfLanguageProfiles_QueryInterface,
865 EnumTfLanguageProfiles_AddRef,
866 EnumTfLanguageProfiles_Release,
868 EnumTfLanguageProfiles_Clone,
869 EnumTfLanguageProfiles_Next,
870 EnumTfLanguageProfiles_Reset,
871 EnumTfLanguageProfiles_Skip
874 static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut)
877 EnumTfLanguageProfiles *This;
879 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EnumTfLanguageProfiles));
881 return E_OUTOFMEMORY;
883 This->Vtbl= &IEnumTfLanguageProfiles_Vtbl;
885 This->langid = langid;
887 hr = CategoryMgr_Constructor(NULL,(IUnknown**)&This->catmgr);
890 HeapFree(GetProcessHeap(),0,This);
894 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szwSystemTIPKey, 0, NULL, 0,
895 KEY_READ | KEY_WRITE, NULL, &This->tipkey, NULL) != ERROR_SUCCESS)
898 TRACE("returning %p\n", This);
899 *ppOut = (IEnumTfLanguageProfiles*)This;