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
;