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)
293 TF_LANGUAGEPROFILE LanguageProfile;
294 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
296 TRACE("(%p) %s %x %s\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfiles));
298 if (langid != This->currentLanguage) return E_INVALIDARG;
300 if (get_active_textservice(rclsid,NULL))
302 TRACE("Already Active\n");
306 hr = ITfInputProcessorProfiles_IsEnabledLanguageProfile(iface, rclsid,
307 langid, guidProfiles, &enabled);
308 if (FAILED(hr) || !enabled)
310 TRACE("Not Enabled\n");
314 LanguageProfile.clsid = *rclsid;
315 LanguageProfile.langid = langid;
316 LanguageProfile.guidProfile = *guidProfiles;
318 hr = add_active_textservice(&LanguageProfile);
323 static HRESULT WINAPI InputProcessorProfiles_GetActiveLanguageProfile(
324 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID *plangid,
327 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
328 FIXME("STUB:(%p)\n",This);
332 static HRESULT WINAPI InputProcessorProfiles_GetLanguageProfileDescription(
333 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
334 REFGUID guidProfile, BSTR *pbstrProfile)
336 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
337 FIXME("STUB:(%p)\n",This);
341 static HRESULT WINAPI InputProcessorProfiles_GetCurrentLanguage(
342 ITfInputProcessorProfiles *iface, LANGID *plangid)
344 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
345 TRACE("(%p) 0x%x\n",This,This->currentLanguage);
350 *plangid = This->currentLanguage;
355 static HRESULT WINAPI InputProcessorProfiles_ChangeCurrentLanguage(
356 ITfInputProcessorProfiles *iface, LANGID langid)
358 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
359 FIXME("STUB:(%p)\n",This);
363 static HRESULT WINAPI InputProcessorProfiles_GetLanguageList(
364 ITfInputProcessorProfiles *iface, LANGID **ppLangId, ULONG *pulCount)
366 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
367 FIXME("STUB:(%p)\n",This);
371 static HRESULT WINAPI InputProcessorProfiles_EnumLanguageProfiles(
372 ITfInputProcessorProfiles *iface, LANGID langid,
373 IEnumTfLanguageProfiles **ppEnum)
375 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
376 TRACE("(%p) %x %p\n",This,langid,ppEnum);
377 return EnumTfLanguageProfiles_Constructor(langid, ppEnum);
380 static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfile(
381 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
382 REFGUID guidProfile, BOOL fEnable)
390 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
391 TRACE("(%p) %s %x %s %i\n",This, debugstr_guid(rclsid), langid, debugstr_guid(guidProfile), fEnable);
393 StringFromGUID2(rclsid, buf, 39);
394 StringFromGUID2(guidProfile, buf2, 39);
395 sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
397 res = RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE, &key);
401 RegSetValueExW(key, szwEnabled, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD));
410 static HRESULT WINAPI InputProcessorProfiles_IsEnabledLanguageProfile(
411 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
412 REFGUID guidProfile, BOOL *pfEnable)
420 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
421 TRACE("(%p) %s, %i, %s, %p\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfile),pfEnable);
426 StringFromGUID2(rclsid, buf, 39);
427 StringFromGUID2(guidProfile, buf2, 39);
428 sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
430 res = RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE, &key);
434 DWORD count = sizeof(DWORD);
435 res = RegQueryValueExW(key, szwEnabled, 0, NULL, (LPBYTE)pfEnable, &count);
439 if (res) /* Try Default */
441 res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | KEY_WRITE, &key);
445 DWORD count = sizeof(DWORD);
446 res = RegQueryValueExW(key, szwEnabled, 0, NULL, (LPBYTE)pfEnable, &count);
457 static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfileByDefault(
458 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
459 REFGUID guidProfile, BOOL fEnable)
467 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
468 TRACE("(%p) %s %x %s %i\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfile),fEnable);
470 StringFromGUID2(rclsid, buf, 39);
471 StringFromGUID2(guidProfile, buf2, 39);
472 sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
474 res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | KEY_WRITE, &key);
478 RegSetValueExW(key, szwEnabled, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD));
487 static HRESULT WINAPI InputProcessorProfiles_SubstituteKeyboardLayout(
488 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
489 REFGUID guidProfile, HKL hKL)
491 InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
492 FIXME("STUB:(%p)\n",This);
497 static const ITfInputProcessorProfilesVtbl InputProcessorProfiles_InputProcessorProfilesVtbl =
499 InputProcessorProfiles_QueryInterface,
500 InputProcessorProfiles_AddRef,
501 InputProcessorProfiles_Release,
503 InputProcessorProfiles_Register,
504 InputProcessorProfiles_Unregister,
505 InputProcessorProfiles_AddLanguageProfile,
506 InputProcessorProfiles_RemoveLanguageProfile,
507 InputProcessorProfiles_EnumInputProcessorInfo,
508 InputProcessorProfiles_GetDefaultLanguageProfile,
509 InputProcessorProfiles_SetDefaultLanguageProfile,
510 InputProcessorProfiles_ActivateLanguageProfile,
511 InputProcessorProfiles_GetActiveLanguageProfile,
512 InputProcessorProfiles_GetLanguageProfileDescription,
513 InputProcessorProfiles_GetCurrentLanguage,
514 InputProcessorProfiles_ChangeCurrentLanguage,
515 InputProcessorProfiles_GetLanguageList,
516 InputProcessorProfiles_EnumLanguageProfiles,
517 InputProcessorProfiles_EnableLanguageProfile,
518 InputProcessorProfiles_IsEnabledLanguageProfile,
519 InputProcessorProfiles_EnableLanguageProfileByDefault,
520 InputProcessorProfiles_SubstituteKeyboardLayout
523 HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
525 InputProcessorProfiles *This;
527 return CLASS_E_NOAGGREGATION;
529 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputProcessorProfiles));
531 return E_OUTOFMEMORY;
533 This->InputProcessorProfilesVtbl= &InputProcessorProfiles_InputProcessorProfilesVtbl;
535 This->currentLanguage = GetUserDefaultLCID();
537 TRACE("returning %p\n", This);
538 *ppOut = (IUnknown *)This;
542 /**************************************************
543 * IEnumGUID implementaion for ITfInputProcessorProfiles::EnumInputProcessorInfo
544 **************************************************/
545 static void ProfilesEnumGuid_Destructor(ProfilesEnumGuid *This)
547 TRACE("destroying %p\n", This);
548 RegCloseKey(This->key);
549 HeapFree(GetProcessHeap(),0,This);
552 static HRESULT WINAPI ProfilesEnumGuid_QueryInterface(IEnumGUID *iface, REFIID iid, LPVOID *ppvOut)
554 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
557 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumGUID))
564 IUnknown_AddRef(iface);
568 WARN("unsupported interface: %s\n", debugstr_guid(iid));
569 return E_NOINTERFACE;
572 static ULONG WINAPI ProfilesEnumGuid_AddRef(IEnumGUID *iface)
574 ProfilesEnumGuid *This = (ProfilesEnumGuid*)iface;
575 return InterlockedIncrement(&This->refCount);
578 static ULONG WINAPI ProfilesEnumGuid_Release(IEnumGUID *iface)
580 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
583 ret = InterlockedDecrement(&This->refCount);
585 ProfilesEnumGuid_Destructor(This);
589 /*****************************************************
590 * IEnumGuid functions
591 *****************************************************/
592 static HRESULT WINAPI ProfilesEnumGuid_Next( LPENUMGUID iface,
593 ULONG celt, GUID *rgelt, ULONG *pceltFetched)
595 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
598 TRACE("(%p)\n",This);
600 if (rgelt == NULL) return E_POINTER;
602 if (This->key) while (fetched < celt)
609 res = RegEnumKeyExW(This->key, This->next_index, catid, &cName,
610 NULL, NULL, NULL, NULL);
611 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
612 ++(This->next_index);
614 hr = CLSIDFromString(catid, rgelt);
615 if (FAILED(hr)) continue;
621 if (pceltFetched) *pceltFetched = fetched;
622 return fetched == celt ? S_OK : S_FALSE;
625 static HRESULT WINAPI ProfilesEnumGuid_Skip( LPENUMGUID iface, ULONG celt)
627 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
628 TRACE("(%p)\n",This);
630 This->next_index += celt;
634 static HRESULT WINAPI ProfilesEnumGuid_Reset( LPENUMGUID iface)
636 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
637 TRACE("(%p)\n",This);
638 This->next_index = 0;
642 static HRESULT WINAPI ProfilesEnumGuid_Clone( LPENUMGUID iface,
645 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
648 TRACE("(%p)\n",This);
650 if (ppenum == NULL) return E_POINTER;
652 res = ProfilesEnumGuid_Constructor(ppenum);
655 ProfilesEnumGuid *new_This = (ProfilesEnumGuid *)*ppenum;
656 new_This->next_index = This->next_index;
661 static const IEnumGUIDVtbl IEnumGUID_Vtbl ={
662 ProfilesEnumGuid_QueryInterface,
663 ProfilesEnumGuid_AddRef,
664 ProfilesEnumGuid_Release,
666 ProfilesEnumGuid_Next,
667 ProfilesEnumGuid_Skip,
668 ProfilesEnumGuid_Reset,
669 ProfilesEnumGuid_Clone
672 static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut)
674 ProfilesEnumGuid *This;
676 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ProfilesEnumGuid));
678 return E_OUTOFMEMORY;
680 This->Vtbl= &IEnumGUID_Vtbl;
683 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szwSystemTIPKey, 0, NULL, 0,
684 KEY_READ | KEY_WRITE, NULL, &This->key, NULL) != ERROR_SUCCESS)
687 TRACE("returning %p\n", This);
688 *ppOut = (IEnumGUID*)This;
692 /**************************************************
693 * IEnumTfLanguageProfiles implementaion
694 **************************************************/
695 static void EnumTfLanguageProfiles_Destructor(EnumTfLanguageProfiles *This)
697 TRACE("destroying %p\n", This);
698 RegCloseKey(This->tipkey);
700 RegCloseKey(This->langkey);
701 ITfCategoryMgr_Release(This->catmgr);
702 HeapFree(GetProcessHeap(),0,This);
705 static HRESULT WINAPI EnumTfLanguageProfiles_QueryInterface(IEnumTfLanguageProfiles *iface, REFIID iid, LPVOID *ppvOut)
707 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
710 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumTfLanguageProfiles))
717 IUnknown_AddRef(iface);
721 WARN("unsupported interface: %s\n", debugstr_guid(iid));
722 return E_NOINTERFACE;
725 static ULONG WINAPI EnumTfLanguageProfiles_AddRef(IEnumTfLanguageProfiles *iface)
727 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles*)iface;
728 return InterlockedIncrement(&This->refCount);
731 static ULONG WINAPI EnumTfLanguageProfiles_Release(IEnumTfLanguageProfiles *iface)
733 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
736 ret = InterlockedDecrement(&This->refCount);
738 EnumTfLanguageProfiles_Destructor(This);
742 /*****************************************************
743 * IEnumGuid functions
744 *****************************************************/
745 static INT next_LanguageProfile(EnumTfLanguageProfiles *This, CLSID clsid, TF_LANGUAGEPROFILE *tflp)
753 static const WCHAR fmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
755 if (This->langkey == NULL)
757 sprintfW(fullkey,fmt,This->szwCurrentClsid,szwLngp,This->langid);
758 res = RegOpenKeyExW(This->tipkey, fullkey, 0, KEY_READ | KEY_WRITE, &This->langkey);
761 This->langkey = NULL;
764 This->lang_index = 0;
766 res = RegEnumKeyExW(This->langkey, This->lang_index, profileid, &cName,
767 NULL, NULL, NULL, NULL);
768 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
770 RegCloseKey(This->langkey);
771 This->langkey = NULL;
774 ++(This->lang_index);
778 static const GUID * tipcats[3] = { &GUID_TFCAT_TIP_KEYBOARD,
779 &GUID_TFCAT_TIP_SPEECH,
780 &GUID_TFCAT_TIP_HANDWRITING };
781 res = CLSIDFromString(profileid, &profile);
782 if (FAILED(res)) return 0;
785 tflp->langid = This->langid;
786 tflp->fActive = get_active_textservice(&clsid, NULL);
787 tflp->guidProfile = profile;
788 if (ITfCategoryMgr_FindClosestCategory(This->catmgr, &clsid,
789 &tflp->catid, tipcats, 3) != S_OK)
790 ITfCategoryMgr_FindClosestCategory(This->catmgr, &clsid,
791 &tflp->catid, NULL, 0);
797 static HRESULT WINAPI EnumTfLanguageProfiles_Next(IEnumTfLanguageProfiles *iface,
798 ULONG ulCount, TF_LANGUAGEPROFILE *pProfile, ULONG *pcFetch)
800 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
803 TRACE("(%p)\n",This);
805 if (pProfile == NULL) return E_POINTER;
807 if (This->tipkey) while (fetched < ulCount)
814 res = RegEnumKeyExW(This->tipkey, This->tip_index,
815 This->szwCurrentClsid, &cName, NULL, NULL, NULL, NULL);
816 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
818 hr = CLSIDFromString(This->szwCurrentClsid, &clsid);
819 if (FAILED(hr)) continue;
821 while ( fetched < ulCount)
823 INT res = next_LanguageProfile(This, clsid, pProfile);
836 if (pcFetch) *pcFetch = fetched;
837 return fetched == ulCount ? S_OK : S_FALSE;
840 static HRESULT WINAPI EnumTfLanguageProfiles_Skip( IEnumTfLanguageProfiles* iface, ULONG celt)
842 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
843 FIXME("STUB (%p)\n",This);
847 static HRESULT WINAPI EnumTfLanguageProfiles_Reset( IEnumTfLanguageProfiles* iface)
849 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
850 TRACE("(%p)\n",This);
853 RegCloseKey(This->langkey);
854 This->langkey = NULL;
855 This->lang_index = 0;
859 static HRESULT WINAPI EnumTfLanguageProfiles_Clone( IEnumTfLanguageProfiles *iface,
860 IEnumTfLanguageProfiles **ppenum)
862 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
865 TRACE("(%p)\n",This);
867 if (ppenum == NULL) return E_POINTER;
869 res = EnumTfLanguageProfiles_Constructor(This->langid, ppenum);
872 EnumTfLanguageProfiles *new_This = (EnumTfLanguageProfiles *)*ppenum;
873 new_This->tip_index = This->tip_index;
874 lstrcpynW(new_This->szwCurrentClsid,This->szwCurrentClsid,39);
879 static const WCHAR fmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
881 sprintfW(fullkey,fmt,This->szwCurrentClsid,szwLngp,This->langid);
882 res = RegOpenKeyExW(new_This->tipkey, fullkey, 0, KEY_READ | KEY_WRITE, &This->langkey);
883 new_This->lang_index = This->lang_index;
889 static const IEnumTfLanguageProfilesVtbl IEnumTfLanguageProfiles_Vtbl ={
890 EnumTfLanguageProfiles_QueryInterface,
891 EnumTfLanguageProfiles_AddRef,
892 EnumTfLanguageProfiles_Release,
894 EnumTfLanguageProfiles_Clone,
895 EnumTfLanguageProfiles_Next,
896 EnumTfLanguageProfiles_Reset,
897 EnumTfLanguageProfiles_Skip
900 static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut)
903 EnumTfLanguageProfiles *This;
905 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EnumTfLanguageProfiles));
907 return E_OUTOFMEMORY;
909 This->Vtbl= &IEnumTfLanguageProfiles_Vtbl;
911 This->langid = langid;
913 hr = CategoryMgr_Constructor(NULL,(IUnknown**)&This->catmgr);
916 HeapFree(GetProcessHeap(),0,This);
920 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szwSystemTIPKey, 0, NULL, 0,
921 KEY_READ | KEY_WRITE, NULL, &This->tipkey, NULL) != ERROR_SUCCESS)
924 TRACE("returning %p\n", This);
925 *ppOut = (IEnumTfLanguageProfiles*)This;