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"
37 #include "wine/unicode.h"
38 #include "wine/list.h"
41 #include "msctf_internal.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(msctf
);
45 static const WCHAR szwLngp
[] = {'L','a','n','g','u','a','g','e','P','r','o','f','i','l','e',0};
46 static const WCHAR szwEnable
[] = {'E','n','a','b','l','e',0};
47 static const WCHAR szwTipfmt
[] = {'%','s','\\','%','s',0};
48 static const WCHAR szwFullLangfmt
[] = {'%','s','\\','%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
50 static const WCHAR szwAssemblies
[] = {'A','s','s','e','m','b','l','i','e','s',0};
51 static const WCHAR szwDefault
[] = {'D','e','f','a','u','l','t',0};
52 static const WCHAR szwProfile
[] = {'P','r','o','f','i','l','e',0};
53 static const WCHAR szwDefaultFmt
[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
55 typedef struct tagInputProcessorProfilesSink
{
58 /* InputProcessorProfile Sinks */
60 ITfLanguageProfileNotifySink
*pITfLanguageProfileNotifySink
;
62 } InputProcessorProfilesSink
;
64 typedef struct tagInputProcessorProfiles
{
65 ITfInputProcessorProfiles ITfInputProcessorProfiles_iface
;
66 ITfSource ITfSource_iface
;
67 ITfInputProcessorProfileMgr ITfInputProcessorProfileMgr_iface
;
68 /* const ITfInputProcessorProfilesExVtbl *InputProcessorProfilesExVtbl; */
69 /* const ITfInputProcessorProfileSubstituteLayoutVtbl *InputProcessorProfileSubstituteLayoutVtbl; */
72 LANGID currentLanguage
;
74 struct list LanguageProfileNotifySink
;
75 } InputProcessorProfiles
;
77 typedef struct tagProfilesEnumGuid
{
78 IEnumGUID IEnumGUID_iface
;
85 typedef struct tagEnumTfLanguageProfiles
{
86 IEnumTfLanguageProfiles IEnumTfLanguageProfiles_iface
;
91 WCHAR szwCurrentClsid
[39];
97 ITfCategoryMgr
*catmgr
;
98 } EnumTfLanguageProfiles
;
101 IEnumTfInputProcessorProfiles IEnumTfInputProcessorProfiles_iface
;
103 } EnumTfInputProcessorProfiles
;
105 static HRESULT
ProfilesEnumGuid_Constructor(IEnumGUID
**ppOut
);
106 static HRESULT
EnumTfLanguageProfiles_Constructor(LANGID langid
, IEnumTfLanguageProfiles
**ppOut
);
108 static inline EnumTfInputProcessorProfiles
*impl_from_IEnumTfInputProcessorProfiles(IEnumTfInputProcessorProfiles
*iface
)
110 return CONTAINING_RECORD(iface
, EnumTfInputProcessorProfiles
, IEnumTfInputProcessorProfiles_iface
);
113 static HRESULT WINAPI
EnumTfInputProcessorProfiles_QueryInterface(IEnumTfInputProcessorProfiles
*iface
,
114 REFIID riid
, void **ppv
)
116 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
118 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
119 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
120 *ppv
= &This
->IEnumTfInputProcessorProfiles_iface
;
121 }else if(IsEqualGUID(riid
, &IID_IEnumTfInputProcessorProfiles
)) {
122 TRACE("(%p)->(IID_IEnumTfInputProcessorProfiles %p)\n", This
, ppv
);
123 *ppv
= &This
->IEnumTfInputProcessorProfiles_iface
;
126 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
127 return E_NOINTERFACE
;
130 IUnknown_AddRef((IUnknown
*)*ppv
);
134 static ULONG WINAPI
EnumTfInputProcessorProfiles_AddRef(IEnumTfInputProcessorProfiles
*iface
)
136 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
137 LONG ref
= InterlockedIncrement(&This
->ref
);
139 TRACE("(%p) ref=%d\n", This
, ref
);
144 static ULONG WINAPI
EnumTfInputProcessorProfiles_Release(IEnumTfInputProcessorProfiles
*iface
)
146 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
147 LONG ref
= InterlockedDecrement(&This
->ref
);
149 TRACE("(%p) ref=%d\n", This
, ref
);
152 HeapFree(GetProcessHeap(), 0, This
);
157 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Clone(IEnumTfInputProcessorProfiles
*iface
,
158 IEnumTfInputProcessorProfiles
**ret
)
160 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
161 FIXME("(%p)->(%p)\n", This
, ret
);
165 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Next(IEnumTfInputProcessorProfiles
*iface
, ULONG count
,
166 TF_INPUTPROCESSORPROFILE
*profile
, ULONG
*fetch
)
168 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
170 FIXME("(%p)->(%u %p %p)\n", This
, count
, profile
, fetch
);
177 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Reset(IEnumTfInputProcessorProfiles
*iface
)
179 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
180 FIXME("(%p)\n", This
);
184 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Skip(IEnumTfInputProcessorProfiles
*iface
, ULONG count
)
186 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
187 FIXME("(%p)->(%u)\n", This
, count
);
191 static const IEnumTfInputProcessorProfilesVtbl EnumTfInputProcessorProfilesVtbl
= {
192 EnumTfInputProcessorProfiles_QueryInterface
,
193 EnumTfInputProcessorProfiles_AddRef
,
194 EnumTfInputProcessorProfiles_Release
,
195 EnumTfInputProcessorProfiles_Clone
,
196 EnumTfInputProcessorProfiles_Next
,
197 EnumTfInputProcessorProfiles_Reset
,
198 EnumTfInputProcessorProfiles_Skip
201 static inline InputProcessorProfiles
*impl_from_ITfInputProcessorProfiles(ITfInputProcessorProfiles
*iface
)
203 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfInputProcessorProfiles_iface
);
206 static inline InputProcessorProfiles
*impl_from_ITfSource(ITfSource
*iface
)
208 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfSource_iface
);
211 static inline ProfilesEnumGuid
*impl_from_IEnumGUID(IEnumGUID
*iface
)
213 return CONTAINING_RECORD(iface
, ProfilesEnumGuid
, IEnumGUID_iface
);
216 static inline EnumTfLanguageProfiles
*impl_from_IEnumTfLanguageProfiles(IEnumTfLanguageProfiles
*iface
)
218 return CONTAINING_RECORD(iface
, EnumTfLanguageProfiles
, IEnumTfLanguageProfiles_iface
);
221 static void free_sink(InputProcessorProfilesSink
*sink
)
223 IUnknown_Release(sink
->interfaces
.pIUnknown
);
224 HeapFree(GetProcessHeap(),0,sink
);
227 static void InputProcessorProfiles_Destructor(InputProcessorProfiles
*This
)
229 struct list
*cursor
, *cursor2
;
230 TRACE("destroying %p\n", This
);
233 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->LanguageProfileNotifySink
)
235 InputProcessorProfilesSink
* sink
= LIST_ENTRY(cursor
,InputProcessorProfilesSink
,entry
);
240 HeapFree(GetProcessHeap(),0,This
);
243 static void add_userkey( REFCLSID rclsid
, LANGID langid
,
250 DWORD disposition
= 0;
255 StringFromGUID2(rclsid
, buf
, 39);
256 StringFromGUID2(guidProfile
, buf2
, 39);
257 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
259 res
= RegCreateKeyExW(HKEY_CURRENT_USER
,fullkey
, 0, NULL
, 0,
260 KEY_READ
| KEY_WRITE
, NULL
, &key
, &disposition
);
262 if (!res
&& disposition
== REG_CREATED_NEW_KEY
)
265 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&zero
, sizeof(DWORD
));
272 static HRESULT WINAPI
InputProcessorProfiles_QueryInterface(ITfInputProcessorProfiles
*iface
, REFIID iid
, void **ppv
)
274 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
276 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfInputProcessorProfiles
))
278 *ppv
= &This
->ITfInputProcessorProfiles_iface
;
280 else if (IsEqualIID(iid
, &IID_ITfInputProcessorProfileMgr
))
282 *ppv
= &This
->ITfInputProcessorProfileMgr_iface
;
284 else if (IsEqualIID(iid
, &IID_ITfSource
))
286 *ppv
= &This
->ITfSource_iface
;
291 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
292 return E_NOINTERFACE
;
295 ITfInputProcessorProfiles_AddRef(iface
);
299 static ULONG WINAPI
InputProcessorProfiles_AddRef(ITfInputProcessorProfiles
*iface
)
301 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
302 return InterlockedIncrement(&This
->refCount
);
305 static ULONG WINAPI
InputProcessorProfiles_Release(ITfInputProcessorProfiles
*iface
)
307 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
310 ret
= InterlockedDecrement(&This
->refCount
);
312 InputProcessorProfiles_Destructor(This
);
316 /*****************************************************
317 * ITfInputProcessorProfiles functions
318 *****************************************************/
319 static HRESULT WINAPI
InputProcessorProfiles_Register(
320 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
)
322 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
327 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
329 StringFromGUID2(rclsid
, buf
, 39);
330 sprintfW(fullkey
,szwTipfmt
,szwSystemTIPKey
,buf
);
332 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,fullkey
, 0, NULL
, 0,
333 KEY_READ
| KEY_WRITE
, NULL
, &tipkey
, NULL
) != ERROR_SUCCESS
)
341 static HRESULT WINAPI
InputProcessorProfiles_Unregister(
342 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
)
344 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
348 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
350 StringFromGUID2(rclsid
, buf
, 39);
351 sprintfW(fullkey
,szwTipfmt
,szwSystemTIPKey
,buf
);
353 RegDeleteTreeW(HKEY_LOCAL_MACHINE
, fullkey
);
354 RegDeleteTreeW(HKEY_CURRENT_USER
, fullkey
);
359 static HRESULT WINAPI
InputProcessorProfiles_AddLanguageProfile(
360 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
,
361 LANGID langid
, REFGUID guidProfile
, const WCHAR
*pchDesc
,
362 ULONG cchDesc
, const WCHAR
*pchIconFile
, ULONG cchFile
,
365 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
370 DWORD disposition
= 0;
372 static const WCHAR fmt2
[] = {'%','s','\\','0','x','%','0','8','x','\\','%','s',0};
373 static const WCHAR desc
[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
374 static const WCHAR icnf
[] = {'I','c','o','n','F','i','l','e',0};
375 static const WCHAR icni
[] = {'I','c','o','n','I','n','d','e','x',0};
377 TRACE("(%p) %s %x %s %s %s %i\n",This
,debugstr_guid(rclsid
), langid
,
378 debugstr_guid(guidProfile
), debugstr_wn(pchDesc
,cchDesc
),
379 debugstr_wn(pchIconFile
,cchFile
),uIconIndex
);
381 StringFromGUID2(rclsid
, buf
, 39);
382 sprintfW(fullkey
,szwTipfmt
,szwSystemTIPKey
,buf
);
384 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,fullkey
, 0, KEY_READ
| KEY_WRITE
,
385 &tipkey
) != ERROR_SUCCESS
)
388 StringFromGUID2(guidProfile
, buf
, 39);
389 sprintfW(fullkey
,fmt2
,szwLngp
,langid
,buf
);
391 res
= RegCreateKeyExW(tipkey
,fullkey
, 0, NULL
, 0, KEY_READ
| KEY_WRITE
,
392 NULL
, &fmtkey
, &disposition
);
397 RegSetValueExW(fmtkey
, desc
, 0, REG_SZ
, (const BYTE
*)pchDesc
, cchDesc
* sizeof(WCHAR
));
398 RegSetValueExW(fmtkey
, icnf
, 0, REG_SZ
, (const BYTE
*)pchIconFile
, cchFile
* sizeof(WCHAR
));
399 RegSetValueExW(fmtkey
, icni
, 0, REG_DWORD
, (LPBYTE
)&uIconIndex
, sizeof(DWORD
));
400 if (disposition
== REG_CREATED_NEW_KEY
)
401 RegSetValueExW(fmtkey
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&zero
, sizeof(DWORD
));
404 add_userkey(rclsid
, langid
, guidProfile
);
414 static HRESULT WINAPI
InputProcessorProfiles_RemoveLanguageProfile(
415 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
418 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
419 FIXME("STUB:(%p)\n",This
);
423 static HRESULT WINAPI
InputProcessorProfiles_EnumInputProcessorInfo(
424 ITfInputProcessorProfiles
*iface
, IEnumGUID
**ppEnum
)
426 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
427 TRACE("(%p) %p\n",This
,ppEnum
);
428 return ProfilesEnumGuid_Constructor(ppEnum
);
431 static HRESULT WINAPI
InputProcessorProfiles_GetDefaultLanguageProfile(
432 ITfInputProcessorProfiles
*iface
, LANGID langid
, REFGUID catid
,
433 CLSID
*pclsid
, GUID
*pguidProfile
)
435 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
442 TRACE("%p) %x %s %p %p\n",This
, langid
, debugstr_guid(catid
),pclsid
,pguidProfile
);
444 if (!catid
|| !pclsid
|| !pguidProfile
)
447 StringFromGUID2(catid
, buf
, 39);
448 sprintfW(fullkey
, szwDefaultFmt
, szwSystemCTFKey
, szwAssemblies
, langid
, buf
);
450 if (RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
,
451 &hkey
) != ERROR_SUCCESS
)
455 res
= RegQueryValueExW(hkey
, szwDefault
, 0, NULL
, (LPBYTE
)buf
, &count
);
456 if (res
!= ERROR_SUCCESS
)
461 CLSIDFromString(buf
,pclsid
);
463 res
= RegQueryValueExW(hkey
, szwProfile
, 0, NULL
, (LPBYTE
)buf
, &count
);
464 if (res
== ERROR_SUCCESS
)
465 CLSIDFromString(buf
,pguidProfile
);
472 static HRESULT WINAPI
InputProcessorProfiles_SetDefaultLanguageProfile(
473 ITfInputProcessorProfiles
*iface
, LANGID langid
, REFCLSID rclsid
,
474 REFGUID guidProfiles
)
476 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
482 ITfCategoryMgr
*catmgr
;
483 static const GUID
* tipcats
[3] = { &GUID_TFCAT_TIP_KEYBOARD
,
484 &GUID_TFCAT_TIP_SPEECH
,
485 &GUID_TFCAT_TIP_HANDWRITING
};
487 TRACE("%p) %x %s %s\n",This
, langid
, debugstr_guid(rclsid
),debugstr_guid(guidProfiles
));
489 if (!rclsid
|| !guidProfiles
)
492 hr
= CategoryMgr_Constructor(NULL
,(IUnknown
**)&catmgr
);
497 if (ITfCategoryMgr_FindClosestCategory(catmgr
, rclsid
,
498 &catid
, tipcats
, 3) != S_OK
)
499 hr
= ITfCategoryMgr_FindClosestCategory(catmgr
, rclsid
,
501 ITfCategoryMgr_Release(catmgr
);
506 StringFromGUID2(&catid
, buf
, 39);
507 sprintfW(fullkey
, szwDefaultFmt
, szwSystemCTFKey
, szwAssemblies
, langid
, buf
);
509 if (RegCreateKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, NULL
, 0, KEY_READ
| KEY_WRITE
,
510 NULL
, &hkey
, NULL
) != ERROR_SUCCESS
)
513 StringFromGUID2(rclsid
, buf
, 39);
514 RegSetValueExW(hkey
, szwDefault
, 0, REG_SZ
, (LPBYTE
)buf
, sizeof(buf
));
515 StringFromGUID2(guidProfiles
, buf
, 39);
516 RegSetValueExW(hkey
, szwProfile
, 0, REG_SZ
, (LPBYTE
)buf
, sizeof(buf
));
522 static HRESULT WINAPI
InputProcessorProfiles_ActivateLanguageProfile(
523 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
524 REFGUID guidProfiles
)
526 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
529 TF_LANGUAGEPROFILE LanguageProfile
;
531 TRACE("(%p) %s %x %s\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfiles
));
533 if (langid
!= This
->currentLanguage
) return E_INVALIDARG
;
535 if (get_active_textservice(rclsid
,NULL
))
537 TRACE("Already Active\n");
541 hr
= ITfInputProcessorProfiles_IsEnabledLanguageProfile(iface
, rclsid
,
542 langid
, guidProfiles
, &enabled
);
543 if (FAILED(hr
) || !enabled
)
545 TRACE("Not Enabled\n");
549 LanguageProfile
.clsid
= *rclsid
;
550 LanguageProfile
.langid
= langid
;
551 LanguageProfile
.guidProfile
= *guidProfiles
;
552 LanguageProfile
.fActive
= TRUE
;
554 return add_active_textservice(&LanguageProfile
);
557 static HRESULT WINAPI
InputProcessorProfiles_GetActiveLanguageProfile(
558 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID
*plangid
,
561 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
562 TF_LANGUAGEPROFILE profile
;
564 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(rclsid
),plangid
,pguidProfile
);
566 if (!rclsid
|| !plangid
|| !pguidProfile
)
569 if (get_active_textservice(rclsid
, &profile
))
571 *plangid
= profile
.langid
;
572 *pguidProfile
= profile
.guidProfile
;
577 *pguidProfile
= GUID_NULL
;
582 static HRESULT WINAPI
InputProcessorProfiles_GetLanguageProfileDescription(
583 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
584 REFGUID guidProfile
, BSTR
*pbstrProfile
)
586 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
587 FIXME("STUB:(%p)\n",This
);
591 static HRESULT WINAPI
InputProcessorProfiles_GetCurrentLanguage(
592 ITfInputProcessorProfiles
*iface
, LANGID
*plangid
)
594 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
595 TRACE("(%p) 0x%x\n",This
,This
->currentLanguage
);
600 *plangid
= This
->currentLanguage
;
605 static HRESULT WINAPI
InputProcessorProfiles_ChangeCurrentLanguage(
606 ITfInputProcessorProfiles
*iface
, LANGID langid
)
608 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
612 FIXME("STUB:(%p)\n",This
);
614 LIST_FOR_EACH(cursor
, &This
->LanguageProfileNotifySink
)
616 InputProcessorProfilesSink
* sink
= LIST_ENTRY(cursor
,InputProcessorProfilesSink
,entry
);
618 ITfLanguageProfileNotifySink_OnLanguageChange(sink
->interfaces
.pITfLanguageProfileNotifySink
, langid
, &accept
);
623 /* TODO: On successful language change call OnLanguageChanged sink */
627 static HRESULT WINAPI
InputProcessorProfiles_GetLanguageList(
628 ITfInputProcessorProfiles
*iface
, LANGID
**ppLangId
, ULONG
*pulCount
)
630 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
631 FIXME("Semi-STUB:(%p)\n",This
);
632 *ppLangId
= CoTaskMemAlloc(sizeof(LANGID
));
633 **ppLangId
= This
->currentLanguage
;
638 static HRESULT WINAPI
InputProcessorProfiles_EnumLanguageProfiles(
639 ITfInputProcessorProfiles
*iface
, LANGID langid
,
640 IEnumTfLanguageProfiles
**ppEnum
)
642 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
643 TRACE("(%p) %x %p\n",This
,langid
,ppEnum
);
644 return EnumTfLanguageProfiles_Constructor(langid
, ppEnum
);
647 static HRESULT WINAPI
InputProcessorProfiles_EnableLanguageProfile(
648 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
649 REFGUID guidProfile
, BOOL fEnable
)
651 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
658 TRACE("(%p) %s %x %s %i\n",This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
), fEnable
);
660 StringFromGUID2(rclsid
, buf
, 39);
661 StringFromGUID2(guidProfile
, buf2
, 39);
662 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
664 res
= RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
668 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&fEnable
, sizeof(DWORD
));
677 static HRESULT WINAPI
InputProcessorProfiles_IsEnabledLanguageProfile(
678 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
679 REFGUID guidProfile
, BOOL
*pfEnable
)
681 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
688 TRACE("(%p) %s, %i, %s, %p\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfile
),pfEnable
);
693 StringFromGUID2(rclsid
, buf
, 39);
694 StringFromGUID2(guidProfile
, buf2
, 39);
695 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
697 res
= RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
701 DWORD count
= sizeof(DWORD
);
702 res
= RegQueryValueExW(key
, szwEnable
, 0, NULL
, (LPBYTE
)pfEnable
, &count
);
706 if (res
) /* Try Default */
708 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
712 DWORD count
= sizeof(DWORD
);
713 res
= RegQueryValueExW(key
, szwEnable
, 0, NULL
, (LPBYTE
)pfEnable
, &count
);
724 static HRESULT WINAPI
InputProcessorProfiles_EnableLanguageProfileByDefault(
725 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
726 REFGUID guidProfile
, BOOL fEnable
)
728 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
735 TRACE("(%p) %s %x %s %i\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfile
),fEnable
);
737 StringFromGUID2(rclsid
, buf
, 39);
738 StringFromGUID2(guidProfile
, buf2
, 39);
739 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
741 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
745 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&fEnable
, sizeof(DWORD
));
754 static HRESULT WINAPI
InputProcessorProfiles_SubstituteKeyboardLayout(
755 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
756 REFGUID guidProfile
, HKL hKL
)
758 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
759 FIXME("STUB:(%p)\n",This
);
763 static const ITfInputProcessorProfilesVtbl InputProcessorProfilesVtbl
=
765 InputProcessorProfiles_QueryInterface
,
766 InputProcessorProfiles_AddRef
,
767 InputProcessorProfiles_Release
,
768 InputProcessorProfiles_Register
,
769 InputProcessorProfiles_Unregister
,
770 InputProcessorProfiles_AddLanguageProfile
,
771 InputProcessorProfiles_RemoveLanguageProfile
,
772 InputProcessorProfiles_EnumInputProcessorInfo
,
773 InputProcessorProfiles_GetDefaultLanguageProfile
,
774 InputProcessorProfiles_SetDefaultLanguageProfile
,
775 InputProcessorProfiles_ActivateLanguageProfile
,
776 InputProcessorProfiles_GetActiveLanguageProfile
,
777 InputProcessorProfiles_GetLanguageProfileDescription
,
778 InputProcessorProfiles_GetCurrentLanguage
,
779 InputProcessorProfiles_ChangeCurrentLanguage
,
780 InputProcessorProfiles_GetLanguageList
,
781 InputProcessorProfiles_EnumLanguageProfiles
,
782 InputProcessorProfiles_EnableLanguageProfile
,
783 InputProcessorProfiles_IsEnabledLanguageProfile
,
784 InputProcessorProfiles_EnableLanguageProfileByDefault
,
785 InputProcessorProfiles_SubstituteKeyboardLayout
788 static inline InputProcessorProfiles
*impl_from_ITfInputProcessorProfileMgr(ITfInputProcessorProfileMgr
*iface
)
790 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfInputProcessorProfileMgr_iface
);
793 static HRESULT WINAPI
InputProcessorProfileMgr_QueryInterface(ITfInputProcessorProfileMgr
*iface
, REFIID riid
, void **ppv
)
795 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
796 return ITfInputProcessorProfiles_QueryInterface(&This
->ITfInputProcessorProfiles_iface
, riid
, ppv
);
799 static ULONG WINAPI
InputProcessorProfileMgr_AddRef(ITfInputProcessorProfileMgr
*iface
)
801 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
802 return ITfInputProcessorProfiles_AddRef(&This
->ITfInputProcessorProfiles_iface
);
805 static ULONG WINAPI
InputProcessorProfileMgr_Release(ITfInputProcessorProfileMgr
*iface
)
807 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
808 return ITfInputProcessorProfiles_Release(&This
->ITfInputProcessorProfiles_iface
);
811 static HRESULT WINAPI
InputProcessorProfileMgr_ActivateProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
812 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, DWORD dwFlags
)
814 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
815 FIXME("(%p)->(%d %x %s %s %p %x)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
816 debugstr_guid(guidProfile
), hkl
, dwFlags
);
820 static HRESULT WINAPI
InputProcessorProfileMgr_DeactivateProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
821 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, DWORD dwFlags
)
823 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
824 FIXME("(%p)->(%d %x %s %s %p %x)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
825 debugstr_guid(guidProfile
), hkl
, dwFlags
);
829 static HRESULT WINAPI
InputProcessorProfileMgr_GetProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
830 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, TF_INPUTPROCESSORPROFILE
*pProfile
)
832 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
833 FIXME("(%p)->(%d %x %s %s %p %p)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
834 debugstr_guid(guidProfile
), hkl
, pProfile
);
838 static HRESULT WINAPI
InputProcessorProfileMgr_EnumProfiles(ITfInputProcessorProfileMgr
*iface
, LANGID langid
,
839 IEnumTfInputProcessorProfiles
**ppEnum
)
841 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
842 EnumTfInputProcessorProfiles
*enum_profiles
;
844 TRACE("(%p)->(%x %p)\n", This
, langid
, ppEnum
);
846 enum_profiles
= HeapAlloc(GetProcessHeap(), 0, sizeof(*enum_profiles
));
848 return E_OUTOFMEMORY
;
850 enum_profiles
->IEnumTfInputProcessorProfiles_iface
.lpVtbl
= &EnumTfInputProcessorProfilesVtbl
;
851 enum_profiles
->ref
= 1;
853 *ppEnum
= &enum_profiles
->IEnumTfInputProcessorProfiles_iface
;
857 static HRESULT WINAPI
InputProcessorProfileMgr_ReleaseInputProcessor(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
860 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
861 FIXME("(%p)->(%s %x)\n", This
, debugstr_guid(rclsid
), dwFlags
);
865 static HRESULT WINAPI
InputProcessorProfileMgr_RegisterProfile(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
866 LANGID langid
, REFGUID guidProfile
, const WCHAR
*pchDesc
, ULONG cchDesc
, const WCHAR
*pchIconFile
,
867 ULONG cchFile
, ULONG uIconIndex
, HKL hklsubstitute
, DWORD dwPreferredLayout
, BOOL bEnabledByDefault
,
870 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
871 FIXME("(%p)->(%s %x %s %s %d %s %u %u %p %x %x %x)\n", This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
),
872 debugstr_w(pchDesc
), cchDesc
, debugstr_w(pchIconFile
), cchFile
, uIconIndex
, hklsubstitute
, dwPreferredLayout
,
873 bEnabledByDefault
, dwFlags
);
877 static HRESULT WINAPI
InputProcessorProfileMgr_UnregisterProfile(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
878 LANGID langid
, REFGUID guidProfile
, DWORD dwFlags
)
880 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
881 FIXME("(%p)->(%s %x %s %x)\n", This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
), dwFlags
);
885 static HRESULT WINAPI
InputProcessorProfileMgr_GetActiveProfile(ITfInputProcessorProfileMgr
*iface
, REFGUID catid
,
886 TF_INPUTPROCESSORPROFILE
*pProfile
)
888 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
889 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(catid
), pProfile
);
893 static const ITfInputProcessorProfileMgrVtbl InputProcessorProfileMgrVtbl
= {
894 InputProcessorProfileMgr_QueryInterface
,
895 InputProcessorProfileMgr_AddRef
,
896 InputProcessorProfileMgr_Release
,
897 InputProcessorProfileMgr_ActivateProfile
,
898 InputProcessorProfileMgr_DeactivateProfile
,
899 InputProcessorProfileMgr_GetProfile
,
900 InputProcessorProfileMgr_EnumProfiles
,
901 InputProcessorProfileMgr_ReleaseInputProcessor
,
902 InputProcessorProfileMgr_RegisterProfile
,
903 InputProcessorProfileMgr_UnregisterProfile
,
904 InputProcessorProfileMgr_GetActiveProfile
907 /*****************************************************
908 * ITfSource functions
909 *****************************************************/
910 static HRESULT WINAPI
IPPSource_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
912 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
913 return ITfInputProcessorProfiles_QueryInterface(&This
->ITfInputProcessorProfiles_iface
, iid
, ppvOut
);
916 static ULONG WINAPI
IPPSource_AddRef(ITfSource
*iface
)
918 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
919 return ITfInputProcessorProfiles_AddRef(&This
->ITfInputProcessorProfiles_iface
);
922 static ULONG WINAPI
IPPSource_Release(ITfSource
*iface
)
924 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
925 return ITfInputProcessorProfiles_Release(&This
->ITfInputProcessorProfiles_iface
);
928 static HRESULT WINAPI
IPPSource_AdviseSink(ITfSource
*iface
,
929 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
931 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
932 InputProcessorProfilesSink
*ipps
;
934 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
936 if (!riid
|| !punk
|| !pdwCookie
)
939 if (IsEqualIID(riid
, &IID_ITfLanguageProfileNotifySink
))
941 ipps
= HeapAlloc(GetProcessHeap(),0,sizeof(InputProcessorProfilesSink
));
943 return E_OUTOFMEMORY
;
944 if (FAILED(IUnknown_QueryInterface(punk
, riid
, (LPVOID
*)&ipps
->interfaces
.pITfLanguageProfileNotifySink
)))
946 HeapFree(GetProcessHeap(),0,ipps
);
947 return CONNECT_E_CANNOTCONNECT
;
949 list_add_head(&This
->LanguageProfileNotifySink
,&ipps
->entry
);
950 *pdwCookie
= generate_Cookie(COOKIE_MAGIC_IPPSINK
, ipps
);
954 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
958 TRACE("cookie %x\n",*pdwCookie
);
963 static HRESULT WINAPI
IPPSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
965 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
966 InputProcessorProfilesSink
*sink
;
968 TRACE("(%p) %x\n",This
,pdwCookie
);
970 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_IPPSINK
)
973 sink
= remove_Cookie(pdwCookie
);
975 return CONNECT_E_NOCONNECTION
;
977 list_remove(&sink
->entry
);
983 static const ITfSourceVtbl InputProcessorProfilesSourceVtbl
=
985 IPPSource_QueryInterface
,
988 IPPSource_AdviseSink
,
989 IPPSource_UnadviseSink
,
992 HRESULT
InputProcessorProfiles_Constructor(IUnknown
*pUnkOuter
, IUnknown
**ppOut
)
994 InputProcessorProfiles
*This
;
996 return CLASS_E_NOAGGREGATION
;
998 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(InputProcessorProfiles
));
1000 return E_OUTOFMEMORY
;
1002 This
->ITfInputProcessorProfiles_iface
.lpVtbl
= &InputProcessorProfilesVtbl
;
1003 This
->ITfSource_iface
.lpVtbl
= &InputProcessorProfilesSourceVtbl
;
1004 This
->ITfInputProcessorProfileMgr_iface
.lpVtbl
= &InputProcessorProfileMgrVtbl
;
1006 This
->currentLanguage
= GetUserDefaultLCID();
1008 list_init(&This
->LanguageProfileNotifySink
);
1010 *ppOut
= (IUnknown
*)&This
->ITfInputProcessorProfiles_iface
;
1011 TRACE("returning %p\n", *ppOut
);
1015 /**************************************************
1016 * IEnumGUID implementation for ITfInputProcessorProfiles::EnumInputProcessorInfo
1017 **************************************************/
1018 static void ProfilesEnumGuid_Destructor(ProfilesEnumGuid
*This
)
1020 TRACE("destroying %p\n", This
);
1021 RegCloseKey(This
->key
);
1022 HeapFree(GetProcessHeap(),0,This
);
1025 static HRESULT WINAPI
ProfilesEnumGuid_QueryInterface(IEnumGUID
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1027 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1030 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumGUID
))
1032 *ppvOut
= &This
->IEnumGUID_iface
;
1037 IEnumGUID_AddRef(iface
);
1041 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
1042 return E_NOINTERFACE
;
1045 static ULONG WINAPI
ProfilesEnumGuid_AddRef(IEnumGUID
*iface
)
1047 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1048 return InterlockedIncrement(&This
->refCount
);
1051 static ULONG WINAPI
ProfilesEnumGuid_Release(IEnumGUID
*iface
)
1053 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1056 ret
= InterlockedDecrement(&This
->refCount
);
1058 ProfilesEnumGuid_Destructor(This
);
1062 /*****************************************************
1063 * IEnumGuid functions
1064 *****************************************************/
1065 static HRESULT WINAPI
ProfilesEnumGuid_Next( LPENUMGUID iface
,
1066 ULONG celt
, GUID
*rgelt
, ULONG
*pceltFetched
)
1068 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1071 TRACE("(%p)\n",This
);
1073 if (rgelt
== NULL
) return E_POINTER
;
1075 if (This
->key
) while (fetched
< celt
)
1082 res
= RegEnumKeyExW(This
->key
, This
->next_index
, catid
, &cName
,
1083 NULL
, NULL
, NULL
, NULL
);
1084 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
) break;
1085 ++(This
->next_index
);
1087 hr
= CLSIDFromString(catid
, rgelt
);
1088 if (FAILED(hr
)) continue;
1094 if (pceltFetched
) *pceltFetched
= fetched
;
1095 return fetched
== celt
? S_OK
: S_FALSE
;
1098 static HRESULT WINAPI
ProfilesEnumGuid_Skip( LPENUMGUID iface
, ULONG celt
)
1100 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1101 TRACE("(%p)\n",This
);
1103 This
->next_index
+= celt
;
1107 static HRESULT WINAPI
ProfilesEnumGuid_Reset( LPENUMGUID iface
)
1109 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1110 TRACE("(%p)\n",This
);
1111 This
->next_index
= 0;
1115 static HRESULT WINAPI
ProfilesEnumGuid_Clone( LPENUMGUID iface
,
1118 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1121 TRACE("(%p)\n",This
);
1123 if (ppenum
== NULL
) return E_POINTER
;
1125 res
= ProfilesEnumGuid_Constructor(ppenum
);
1128 ProfilesEnumGuid
*new_This
= impl_from_IEnumGUID(*ppenum
);
1129 new_This
->next_index
= This
->next_index
;
1134 static const IEnumGUIDVtbl EnumGUIDVtbl
=
1136 ProfilesEnumGuid_QueryInterface
,
1137 ProfilesEnumGuid_AddRef
,
1138 ProfilesEnumGuid_Release
,
1139 ProfilesEnumGuid_Next
,
1140 ProfilesEnumGuid_Skip
,
1141 ProfilesEnumGuid_Reset
,
1142 ProfilesEnumGuid_Clone
1145 static HRESULT
ProfilesEnumGuid_Constructor(IEnumGUID
**ppOut
)
1147 ProfilesEnumGuid
*This
;
1149 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ProfilesEnumGuid
));
1151 return E_OUTOFMEMORY
;
1153 This
->IEnumGUID_iface
.lpVtbl
= &EnumGUIDVtbl
;
1156 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
, szwSystemTIPKey
, 0, NULL
, 0,
1157 KEY_READ
| KEY_WRITE
, NULL
, &This
->key
, NULL
) != ERROR_SUCCESS
)
1159 HeapFree(GetProcessHeap(), 0, This
);
1163 *ppOut
= &This
->IEnumGUID_iface
;
1164 TRACE("returning %p\n", *ppOut
);
1168 /**************************************************
1169 * IEnumTfLanguageProfiles implementation
1170 **************************************************/
1171 static void EnumTfLanguageProfiles_Destructor(EnumTfLanguageProfiles
*This
)
1173 TRACE("destroying %p\n", This
);
1174 RegCloseKey(This
->tipkey
);
1176 RegCloseKey(This
->langkey
);
1177 ITfCategoryMgr_Release(This
->catmgr
);
1178 HeapFree(GetProcessHeap(),0,This
);
1181 static HRESULT WINAPI
EnumTfLanguageProfiles_QueryInterface(IEnumTfLanguageProfiles
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1183 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1187 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumTfLanguageProfiles
))
1189 *ppvOut
= &This
->IEnumTfLanguageProfiles_iface
;
1194 IEnumTfLanguageProfiles_AddRef(iface
);
1198 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
1199 return E_NOINTERFACE
;
1202 static ULONG WINAPI
EnumTfLanguageProfiles_AddRef(IEnumTfLanguageProfiles
*iface
)
1204 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1205 return InterlockedIncrement(&This
->refCount
);
1208 static ULONG WINAPI
EnumTfLanguageProfiles_Release(IEnumTfLanguageProfiles
*iface
)
1210 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1213 ret
= InterlockedDecrement(&This
->refCount
);
1215 EnumTfLanguageProfiles_Destructor(This
);
1219 /*****************************************************
1220 * IEnumGuid functions
1221 *****************************************************/
1222 static INT
next_LanguageProfile(EnumTfLanguageProfiles
*This
, CLSID clsid
, TF_LANGUAGEPROFILE
*tflp
)
1226 WCHAR profileid
[39];
1230 static const WCHAR fmt
[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
1232 if (This
->langkey
== NULL
)
1234 sprintfW(fullkey
,fmt
,This
->szwCurrentClsid
,szwLngp
,This
->langid
);
1235 res
= RegOpenKeyExW(This
->tipkey
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &This
->langkey
);
1238 This
->langkey
= NULL
;
1241 This
->lang_index
= 0;
1243 res
= RegEnumKeyExW(This
->langkey
, This
->lang_index
, profileid
, &cName
,
1244 NULL
, NULL
, NULL
, NULL
);
1245 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
)
1247 RegCloseKey(This
->langkey
);
1248 This
->langkey
= NULL
;
1251 ++(This
->lang_index
);
1255 static const GUID
* tipcats
[3] = { &GUID_TFCAT_TIP_KEYBOARD
,
1256 &GUID_TFCAT_TIP_SPEECH
,
1257 &GUID_TFCAT_TIP_HANDWRITING
};
1258 res
= CLSIDFromString(profileid
, &profile
);
1259 if (FAILED(res
)) return 0;
1261 tflp
->clsid
= clsid
;
1262 tflp
->langid
= This
->langid
;
1263 tflp
->fActive
= get_active_textservice(&clsid
, NULL
);
1264 tflp
->guidProfile
= profile
;
1265 if (ITfCategoryMgr_FindClosestCategory(This
->catmgr
, &clsid
,
1266 &tflp
->catid
, tipcats
, 3) != S_OK
)
1267 ITfCategoryMgr_FindClosestCategory(This
->catmgr
, &clsid
,
1268 &tflp
->catid
, NULL
, 0);
1274 static HRESULT WINAPI
EnumTfLanguageProfiles_Next(IEnumTfLanguageProfiles
*iface
,
1275 ULONG ulCount
, TF_LANGUAGEPROFILE
*pProfile
, ULONG
*pcFetch
)
1277 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1280 TRACE("(%p)\n",This
);
1282 if (pProfile
== NULL
) return E_POINTER
;
1284 if (This
->tipkey
) while (fetched
< ulCount
)
1291 res
= RegEnumKeyExW(This
->tipkey
, This
->tip_index
,
1292 This
->szwCurrentClsid
, &cName
, NULL
, NULL
, NULL
, NULL
);
1293 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
) break;
1294 ++(This
->tip_index
);
1295 hr
= CLSIDFromString(This
->szwCurrentClsid
, &clsid
);
1296 if (FAILED(hr
)) continue;
1298 while ( fetched
< ulCount
)
1300 INT res
= next_LanguageProfile(This
, clsid
, pProfile
);
1313 if (pcFetch
) *pcFetch
= fetched
;
1314 return fetched
== ulCount
? S_OK
: S_FALSE
;
1317 static HRESULT WINAPI
EnumTfLanguageProfiles_Skip( IEnumTfLanguageProfiles
* iface
, ULONG celt
)
1319 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1320 FIXME("STUB (%p)\n",This
);
1324 static HRESULT WINAPI
EnumTfLanguageProfiles_Reset( IEnumTfLanguageProfiles
* iface
)
1326 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1327 TRACE("(%p)\n",This
);
1328 This
->tip_index
= 0;
1330 RegCloseKey(This
->langkey
);
1331 This
->langkey
= NULL
;
1332 This
->lang_index
= 0;
1336 static HRESULT WINAPI
EnumTfLanguageProfiles_Clone( IEnumTfLanguageProfiles
*iface
,
1337 IEnumTfLanguageProfiles
**ppenum
)
1339 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1342 TRACE("(%p)\n",This
);
1344 if (ppenum
== NULL
) return E_POINTER
;
1346 res
= EnumTfLanguageProfiles_Constructor(This
->langid
, ppenum
);
1349 EnumTfLanguageProfiles
*new_This
= (EnumTfLanguageProfiles
*)*ppenum
;
1350 new_This
->tip_index
= This
->tip_index
;
1351 lstrcpynW(new_This
->szwCurrentClsid
,This
->szwCurrentClsid
,39);
1356 static const WCHAR fmt
[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
1358 sprintfW(fullkey
,fmt
,This
->szwCurrentClsid
,szwLngp
,This
->langid
);
1359 res
= RegOpenKeyExW(new_This
->tipkey
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &This
->langkey
);
1360 new_This
->lang_index
= This
->lang_index
;
1366 static const IEnumTfLanguageProfilesVtbl EnumTfLanguageProfilesVtbl
=
1368 EnumTfLanguageProfiles_QueryInterface
,
1369 EnumTfLanguageProfiles_AddRef
,
1370 EnumTfLanguageProfiles_Release
,
1371 EnumTfLanguageProfiles_Clone
,
1372 EnumTfLanguageProfiles_Next
,
1373 EnumTfLanguageProfiles_Reset
,
1374 EnumTfLanguageProfiles_Skip
1377 static HRESULT
EnumTfLanguageProfiles_Constructor(LANGID langid
, IEnumTfLanguageProfiles
**ppOut
)
1380 EnumTfLanguageProfiles
*This
;
1382 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(EnumTfLanguageProfiles
));
1384 return E_OUTOFMEMORY
;
1386 This
->IEnumTfLanguageProfiles_iface
.lpVtbl
= &EnumTfLanguageProfilesVtbl
;
1388 This
->langid
= langid
;
1390 hr
= CategoryMgr_Constructor(NULL
,(IUnknown
**)&This
->catmgr
);
1393 HeapFree(GetProcessHeap(),0,This
);
1397 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
, szwSystemTIPKey
, 0, NULL
, 0,
1398 KEY_READ
| KEY_WRITE
, NULL
, &This
->tipkey
, NULL
) != ERROR_SUCCESS
)
1400 HeapFree(GetProcessHeap(), 0, This
);
1404 *ppOut
= &This
->IEnumTfLanguageProfiles_iface
;
1405 TRACE("returning %p\n", *ppOut
);