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
21 #include "msctf_internal.h"
23 static const WCHAR szwLngp
[] = {'L','a','n','g','u','a','g','e','P','r','o','f','i','l','e',0};
24 static const WCHAR szwEnable
[] = {'E','n','a','b','l','e',0};
25 static const WCHAR szwTipfmt
[] = {'%','s','\\','%','s',0};
26 static const WCHAR szwFullLangfmt
[] = {'%','s','\\','%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
28 static const WCHAR szwAssemblies
[] = {'A','s','s','e','m','b','l','i','e','s',0};
29 static const WCHAR szwDefault
[] = {'D','e','f','a','u','l','t',0};
30 static const WCHAR szwProfile
[] = {'P','r','o','f','i','l','e',0};
31 static const WCHAR szwDefaultFmt
[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
33 typedef struct tagInputProcessorProfilesSink
{
36 /* InputProcessorProfile Sinks */
38 ITfLanguageProfileNotifySink
*pITfLanguageProfileNotifySink
;
40 } InputProcessorProfilesSink
;
42 typedef struct tagInputProcessorProfiles
{
43 ITfInputProcessorProfiles ITfInputProcessorProfiles_iface
;
44 ITfSource ITfSource_iface
;
45 ITfInputProcessorProfileMgr ITfInputProcessorProfileMgr_iface
;
46 /* const ITfInputProcessorProfilesExVtbl *InputProcessorProfilesExVtbl; */
47 /* const ITfInputProcessorProfileSubstituteLayoutVtbl *InputProcessorProfileSubstituteLayoutVtbl; */
50 LANGID currentLanguage
;
52 struct list LanguageProfileNotifySink
;
53 } InputProcessorProfiles
;
55 typedef struct tagProfilesEnumGuid
{
56 IEnumGUID IEnumGUID_iface
;
63 typedef struct tagEnumTfLanguageProfiles
{
64 IEnumTfLanguageProfiles IEnumTfLanguageProfiles_iface
;
69 WCHAR szwCurrentClsid
[39];
75 ITfCategoryMgr
*catmgr
;
76 } EnumTfLanguageProfiles
;
79 IEnumTfInputProcessorProfiles IEnumTfInputProcessorProfiles_iface
;
81 } EnumTfInputProcessorProfiles
;
83 static HRESULT
ProfilesEnumGuid_Constructor(IEnumGUID
**ppOut
);
84 static HRESULT
EnumTfLanguageProfiles_Constructor(LANGID langid
, IEnumTfLanguageProfiles
**ppOut
);
86 static inline EnumTfInputProcessorProfiles
*impl_from_IEnumTfInputProcessorProfiles(IEnumTfInputProcessorProfiles
*iface
)
88 return CONTAINING_RECORD(iface
, EnumTfInputProcessorProfiles
, IEnumTfInputProcessorProfiles_iface
);
91 static HRESULT WINAPI
EnumTfInputProcessorProfiles_QueryInterface(IEnumTfInputProcessorProfiles
*iface
,
92 REFIID riid
, void **ppv
)
94 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
96 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
97 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
98 *ppv
= &This
->IEnumTfInputProcessorProfiles_iface
;
99 }else if(IsEqualGUID(riid
, &IID_IEnumTfInputProcessorProfiles
)) {
100 TRACE("(%p)->(IID_IEnumTfInputProcessorProfiles %p)\n", This
, ppv
);
101 *ppv
= &This
->IEnumTfInputProcessorProfiles_iface
;
104 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
105 return E_NOINTERFACE
;
108 IUnknown_AddRef((IUnknown
*)*ppv
);
112 static ULONG WINAPI
EnumTfInputProcessorProfiles_AddRef(IEnumTfInputProcessorProfiles
*iface
)
114 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
115 LONG ref
= InterlockedIncrement(&This
->ref
);
117 TRACE("(%p) ref=%d\n", This
, ref
);
122 static ULONG WINAPI
EnumTfInputProcessorProfiles_Release(IEnumTfInputProcessorProfiles
*iface
)
124 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
125 LONG ref
= InterlockedDecrement(&This
->ref
);
127 TRACE("(%p) ref=%d\n", This
, ref
);
130 HeapFree(GetProcessHeap(), 0, This
);
135 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Clone(IEnumTfInputProcessorProfiles
*iface
,
136 IEnumTfInputProcessorProfiles
**ret
)
138 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
139 FIXME("(%p)->(%p)\n", This
, ret
);
143 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Next(IEnumTfInputProcessorProfiles
*iface
, ULONG count
,
144 TF_INPUTPROCESSORPROFILE
*profile
, ULONG
*fetch
)
146 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
148 FIXME("(%p)->(%u %p %p)\n", This
, count
, profile
, fetch
);
155 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Reset(IEnumTfInputProcessorProfiles
*iface
)
157 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
158 FIXME("(%p)\n", This
);
162 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Skip(IEnumTfInputProcessorProfiles
*iface
, ULONG count
)
164 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
165 FIXME("(%p)->(%u)\n", This
, count
);
169 static const IEnumTfInputProcessorProfilesVtbl EnumTfInputProcessorProfilesVtbl
= {
170 EnumTfInputProcessorProfiles_QueryInterface
,
171 EnumTfInputProcessorProfiles_AddRef
,
172 EnumTfInputProcessorProfiles_Release
,
173 EnumTfInputProcessorProfiles_Clone
,
174 EnumTfInputProcessorProfiles_Next
,
175 EnumTfInputProcessorProfiles_Reset
,
176 EnumTfInputProcessorProfiles_Skip
179 static inline InputProcessorProfiles
*impl_from_ITfInputProcessorProfiles(ITfInputProcessorProfiles
*iface
)
181 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfInputProcessorProfiles_iface
);
184 static inline InputProcessorProfiles
*impl_from_ITfSource(ITfSource
*iface
)
186 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfSource_iface
);
189 static inline ProfilesEnumGuid
*impl_from_IEnumGUID(IEnumGUID
*iface
)
191 return CONTAINING_RECORD(iface
, ProfilesEnumGuid
, IEnumGUID_iface
);
194 static inline EnumTfLanguageProfiles
*impl_from_IEnumTfLanguageProfiles(IEnumTfLanguageProfiles
*iface
)
196 return CONTAINING_RECORD(iface
, EnumTfLanguageProfiles
, IEnumTfLanguageProfiles_iface
);
199 static void free_sink(InputProcessorProfilesSink
*sink
)
201 IUnknown_Release(sink
->interfaces
.pIUnknown
);
202 HeapFree(GetProcessHeap(),0,sink
);
205 static void InputProcessorProfiles_Destructor(InputProcessorProfiles
*This
)
207 struct list
*cursor
, *cursor2
;
208 TRACE("destroying %p\n", This
);
211 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->LanguageProfileNotifySink
)
213 InputProcessorProfilesSink
* sink
= LIST_ENTRY(cursor
,InputProcessorProfilesSink
,entry
);
218 HeapFree(GetProcessHeap(),0,This
);
221 static void add_userkey( REFCLSID rclsid
, LANGID langid
,
228 DWORD disposition
= 0;
233 StringFromGUID2(rclsid
, buf
, 39);
234 StringFromGUID2(guidProfile
, buf2
, 39);
235 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
237 res
= RegCreateKeyExW(HKEY_CURRENT_USER
,fullkey
, 0, NULL
, 0,
238 KEY_READ
| KEY_WRITE
, NULL
, &key
, &disposition
);
240 if (!res
&& disposition
== REG_CREATED_NEW_KEY
)
243 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&zero
, sizeof(DWORD
));
250 static HRESULT WINAPI
InputProcessorProfiles_QueryInterface(ITfInputProcessorProfiles
*iface
, REFIID iid
, void **ppv
)
252 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
254 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfInputProcessorProfiles
))
256 *ppv
= &This
->ITfInputProcessorProfiles_iface
;
258 else if (IsEqualIID(iid
, &IID_ITfInputProcessorProfileMgr
))
260 *ppv
= &This
->ITfInputProcessorProfileMgr_iface
;
262 else if (IsEqualIID(iid
, &IID_ITfSource
))
264 *ppv
= &This
->ITfSource_iface
;
269 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
270 return E_NOINTERFACE
;
273 ITfInputProcessorProfiles_AddRef(iface
);
277 static ULONG WINAPI
InputProcessorProfiles_AddRef(ITfInputProcessorProfiles
*iface
)
279 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
280 return InterlockedIncrement(&This
->refCount
);
283 static ULONG WINAPI
InputProcessorProfiles_Release(ITfInputProcessorProfiles
*iface
)
285 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
288 ret
= InterlockedDecrement(&This
->refCount
);
290 InputProcessorProfiles_Destructor(This
);
294 /*****************************************************
295 * ITfInputProcessorProfiles functions
296 *****************************************************/
297 static HRESULT WINAPI
InputProcessorProfiles_Register(
298 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
)
300 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
305 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
307 StringFromGUID2(rclsid
, buf
, 39);
308 sprintfW(fullkey
,szwTipfmt
,szwSystemTIPKey
,buf
);
310 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,fullkey
, 0, NULL
, 0,
311 KEY_READ
| KEY_WRITE
, NULL
, &tipkey
, NULL
) != ERROR_SUCCESS
)
319 static HRESULT WINAPI
InputProcessorProfiles_Unregister(
320 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
)
322 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
326 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
328 StringFromGUID2(rclsid
, buf
, 39);
329 sprintfW(fullkey
,szwTipfmt
,szwSystemTIPKey
,buf
);
331 SHDeleteKeyW(HKEY_LOCAL_MACHINE
, fullkey
);
332 SHDeleteKeyW(HKEY_CURRENT_USER
, fullkey
);
337 static HRESULT WINAPI
InputProcessorProfiles_AddLanguageProfile(
338 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
,
339 LANGID langid
, REFGUID guidProfile
, const WCHAR
*pchDesc
,
340 ULONG cchDesc
, const WCHAR
*pchIconFile
, ULONG cchFile
,
343 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
348 DWORD disposition
= 0;
350 static const WCHAR fmt2
[] = {'%','s','\\','0','x','%','0','8','x','\\','%','s',0};
351 static const WCHAR desc
[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
352 static const WCHAR icnf
[] = {'I','c','o','n','F','i','l','e',0};
353 static const WCHAR icni
[] = {'I','c','o','n','I','n','d','e','x',0};
355 TRACE("(%p) %s %x %s %s %s %i\n",This
,debugstr_guid(rclsid
), langid
,
356 debugstr_guid(guidProfile
), debugstr_wn(pchDesc
,cchDesc
),
357 debugstr_wn(pchIconFile
,cchFile
),uIconIndex
);
359 StringFromGUID2(rclsid
, buf
, 39);
360 sprintfW(fullkey
,szwTipfmt
,szwSystemTIPKey
,buf
);
362 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,fullkey
, 0, KEY_READ
| KEY_WRITE
,
363 &tipkey
) != ERROR_SUCCESS
)
366 StringFromGUID2(guidProfile
, buf
, 39);
367 sprintfW(fullkey
,fmt2
,szwLngp
,langid
,buf
);
369 res
= RegCreateKeyExW(tipkey
,fullkey
, 0, NULL
, 0, KEY_READ
| KEY_WRITE
,
370 NULL
, &fmtkey
, &disposition
);
375 RegSetValueExW(fmtkey
, desc
, 0, REG_SZ
, (const BYTE
*)pchDesc
, cchDesc
* sizeof(WCHAR
));
376 RegSetValueExW(fmtkey
, icnf
, 0, REG_SZ
, (const BYTE
*)pchIconFile
, cchFile
* sizeof(WCHAR
));
377 RegSetValueExW(fmtkey
, icni
, 0, REG_DWORD
, (LPBYTE
)&uIconIndex
, sizeof(DWORD
));
378 if (disposition
== REG_CREATED_NEW_KEY
)
379 RegSetValueExW(fmtkey
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&zero
, sizeof(DWORD
));
382 add_userkey(rclsid
, langid
, guidProfile
);
392 static HRESULT WINAPI
InputProcessorProfiles_RemoveLanguageProfile(
393 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
396 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
397 FIXME("STUB:(%p)\n",This
);
401 static HRESULT WINAPI
InputProcessorProfiles_EnumInputProcessorInfo(
402 ITfInputProcessorProfiles
*iface
, IEnumGUID
**ppEnum
)
404 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
405 TRACE("(%p) %p\n",This
,ppEnum
);
406 return ProfilesEnumGuid_Constructor(ppEnum
);
409 static HRESULT WINAPI
InputProcessorProfiles_GetDefaultLanguageProfile(
410 ITfInputProcessorProfiles
*iface
, LANGID langid
, REFGUID catid
,
411 CLSID
*pclsid
, GUID
*pguidProfile
)
413 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
420 TRACE("%p) %x %s %p %p\n",This
, langid
, debugstr_guid(catid
),pclsid
,pguidProfile
);
422 if (!catid
|| !pclsid
|| !pguidProfile
)
425 StringFromGUID2(catid
, buf
, 39);
426 sprintfW(fullkey
, szwDefaultFmt
, szwSystemCTFKey
, szwAssemblies
, langid
, buf
);
428 if (RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
,
429 &hkey
) != ERROR_SUCCESS
)
433 res
= RegQueryValueExW(hkey
, szwDefault
, 0, NULL
, (LPBYTE
)buf
, &count
);
434 if (res
!= ERROR_SUCCESS
)
439 CLSIDFromString(buf
,pclsid
);
441 res
= RegQueryValueExW(hkey
, szwProfile
, 0, NULL
, (LPBYTE
)buf
, &count
);
442 if (res
== ERROR_SUCCESS
)
443 CLSIDFromString(buf
,pguidProfile
);
450 static HRESULT WINAPI
InputProcessorProfiles_SetDefaultLanguageProfile(
451 ITfInputProcessorProfiles
*iface
, LANGID langid
, REFCLSID rclsid
,
452 REFGUID guidProfiles
)
454 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
460 ITfCategoryMgr
*catmgr
;
461 static const GUID
* tipcats
[3] = { &GUID_TFCAT_TIP_KEYBOARD
,
462 &GUID_TFCAT_TIP_SPEECH
,
463 &GUID_TFCAT_TIP_HANDWRITING
};
465 TRACE("%p) %x %s %s\n",This
, langid
, debugstr_guid(rclsid
),debugstr_guid(guidProfiles
));
467 if (!rclsid
|| !guidProfiles
)
470 hr
= CategoryMgr_Constructor(NULL
,(IUnknown
**)&catmgr
);
475 if (ITfCategoryMgr_FindClosestCategory(catmgr
, rclsid
,
476 &catid
, tipcats
, 3) != S_OK
)
477 hr
= ITfCategoryMgr_FindClosestCategory(catmgr
, rclsid
,
479 ITfCategoryMgr_Release(catmgr
);
484 StringFromGUID2(&catid
, buf
, 39);
485 sprintfW(fullkey
, szwDefaultFmt
, szwSystemCTFKey
, szwAssemblies
, langid
, buf
);
487 if (RegCreateKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, NULL
, 0, KEY_READ
| KEY_WRITE
,
488 NULL
, &hkey
, NULL
) != ERROR_SUCCESS
)
491 StringFromGUID2(rclsid
, buf
, 39);
492 RegSetValueExW(hkey
, szwDefault
, 0, REG_SZ
, (LPBYTE
)buf
, sizeof(buf
));
493 StringFromGUID2(guidProfiles
, buf
, 39);
494 RegSetValueExW(hkey
, szwProfile
, 0, REG_SZ
, (LPBYTE
)buf
, sizeof(buf
));
500 static HRESULT WINAPI
InputProcessorProfiles_ActivateLanguageProfile(
501 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
502 REFGUID guidProfiles
)
504 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
507 TF_LANGUAGEPROFILE LanguageProfile
;
509 TRACE("(%p) %s %x %s\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfiles
));
511 if (langid
!= This
->currentLanguage
) return E_INVALIDARG
;
513 if (get_active_textservice(rclsid
,NULL
))
515 TRACE("Already Active\n");
519 hr
= ITfInputProcessorProfiles_IsEnabledLanguageProfile(iface
, rclsid
,
520 langid
, guidProfiles
, &enabled
);
521 if (FAILED(hr
) || !enabled
)
523 TRACE("Not Enabled\n");
527 LanguageProfile
.clsid
= *rclsid
;
528 LanguageProfile
.langid
= langid
;
529 LanguageProfile
.guidProfile
= *guidProfiles
;
530 LanguageProfile
.fActive
= TRUE
;
532 return add_active_textservice(&LanguageProfile
);
535 static HRESULT WINAPI
InputProcessorProfiles_GetActiveLanguageProfile(
536 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID
*plangid
,
539 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
540 TF_LANGUAGEPROFILE profile
;
542 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(rclsid
),plangid
,pguidProfile
);
544 if (!rclsid
|| !plangid
|| !pguidProfile
)
547 if (get_active_textservice(rclsid
, &profile
))
549 *plangid
= profile
.langid
;
550 *pguidProfile
= profile
.guidProfile
;
555 *pguidProfile
= GUID_NULL
;
560 static HRESULT WINAPI
InputProcessorProfiles_GetLanguageProfileDescription(
561 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
562 REFGUID guidProfile
, BSTR
*pbstrProfile
)
564 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
565 FIXME("STUB:(%p)\n",This
);
569 static HRESULT WINAPI
InputProcessorProfiles_GetCurrentLanguage(
570 ITfInputProcessorProfiles
*iface
, LANGID
*plangid
)
572 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
573 TRACE("(%p) 0x%x\n",This
,This
->currentLanguage
);
578 *plangid
= This
->currentLanguage
;
583 static HRESULT WINAPI
InputProcessorProfiles_ChangeCurrentLanguage(
584 ITfInputProcessorProfiles
*iface
, LANGID langid
)
586 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
590 FIXME("STUB:(%p)\n",This
);
592 LIST_FOR_EACH(cursor
, &This
->LanguageProfileNotifySink
)
594 InputProcessorProfilesSink
* sink
= LIST_ENTRY(cursor
,InputProcessorProfilesSink
,entry
);
596 ITfLanguageProfileNotifySink_OnLanguageChange(sink
->interfaces
.pITfLanguageProfileNotifySink
, langid
, &accept
);
601 /* TODO: On successful language change call OnLanguageChanged sink */
605 static HRESULT WINAPI
InputProcessorProfiles_GetLanguageList(
606 ITfInputProcessorProfiles
*iface
, LANGID
**ppLangId
, ULONG
*pulCount
)
608 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
609 FIXME("Semi-STUB:(%p)\n",This
);
610 *ppLangId
= CoTaskMemAlloc(sizeof(LANGID
));
611 **ppLangId
= This
->currentLanguage
;
616 static HRESULT WINAPI
InputProcessorProfiles_EnumLanguageProfiles(
617 ITfInputProcessorProfiles
*iface
, LANGID langid
,
618 IEnumTfLanguageProfiles
**ppEnum
)
620 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
621 TRACE("(%p) %x %p\n",This
,langid
,ppEnum
);
622 return EnumTfLanguageProfiles_Constructor(langid
, ppEnum
);
625 static HRESULT WINAPI
InputProcessorProfiles_EnableLanguageProfile(
626 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
627 REFGUID guidProfile
, BOOL fEnable
)
629 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
636 TRACE("(%p) %s %x %s %i\n",This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
), fEnable
);
638 StringFromGUID2(rclsid
, buf
, 39);
639 StringFromGUID2(guidProfile
, buf2
, 39);
640 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
642 res
= RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
646 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&fEnable
, sizeof(DWORD
));
655 static HRESULT WINAPI
InputProcessorProfiles_IsEnabledLanguageProfile(
656 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
657 REFGUID guidProfile
, BOOL
*pfEnable
)
659 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
666 TRACE("(%p) %s, %i, %s, %p\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfile
),pfEnable
);
671 StringFromGUID2(rclsid
, buf
, 39);
672 StringFromGUID2(guidProfile
, buf2
, 39);
673 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
675 res
= RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
679 DWORD count
= sizeof(DWORD
);
680 res
= RegQueryValueExW(key
, szwEnable
, 0, NULL
, (LPBYTE
)pfEnable
, &count
);
684 if (res
) /* Try Default */
686 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
690 DWORD count
= sizeof(DWORD
);
691 res
= RegQueryValueExW(key
, szwEnable
, 0, NULL
, (LPBYTE
)pfEnable
, &count
);
702 static HRESULT WINAPI
InputProcessorProfiles_EnableLanguageProfileByDefault(
703 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
704 REFGUID guidProfile
, BOOL fEnable
)
706 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
713 TRACE("(%p) %s %x %s %i\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfile
),fEnable
);
715 StringFromGUID2(rclsid
, buf
, 39);
716 StringFromGUID2(guidProfile
, buf2
, 39);
717 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
719 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
723 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&fEnable
, sizeof(DWORD
));
732 static HRESULT WINAPI
InputProcessorProfiles_SubstituteKeyboardLayout(
733 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
734 REFGUID guidProfile
, HKL hKL
)
736 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
737 FIXME("STUB:(%p)\n",This
);
741 static const ITfInputProcessorProfilesVtbl InputProcessorProfilesVtbl
=
743 InputProcessorProfiles_QueryInterface
,
744 InputProcessorProfiles_AddRef
,
745 InputProcessorProfiles_Release
,
746 InputProcessorProfiles_Register
,
747 InputProcessorProfiles_Unregister
,
748 InputProcessorProfiles_AddLanguageProfile
,
749 InputProcessorProfiles_RemoveLanguageProfile
,
750 InputProcessorProfiles_EnumInputProcessorInfo
,
751 InputProcessorProfiles_GetDefaultLanguageProfile
,
752 InputProcessorProfiles_SetDefaultLanguageProfile
,
753 InputProcessorProfiles_ActivateLanguageProfile
,
754 InputProcessorProfiles_GetActiveLanguageProfile
,
755 InputProcessorProfiles_GetLanguageProfileDescription
,
756 InputProcessorProfiles_GetCurrentLanguage
,
757 InputProcessorProfiles_ChangeCurrentLanguage
,
758 InputProcessorProfiles_GetLanguageList
,
759 InputProcessorProfiles_EnumLanguageProfiles
,
760 InputProcessorProfiles_EnableLanguageProfile
,
761 InputProcessorProfiles_IsEnabledLanguageProfile
,
762 InputProcessorProfiles_EnableLanguageProfileByDefault
,
763 InputProcessorProfiles_SubstituteKeyboardLayout
766 static inline InputProcessorProfiles
*impl_from_ITfInputProcessorProfileMgr(ITfInputProcessorProfileMgr
*iface
)
768 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfInputProcessorProfileMgr_iface
);
771 static HRESULT WINAPI
InputProcessorProfileMgr_QueryInterface(ITfInputProcessorProfileMgr
*iface
, REFIID riid
, void **ppv
)
773 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
774 return ITfInputProcessorProfiles_QueryInterface(&This
->ITfInputProcessorProfiles_iface
, riid
, ppv
);
777 static ULONG WINAPI
InputProcessorProfileMgr_AddRef(ITfInputProcessorProfileMgr
*iface
)
779 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
780 return ITfInputProcessorProfiles_AddRef(&This
->ITfInputProcessorProfiles_iface
);
783 static ULONG WINAPI
InputProcessorProfileMgr_Release(ITfInputProcessorProfileMgr
*iface
)
785 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
786 return ITfInputProcessorProfiles_Release(&This
->ITfInputProcessorProfiles_iface
);
789 static HRESULT WINAPI
InputProcessorProfileMgr_ActivateProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
790 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, DWORD dwFlags
)
792 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
793 FIXME("(%p)->(%d %x %s %s %p %x)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
794 debugstr_guid(guidProfile
), hkl
, dwFlags
);
798 static HRESULT WINAPI
InputProcessorProfileMgr_DeactivateProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
799 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, DWORD dwFlags
)
801 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
802 FIXME("(%p)->(%d %x %s %s %p %x)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
803 debugstr_guid(guidProfile
), hkl
, dwFlags
);
807 static HRESULT WINAPI
InputProcessorProfileMgr_GetProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
808 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, TF_INPUTPROCESSORPROFILE
*pProfile
)
810 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
811 FIXME("(%p)->(%d %x %s %s %p %p)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
812 debugstr_guid(guidProfile
), hkl
, pProfile
);
816 static HRESULT WINAPI
InputProcessorProfileMgr_EnumProfiles(ITfInputProcessorProfileMgr
*iface
, LANGID langid
,
817 IEnumTfInputProcessorProfiles
**ppEnum
)
819 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
820 EnumTfInputProcessorProfiles
*enum_profiles
;
822 TRACE("(%p)->(%x %p)\n", This
, langid
, ppEnum
);
824 enum_profiles
= HeapAlloc(GetProcessHeap(), 0, sizeof(*enum_profiles
));
826 return E_OUTOFMEMORY
;
828 enum_profiles
->IEnumTfInputProcessorProfiles_iface
.lpVtbl
= &EnumTfInputProcessorProfilesVtbl
;
829 enum_profiles
->ref
= 1;
831 *ppEnum
= &enum_profiles
->IEnumTfInputProcessorProfiles_iface
;
835 static HRESULT WINAPI
InputProcessorProfileMgr_ReleaseInputProcessor(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
838 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
839 FIXME("(%p)->(%s %x)\n", This
, debugstr_guid(rclsid
), dwFlags
);
843 static HRESULT WINAPI
InputProcessorProfileMgr_RegisterProfile(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
844 LANGID langid
, REFGUID guidProfile
, const WCHAR
*pchDesc
, ULONG cchDesc
, const WCHAR
*pchIconFile
,
845 ULONG cchFile
, ULONG uIconIndex
, HKL hklsubstitute
, DWORD dwPreferredLayout
, BOOL bEnabledByDefault
,
848 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
849 FIXME("(%p)->(%s %x %s %s %d %s %u %u %p %x %x %x)\n", This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
),
850 debugstr_w(pchDesc
), cchDesc
, debugstr_w(pchIconFile
), cchFile
, uIconIndex
, hklsubstitute
, dwPreferredLayout
,
851 bEnabledByDefault
, dwFlags
);
855 static HRESULT WINAPI
InputProcessorProfileMgr_UnregisterProfile(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
856 LANGID langid
, REFGUID guidProfile
, DWORD dwFlags
)
858 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
859 FIXME("(%p)->(%s %x %s %x)\n", This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
), dwFlags
);
863 static HRESULT WINAPI
InputProcessorProfileMgr_GetActiveProfile(ITfInputProcessorProfileMgr
*iface
, REFGUID catid
,
864 TF_INPUTPROCESSORPROFILE
*pProfile
)
866 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
867 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(catid
), pProfile
);
871 static const ITfInputProcessorProfileMgrVtbl InputProcessorProfileMgrVtbl
= {
872 InputProcessorProfileMgr_QueryInterface
,
873 InputProcessorProfileMgr_AddRef
,
874 InputProcessorProfileMgr_Release
,
875 InputProcessorProfileMgr_ActivateProfile
,
876 InputProcessorProfileMgr_DeactivateProfile
,
877 InputProcessorProfileMgr_GetProfile
,
878 InputProcessorProfileMgr_EnumProfiles
,
879 InputProcessorProfileMgr_ReleaseInputProcessor
,
880 InputProcessorProfileMgr_RegisterProfile
,
881 InputProcessorProfileMgr_UnregisterProfile
,
882 InputProcessorProfileMgr_GetActiveProfile
885 /*****************************************************
886 * ITfSource functions
887 *****************************************************/
888 static HRESULT WINAPI
IPPSource_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
890 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
891 return ITfInputProcessorProfiles_QueryInterface(&This
->ITfInputProcessorProfiles_iface
, iid
, ppvOut
);
894 static ULONG WINAPI
IPPSource_AddRef(ITfSource
*iface
)
896 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
897 return ITfInputProcessorProfiles_AddRef(&This
->ITfInputProcessorProfiles_iface
);
900 static ULONG WINAPI
IPPSource_Release(ITfSource
*iface
)
902 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
903 return ITfInputProcessorProfiles_Release(&This
->ITfInputProcessorProfiles_iface
);
906 static HRESULT WINAPI
IPPSource_AdviseSink(ITfSource
*iface
,
907 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
909 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
910 InputProcessorProfilesSink
*ipps
;
912 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
914 if (!riid
|| !punk
|| !pdwCookie
)
917 if (IsEqualIID(riid
, &IID_ITfLanguageProfileNotifySink
))
919 ipps
= HeapAlloc(GetProcessHeap(),0,sizeof(InputProcessorProfilesSink
));
921 return E_OUTOFMEMORY
;
922 if (FAILED(IUnknown_QueryInterface(punk
, riid
, (LPVOID
*)&ipps
->interfaces
.pITfLanguageProfileNotifySink
)))
924 HeapFree(GetProcessHeap(),0,ipps
);
925 return CONNECT_E_CANNOTCONNECT
;
927 list_add_head(&This
->LanguageProfileNotifySink
,&ipps
->entry
);
928 *pdwCookie
= generate_Cookie(COOKIE_MAGIC_IPPSINK
, ipps
);
932 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
936 TRACE("cookie %x\n",*pdwCookie
);
941 static HRESULT WINAPI
IPPSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
943 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
944 InputProcessorProfilesSink
*sink
;
946 TRACE("(%p) %x\n",This
,pdwCookie
);
948 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_IPPSINK
)
951 sink
= remove_Cookie(pdwCookie
);
953 return CONNECT_E_NOCONNECTION
;
955 list_remove(&sink
->entry
);
961 static const ITfSourceVtbl InputProcessorProfilesSourceVtbl
=
963 IPPSource_QueryInterface
,
966 IPPSource_AdviseSink
,
967 IPPSource_UnadviseSink
,
970 HRESULT
InputProcessorProfiles_Constructor(IUnknown
*pUnkOuter
, IUnknown
**ppOut
)
972 InputProcessorProfiles
*This
;
974 return CLASS_E_NOAGGREGATION
;
976 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(InputProcessorProfiles
));
978 return E_OUTOFMEMORY
;
980 This
->ITfInputProcessorProfiles_iface
.lpVtbl
= &InputProcessorProfilesVtbl
;
981 This
->ITfSource_iface
.lpVtbl
= &InputProcessorProfilesSourceVtbl
;
982 This
->ITfInputProcessorProfileMgr_iface
.lpVtbl
= &InputProcessorProfileMgrVtbl
;
984 This
->currentLanguage
= GetUserDefaultLCID();
986 list_init(&This
->LanguageProfileNotifySink
);
988 *ppOut
= (IUnknown
*)&This
->ITfInputProcessorProfiles_iface
;
989 TRACE("returning %p\n", *ppOut
);
993 /**************************************************
994 * IEnumGUID implementation for ITfInputProcessorProfiles::EnumInputProcessorInfo
995 **************************************************/
996 static void ProfilesEnumGuid_Destructor(ProfilesEnumGuid
*This
)
998 TRACE("destroying %p\n", This
);
999 RegCloseKey(This
->key
);
1000 HeapFree(GetProcessHeap(),0,This
);
1003 static HRESULT WINAPI
ProfilesEnumGuid_QueryInterface(IEnumGUID
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1005 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1008 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumGUID
))
1010 *ppvOut
= &This
->IEnumGUID_iface
;
1015 IEnumGUID_AddRef(iface
);
1019 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
1020 return E_NOINTERFACE
;
1023 static ULONG WINAPI
ProfilesEnumGuid_AddRef(IEnumGUID
*iface
)
1025 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1026 return InterlockedIncrement(&This
->refCount
);
1029 static ULONG WINAPI
ProfilesEnumGuid_Release(IEnumGUID
*iface
)
1031 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1034 ret
= InterlockedDecrement(&This
->refCount
);
1036 ProfilesEnumGuid_Destructor(This
);
1040 /*****************************************************
1041 * IEnumGuid functions
1042 *****************************************************/
1043 static HRESULT WINAPI
ProfilesEnumGuid_Next( LPENUMGUID iface
,
1044 ULONG celt
, GUID
*rgelt
, ULONG
*pceltFetched
)
1046 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1049 TRACE("(%p)\n",This
);
1051 if (rgelt
== NULL
) return E_POINTER
;
1053 if (This
->key
) while (fetched
< celt
)
1060 res
= RegEnumKeyExW(This
->key
, This
->next_index
, catid
, &cName
,
1061 NULL
, NULL
, NULL
, NULL
);
1062 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
) break;
1063 ++(This
->next_index
);
1065 hr
= CLSIDFromString(catid
, rgelt
);
1066 if (FAILED(hr
)) continue;
1072 if (pceltFetched
) *pceltFetched
= fetched
;
1073 return fetched
== celt
? S_OK
: S_FALSE
;
1076 static HRESULT WINAPI
ProfilesEnumGuid_Skip( LPENUMGUID iface
, ULONG celt
)
1078 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1079 TRACE("(%p)\n",This
);
1081 This
->next_index
+= celt
;
1085 static HRESULT WINAPI
ProfilesEnumGuid_Reset( LPENUMGUID iface
)
1087 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1088 TRACE("(%p)\n",This
);
1089 This
->next_index
= 0;
1093 static HRESULT WINAPI
ProfilesEnumGuid_Clone( LPENUMGUID iface
,
1096 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1099 TRACE("(%p)\n",This
);
1101 if (ppenum
== NULL
) return E_POINTER
;
1103 res
= ProfilesEnumGuid_Constructor(ppenum
);
1106 ProfilesEnumGuid
*new_This
= impl_from_IEnumGUID(*ppenum
);
1107 new_This
->next_index
= This
->next_index
;
1112 static const IEnumGUIDVtbl EnumGUIDVtbl
=
1114 ProfilesEnumGuid_QueryInterface
,
1115 ProfilesEnumGuid_AddRef
,
1116 ProfilesEnumGuid_Release
,
1117 ProfilesEnumGuid_Next
,
1118 ProfilesEnumGuid_Skip
,
1119 ProfilesEnumGuid_Reset
,
1120 ProfilesEnumGuid_Clone
1123 static HRESULT
ProfilesEnumGuid_Constructor(IEnumGUID
**ppOut
)
1125 ProfilesEnumGuid
*This
;
1127 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ProfilesEnumGuid
));
1129 return E_OUTOFMEMORY
;
1131 This
->IEnumGUID_iface
.lpVtbl
= &EnumGUIDVtbl
;
1134 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
, szwSystemTIPKey
, 0, NULL
, 0,
1135 KEY_READ
| KEY_WRITE
, NULL
, &This
->key
, NULL
) != ERROR_SUCCESS
)
1137 HeapFree(GetProcessHeap(), 0, This
);
1141 *ppOut
= &This
->IEnumGUID_iface
;
1142 TRACE("returning %p\n", *ppOut
);
1146 /**************************************************
1147 * IEnumTfLanguageProfiles implementation
1148 **************************************************/
1149 static void EnumTfLanguageProfiles_Destructor(EnumTfLanguageProfiles
*This
)
1151 TRACE("destroying %p\n", This
);
1152 RegCloseKey(This
->tipkey
);
1154 RegCloseKey(This
->langkey
);
1155 ITfCategoryMgr_Release(This
->catmgr
);
1156 HeapFree(GetProcessHeap(),0,This
);
1159 static HRESULT WINAPI
EnumTfLanguageProfiles_QueryInterface(IEnumTfLanguageProfiles
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1161 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1165 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumTfLanguageProfiles
))
1167 *ppvOut
= &This
->IEnumTfLanguageProfiles_iface
;
1172 IEnumTfLanguageProfiles_AddRef(iface
);
1176 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
1177 return E_NOINTERFACE
;
1180 static ULONG WINAPI
EnumTfLanguageProfiles_AddRef(IEnumTfLanguageProfiles
*iface
)
1182 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1183 return InterlockedIncrement(&This
->refCount
);
1186 static ULONG WINAPI
EnumTfLanguageProfiles_Release(IEnumTfLanguageProfiles
*iface
)
1188 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1191 ret
= InterlockedDecrement(&This
->refCount
);
1193 EnumTfLanguageProfiles_Destructor(This
);
1197 /*****************************************************
1198 * IEnumGuid functions
1199 *****************************************************/
1200 static INT
next_LanguageProfile(EnumTfLanguageProfiles
*This
, CLSID clsid
, TF_LANGUAGEPROFILE
*tflp
)
1204 WCHAR profileid
[39];
1208 static const WCHAR fmt
[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
1210 if (This
->langkey
== NULL
)
1212 sprintfW(fullkey
,fmt
,This
->szwCurrentClsid
,szwLngp
,This
->langid
);
1213 res
= RegOpenKeyExW(This
->tipkey
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &This
->langkey
);
1216 This
->langkey
= NULL
;
1219 This
->lang_index
= 0;
1221 res
= RegEnumKeyExW(This
->langkey
, This
->lang_index
, profileid
, &cName
,
1222 NULL
, NULL
, NULL
, NULL
);
1223 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
)
1225 RegCloseKey(This
->langkey
);
1226 This
->langkey
= NULL
;
1229 ++(This
->lang_index
);
1233 static const GUID
* tipcats
[3] = { &GUID_TFCAT_TIP_KEYBOARD
,
1234 &GUID_TFCAT_TIP_SPEECH
,
1235 &GUID_TFCAT_TIP_HANDWRITING
};
1236 res
= CLSIDFromString(profileid
, &profile
);
1237 if (FAILED(res
)) return 0;
1239 tflp
->clsid
= clsid
;
1240 tflp
->langid
= This
->langid
;
1241 tflp
->fActive
= get_active_textservice(&clsid
, NULL
);
1242 tflp
->guidProfile
= profile
;
1243 if (ITfCategoryMgr_FindClosestCategory(This
->catmgr
, &clsid
,
1244 &tflp
->catid
, tipcats
, 3) != S_OK
)
1245 ITfCategoryMgr_FindClosestCategory(This
->catmgr
, &clsid
,
1246 &tflp
->catid
, NULL
, 0);
1252 static HRESULT WINAPI
EnumTfLanguageProfiles_Next(IEnumTfLanguageProfiles
*iface
,
1253 ULONG ulCount
, TF_LANGUAGEPROFILE
*pProfile
, ULONG
*pcFetch
)
1255 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1258 TRACE("(%p)\n",This
);
1260 if (pProfile
== NULL
) return E_POINTER
;
1262 if (This
->tipkey
) while (fetched
< ulCount
)
1269 res
= RegEnumKeyExW(This
->tipkey
, This
->tip_index
,
1270 This
->szwCurrentClsid
, &cName
, NULL
, NULL
, NULL
, NULL
);
1271 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
) break;
1272 ++(This
->tip_index
);
1273 hr
= CLSIDFromString(This
->szwCurrentClsid
, &clsid
);
1274 if (FAILED(hr
)) continue;
1276 while ( fetched
< ulCount
)
1278 INT res
= next_LanguageProfile(This
, clsid
, pProfile
);
1291 if (pcFetch
) *pcFetch
= fetched
;
1292 return fetched
== ulCount
? S_OK
: S_FALSE
;
1295 static HRESULT WINAPI
EnumTfLanguageProfiles_Skip( IEnumTfLanguageProfiles
* iface
, ULONG celt
)
1297 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1298 FIXME("STUB (%p)\n",This
);
1302 static HRESULT WINAPI
EnumTfLanguageProfiles_Reset( IEnumTfLanguageProfiles
* iface
)
1304 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1305 TRACE("(%p)\n",This
);
1306 This
->tip_index
= 0;
1308 RegCloseKey(This
->langkey
);
1309 This
->langkey
= NULL
;
1310 This
->lang_index
= 0;
1314 static HRESULT WINAPI
EnumTfLanguageProfiles_Clone( IEnumTfLanguageProfiles
*iface
,
1315 IEnumTfLanguageProfiles
**ppenum
)
1317 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1320 TRACE("(%p)\n",This
);
1322 if (ppenum
== NULL
) return E_POINTER
;
1324 res
= EnumTfLanguageProfiles_Constructor(This
->langid
, ppenum
);
1327 EnumTfLanguageProfiles
*new_This
= (EnumTfLanguageProfiles
*)*ppenum
;
1328 new_This
->tip_index
= This
->tip_index
;
1329 lstrcpynW(new_This
->szwCurrentClsid
,This
->szwCurrentClsid
,39);
1334 static const WCHAR fmt
[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
1336 sprintfW(fullkey
,fmt
,This
->szwCurrentClsid
,szwLngp
,This
->langid
);
1337 res
= RegOpenKeyExW(new_This
->tipkey
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &This
->langkey
);
1338 new_This
->lang_index
= This
->lang_index
;
1344 static const IEnumTfLanguageProfilesVtbl EnumTfLanguageProfilesVtbl
=
1346 EnumTfLanguageProfiles_QueryInterface
,
1347 EnumTfLanguageProfiles_AddRef
,
1348 EnumTfLanguageProfiles_Release
,
1349 EnumTfLanguageProfiles_Clone
,
1350 EnumTfLanguageProfiles_Next
,
1351 EnumTfLanguageProfiles_Reset
,
1352 EnumTfLanguageProfiles_Skip
1355 static HRESULT
EnumTfLanguageProfiles_Constructor(LANGID langid
, IEnumTfLanguageProfiles
**ppOut
)
1358 EnumTfLanguageProfiles
*This
;
1360 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(EnumTfLanguageProfiles
));
1362 return E_OUTOFMEMORY
;
1364 This
->IEnumTfLanguageProfiles_iface
.lpVtbl
= &EnumTfLanguageProfilesVtbl
;
1366 This
->langid
= langid
;
1368 hr
= CategoryMgr_Constructor(NULL
,(IUnknown
**)&This
->catmgr
);
1371 HeapFree(GetProcessHeap(),0,This
);
1375 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
, szwSystemTIPKey
, 0, NULL
, 0,
1376 KEY_READ
| KEY_WRITE
, NULL
, &This
->tipkey
, NULL
) != ERROR_SUCCESS
)
1378 HeapFree(GetProcessHeap(), 0, This
);
1382 *ppOut
= &This
->IEnumTfLanguageProfiles_iface
;
1383 TRACE("returning %p\n", *ppOut
);