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 tagInputProcessorProfiles
{
34 ITfInputProcessorProfiles ITfInputProcessorProfiles_iface
;
35 ITfSource ITfSource_iface
;
36 ITfInputProcessorProfileMgr ITfInputProcessorProfileMgr_iface
;
37 /* const ITfInputProcessorProfilesExVtbl *InputProcessorProfilesExVtbl; */
38 /* const ITfInputProcessorProfileSubstituteLayoutVtbl *InputProcessorProfileSubstituteLayoutVtbl; */
41 LANGID currentLanguage
;
43 struct list LanguageProfileNotifySink
;
44 } InputProcessorProfiles
;
46 typedef struct tagProfilesEnumGuid
{
47 IEnumGUID IEnumGUID_iface
;
54 typedef struct tagEnumTfLanguageProfiles
{
55 IEnumTfLanguageProfiles IEnumTfLanguageProfiles_iface
;
60 WCHAR szwCurrentClsid
[39];
66 ITfCategoryMgr
*catmgr
;
67 } EnumTfLanguageProfiles
;
70 IEnumTfInputProcessorProfiles IEnumTfInputProcessorProfiles_iface
;
72 } EnumTfInputProcessorProfiles
;
74 static HRESULT
ProfilesEnumGuid_Constructor(IEnumGUID
**ppOut
);
75 static HRESULT
EnumTfLanguageProfiles_Constructor(LANGID langid
, EnumTfLanguageProfiles
**out
);
77 static inline EnumTfInputProcessorProfiles
*impl_from_IEnumTfInputProcessorProfiles(IEnumTfInputProcessorProfiles
*iface
)
79 return CONTAINING_RECORD(iface
, EnumTfInputProcessorProfiles
, IEnumTfInputProcessorProfiles_iface
);
82 static HRESULT WINAPI
EnumTfInputProcessorProfiles_QueryInterface(IEnumTfInputProcessorProfiles
*iface
,
83 REFIID riid
, void **ppv
)
85 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
87 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
88 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
89 *ppv
= &This
->IEnumTfInputProcessorProfiles_iface
;
90 }else if(IsEqualGUID(riid
, &IID_IEnumTfInputProcessorProfiles
)) {
91 TRACE("(%p)->(IID_IEnumTfInputProcessorProfiles %p)\n", This
, ppv
);
92 *ppv
= &This
->IEnumTfInputProcessorProfiles_iface
;
95 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
99 IUnknown_AddRef((IUnknown
*)*ppv
);
103 static ULONG WINAPI
EnumTfInputProcessorProfiles_AddRef(IEnumTfInputProcessorProfiles
*iface
)
105 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
106 LONG ref
= InterlockedIncrement(&This
->ref
);
108 TRACE("(%p) ref=%d\n", This
, ref
);
113 static ULONG WINAPI
EnumTfInputProcessorProfiles_Release(IEnumTfInputProcessorProfiles
*iface
)
115 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
116 LONG ref
= InterlockedDecrement(&This
->ref
);
118 TRACE("(%p) ref=%d\n", This
, ref
);
121 HeapFree(GetProcessHeap(), 0, This
);
126 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Clone(IEnumTfInputProcessorProfiles
*iface
,
127 IEnumTfInputProcessorProfiles
**ret
)
129 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
130 FIXME("(%p)->(%p)\n", This
, ret
);
134 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Next(IEnumTfInputProcessorProfiles
*iface
, ULONG count
,
135 TF_INPUTPROCESSORPROFILE
*profile
, ULONG
*fetch
)
137 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
139 FIXME("(%p)->(%u %p %p)\n", This
, count
, profile
, fetch
);
146 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Reset(IEnumTfInputProcessorProfiles
*iface
)
148 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
149 FIXME("(%p)\n", This
);
153 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Skip(IEnumTfInputProcessorProfiles
*iface
, ULONG count
)
155 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
156 FIXME("(%p)->(%u)\n", This
, count
);
160 static const IEnumTfInputProcessorProfilesVtbl EnumTfInputProcessorProfilesVtbl
= {
161 EnumTfInputProcessorProfiles_QueryInterface
,
162 EnumTfInputProcessorProfiles_AddRef
,
163 EnumTfInputProcessorProfiles_Release
,
164 EnumTfInputProcessorProfiles_Clone
,
165 EnumTfInputProcessorProfiles_Next
,
166 EnumTfInputProcessorProfiles_Reset
,
167 EnumTfInputProcessorProfiles_Skip
170 static inline InputProcessorProfiles
*impl_from_ITfInputProcessorProfiles(ITfInputProcessorProfiles
*iface
)
172 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfInputProcessorProfiles_iface
);
175 static inline InputProcessorProfiles
*impl_from_ITfSource(ITfSource
*iface
)
177 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfSource_iface
);
180 static inline ProfilesEnumGuid
*impl_from_IEnumGUID(IEnumGUID
*iface
)
182 return CONTAINING_RECORD(iface
, ProfilesEnumGuid
, IEnumGUID_iface
);
185 static inline EnumTfLanguageProfiles
*impl_from_IEnumTfLanguageProfiles(IEnumTfLanguageProfiles
*iface
)
187 return CONTAINING_RECORD(iface
, EnumTfLanguageProfiles
, IEnumTfLanguageProfiles_iface
);
190 static void InputProcessorProfiles_Destructor(InputProcessorProfiles
*This
)
192 TRACE("destroying %p\n", This
);
194 free_sinks(&This
->LanguageProfileNotifySink
);
195 HeapFree(GetProcessHeap(),0,This
);
198 static void add_userkey( REFCLSID rclsid
, LANGID langid
,
205 DWORD disposition
= 0;
210 StringFromGUID2(rclsid
, buf
, 39);
211 StringFromGUID2(guidProfile
, buf2
, 39);
212 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
214 res
= RegCreateKeyExW(HKEY_CURRENT_USER
,fullkey
, 0, NULL
, 0,
215 KEY_READ
| KEY_WRITE
, NULL
, &key
, &disposition
);
217 if (!res
&& disposition
== REG_CREATED_NEW_KEY
)
220 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&zero
, sizeof(DWORD
));
227 static HRESULT WINAPI
InputProcessorProfiles_QueryInterface(ITfInputProcessorProfiles
*iface
, REFIID iid
, void **ppv
)
229 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
231 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfInputProcessorProfiles
))
233 *ppv
= &This
->ITfInputProcessorProfiles_iface
;
235 else if (IsEqualIID(iid
, &IID_ITfInputProcessorProfileMgr
))
237 *ppv
= &This
->ITfInputProcessorProfileMgr_iface
;
239 else if (IsEqualIID(iid
, &IID_ITfSource
))
241 *ppv
= &This
->ITfSource_iface
;
246 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
247 return E_NOINTERFACE
;
250 ITfInputProcessorProfiles_AddRef(iface
);
254 static ULONG WINAPI
InputProcessorProfiles_AddRef(ITfInputProcessorProfiles
*iface
)
256 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
257 return InterlockedIncrement(&This
->refCount
);
260 static ULONG WINAPI
InputProcessorProfiles_Release(ITfInputProcessorProfiles
*iface
)
262 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
265 ret
= InterlockedDecrement(&This
->refCount
);
267 InputProcessorProfiles_Destructor(This
);
271 /*****************************************************
272 * ITfInputProcessorProfiles functions
273 *****************************************************/
274 static HRESULT WINAPI
InputProcessorProfiles_Register(
275 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
)
277 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
282 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
284 StringFromGUID2(rclsid
, buf
, 39);
285 sprintfW(fullkey
,szwTipfmt
,szwSystemTIPKey
,buf
);
287 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,fullkey
, 0, NULL
, 0,
288 KEY_READ
| KEY_WRITE
, NULL
, &tipkey
, NULL
) != ERROR_SUCCESS
)
296 static HRESULT WINAPI
InputProcessorProfiles_Unregister(
297 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
)
299 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
303 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
305 StringFromGUID2(rclsid
, buf
, 39);
306 sprintfW(fullkey
,szwTipfmt
,szwSystemTIPKey
,buf
);
308 RegDeleteTreeW(HKEY_LOCAL_MACHINE
, fullkey
);
309 RegDeleteTreeW(HKEY_CURRENT_USER
, fullkey
);
314 static HRESULT WINAPI
InputProcessorProfiles_AddLanguageProfile(
315 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
,
316 LANGID langid
, REFGUID guidProfile
, const WCHAR
*pchDesc
,
317 ULONG cchDesc
, const WCHAR
*pchIconFile
, ULONG cchFile
,
320 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
325 DWORD disposition
= 0;
327 static const WCHAR fmt2
[] = {'%','s','\\','0','x','%','0','8','x','\\','%','s',0};
328 static const WCHAR desc
[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
329 static const WCHAR icnf
[] = {'I','c','o','n','F','i','l','e',0};
330 static const WCHAR icni
[] = {'I','c','o','n','I','n','d','e','x',0};
332 TRACE("(%p) %s %x %s %s %s %i\n",This
,debugstr_guid(rclsid
), langid
,
333 debugstr_guid(guidProfile
), debugstr_wn(pchDesc
,cchDesc
),
334 debugstr_wn(pchIconFile
,cchFile
),uIconIndex
);
336 StringFromGUID2(rclsid
, buf
, 39);
337 sprintfW(fullkey
,szwTipfmt
,szwSystemTIPKey
,buf
);
339 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,fullkey
, 0, KEY_READ
| KEY_WRITE
,
340 &tipkey
) != ERROR_SUCCESS
)
343 StringFromGUID2(guidProfile
, buf
, 39);
344 sprintfW(fullkey
,fmt2
,szwLngp
,langid
,buf
);
346 res
= RegCreateKeyExW(tipkey
,fullkey
, 0, NULL
, 0, KEY_READ
| KEY_WRITE
,
347 NULL
, &fmtkey
, &disposition
);
352 RegSetValueExW(fmtkey
, desc
, 0, REG_SZ
, (const BYTE
*)pchDesc
, cchDesc
* sizeof(WCHAR
));
353 RegSetValueExW(fmtkey
, icnf
, 0, REG_SZ
, (const BYTE
*)pchIconFile
, cchFile
* sizeof(WCHAR
));
354 RegSetValueExW(fmtkey
, icni
, 0, REG_DWORD
, (LPBYTE
)&uIconIndex
, sizeof(DWORD
));
355 if (disposition
== REG_CREATED_NEW_KEY
)
356 RegSetValueExW(fmtkey
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&zero
, sizeof(DWORD
));
359 add_userkey(rclsid
, langid
, guidProfile
);
369 static HRESULT WINAPI
InputProcessorProfiles_RemoveLanguageProfile(
370 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
373 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
374 FIXME("STUB:(%p)\n",This
);
378 static HRESULT WINAPI
InputProcessorProfiles_EnumInputProcessorInfo(
379 ITfInputProcessorProfiles
*iface
, IEnumGUID
**ppEnum
)
381 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
382 TRACE("(%p) %p\n",This
,ppEnum
);
383 return ProfilesEnumGuid_Constructor(ppEnum
);
386 static HRESULT WINAPI
InputProcessorProfiles_GetDefaultLanguageProfile(
387 ITfInputProcessorProfiles
*iface
, LANGID langid
, REFGUID catid
,
388 CLSID
*pclsid
, GUID
*pguidProfile
)
390 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
397 TRACE("%p) %x %s %p %p\n",This
, langid
, debugstr_guid(catid
),pclsid
,pguidProfile
);
399 if (!catid
|| !pclsid
|| !pguidProfile
)
402 StringFromGUID2(catid
, buf
, 39);
403 sprintfW(fullkey
, szwDefaultFmt
, szwSystemCTFKey
, szwAssemblies
, langid
, buf
);
405 if (RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
,
406 &hkey
) != ERROR_SUCCESS
)
410 res
= RegQueryValueExW(hkey
, szwDefault
, 0, NULL
, (LPBYTE
)buf
, &count
);
411 if (res
!= ERROR_SUCCESS
)
416 CLSIDFromString(buf
,pclsid
);
418 res
= RegQueryValueExW(hkey
, szwProfile
, 0, NULL
, (LPBYTE
)buf
, &count
);
419 if (res
== ERROR_SUCCESS
)
420 CLSIDFromString(buf
,pguidProfile
);
427 static HRESULT WINAPI
InputProcessorProfiles_SetDefaultLanguageProfile(
428 ITfInputProcessorProfiles
*iface
, LANGID langid
, REFCLSID rclsid
,
429 REFGUID guidProfiles
)
431 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
437 ITfCategoryMgr
*catmgr
;
438 static const GUID
* tipcats
[3] = { &GUID_TFCAT_TIP_KEYBOARD
,
439 &GUID_TFCAT_TIP_SPEECH
,
440 &GUID_TFCAT_TIP_HANDWRITING
};
442 TRACE("%p) %x %s %s\n",This
, langid
, debugstr_guid(rclsid
),debugstr_guid(guidProfiles
));
444 if (!rclsid
|| !guidProfiles
)
447 hr
= CategoryMgr_Constructor(NULL
,(IUnknown
**)&catmgr
);
452 if (ITfCategoryMgr_FindClosestCategory(catmgr
, rclsid
,
453 &catid
, tipcats
, 3) != S_OK
)
454 hr
= ITfCategoryMgr_FindClosestCategory(catmgr
, rclsid
,
456 ITfCategoryMgr_Release(catmgr
);
461 StringFromGUID2(&catid
, buf
, 39);
462 sprintfW(fullkey
, szwDefaultFmt
, szwSystemCTFKey
, szwAssemblies
, langid
, buf
);
464 if (RegCreateKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, NULL
, 0, KEY_READ
| KEY_WRITE
,
465 NULL
, &hkey
, NULL
) != ERROR_SUCCESS
)
468 StringFromGUID2(rclsid
, buf
, 39);
469 RegSetValueExW(hkey
, szwDefault
, 0, REG_SZ
, (LPBYTE
)buf
, sizeof(buf
));
470 StringFromGUID2(guidProfiles
, buf
, 39);
471 RegSetValueExW(hkey
, szwProfile
, 0, REG_SZ
, (LPBYTE
)buf
, sizeof(buf
));
477 static HRESULT WINAPI
InputProcessorProfiles_ActivateLanguageProfile(
478 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
479 REFGUID guidProfiles
)
481 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
484 TF_LANGUAGEPROFILE LanguageProfile
;
486 TRACE("(%p) %s %x %s\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfiles
));
488 if (langid
!= This
->currentLanguage
) return E_INVALIDARG
;
490 if (get_active_textservice(rclsid
,NULL
))
492 TRACE("Already Active\n");
496 hr
= ITfInputProcessorProfiles_IsEnabledLanguageProfile(iface
, rclsid
,
497 langid
, guidProfiles
, &enabled
);
498 if (FAILED(hr
) || !enabled
)
500 TRACE("Not Enabled\n");
504 LanguageProfile
.clsid
= *rclsid
;
505 LanguageProfile
.langid
= langid
;
506 LanguageProfile
.guidProfile
= *guidProfiles
;
507 LanguageProfile
.fActive
= TRUE
;
509 return add_active_textservice(&LanguageProfile
);
512 static HRESULT WINAPI
InputProcessorProfiles_GetActiveLanguageProfile(
513 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID
*plangid
,
516 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
517 TF_LANGUAGEPROFILE profile
;
519 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(rclsid
),plangid
,pguidProfile
);
521 if (!rclsid
|| !plangid
|| !pguidProfile
)
524 if (get_active_textservice(rclsid
, &profile
))
526 *plangid
= profile
.langid
;
527 *pguidProfile
= profile
.guidProfile
;
532 *pguidProfile
= GUID_NULL
;
537 static HRESULT WINAPI
InputProcessorProfiles_GetLanguageProfileDescription(
538 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
539 REFGUID guidProfile
, BSTR
*pbstrProfile
)
541 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
542 FIXME("STUB:(%p)\n",This
);
546 static HRESULT WINAPI
InputProcessorProfiles_GetCurrentLanguage(
547 ITfInputProcessorProfiles
*iface
, LANGID
*plangid
)
549 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
550 TRACE("(%p) 0x%x\n",This
,This
->currentLanguage
);
555 *plangid
= This
->currentLanguage
;
560 static HRESULT WINAPI
InputProcessorProfiles_ChangeCurrentLanguage(
561 ITfInputProcessorProfiles
*iface
, LANGID langid
)
563 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
564 ITfLanguageProfileNotifySink
*sink
;
568 FIXME("STUB:(%p)\n",This
);
570 SINK_FOR_EACH(cursor
, &This
->LanguageProfileNotifySink
, ITfLanguageProfileNotifySink
, sink
)
573 ITfLanguageProfileNotifySink_OnLanguageChange(sink
, langid
, &accept
);
578 /* TODO: On successful language change call OnLanguageChanged sink */
582 static HRESULT WINAPI
InputProcessorProfiles_GetLanguageList(
583 ITfInputProcessorProfiles
*iface
, LANGID
**ppLangId
, ULONG
*pulCount
)
585 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
586 FIXME("Semi-STUB:(%p)\n",This
);
587 *ppLangId
= CoTaskMemAlloc(sizeof(LANGID
));
588 **ppLangId
= This
->currentLanguage
;
593 static HRESULT WINAPI
InputProcessorProfiles_EnumLanguageProfiles(
594 ITfInputProcessorProfiles
*iface
, LANGID langid
,
595 IEnumTfLanguageProfiles
**ppEnum
)
597 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
598 EnumTfLanguageProfiles
*profenum
;
601 TRACE("(%p) %x %p\n",This
,langid
,ppEnum
);
605 hr
= EnumTfLanguageProfiles_Constructor(langid
, &profenum
);
606 *ppEnum
= &profenum
->IEnumTfLanguageProfiles_iface
;
611 static HRESULT WINAPI
InputProcessorProfiles_EnableLanguageProfile(
612 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
613 REFGUID guidProfile
, BOOL fEnable
)
615 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
622 TRACE("(%p) %s %x %s %i\n",This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
), fEnable
);
624 StringFromGUID2(rclsid
, buf
, 39);
625 StringFromGUID2(guidProfile
, buf2
, 39);
626 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
628 res
= RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
632 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&fEnable
, sizeof(DWORD
));
641 static HRESULT WINAPI
InputProcessorProfiles_IsEnabledLanguageProfile(
642 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
643 REFGUID guidProfile
, BOOL
*pfEnable
)
645 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
652 TRACE("(%p) %s, %i, %s, %p\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfile
),pfEnable
);
657 StringFromGUID2(rclsid
, buf
, 39);
658 StringFromGUID2(guidProfile
, buf2
, 39);
659 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
661 res
= RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
665 DWORD count
= sizeof(DWORD
);
666 res
= RegQueryValueExW(key
, szwEnable
, 0, NULL
, (LPBYTE
)pfEnable
, &count
);
670 if (res
) /* Try Default */
672 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
676 DWORD count
= sizeof(DWORD
);
677 res
= RegQueryValueExW(key
, szwEnable
, 0, NULL
, (LPBYTE
)pfEnable
, &count
);
688 static HRESULT WINAPI
InputProcessorProfiles_EnableLanguageProfileByDefault(
689 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
690 REFGUID guidProfile
, BOOL fEnable
)
692 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
699 TRACE("(%p) %s %x %s %i\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfile
),fEnable
);
701 StringFromGUID2(rclsid
, buf
, 39);
702 StringFromGUID2(guidProfile
, buf2
, 39);
703 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
705 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
709 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&fEnable
, sizeof(DWORD
));
718 static HRESULT WINAPI
InputProcessorProfiles_SubstituteKeyboardLayout(
719 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
720 REFGUID guidProfile
, HKL hKL
)
722 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
723 FIXME("STUB:(%p)\n",This
);
727 static const ITfInputProcessorProfilesVtbl InputProcessorProfilesVtbl
=
729 InputProcessorProfiles_QueryInterface
,
730 InputProcessorProfiles_AddRef
,
731 InputProcessorProfiles_Release
,
732 InputProcessorProfiles_Register
,
733 InputProcessorProfiles_Unregister
,
734 InputProcessorProfiles_AddLanguageProfile
,
735 InputProcessorProfiles_RemoveLanguageProfile
,
736 InputProcessorProfiles_EnumInputProcessorInfo
,
737 InputProcessorProfiles_GetDefaultLanguageProfile
,
738 InputProcessorProfiles_SetDefaultLanguageProfile
,
739 InputProcessorProfiles_ActivateLanguageProfile
,
740 InputProcessorProfiles_GetActiveLanguageProfile
,
741 InputProcessorProfiles_GetLanguageProfileDescription
,
742 InputProcessorProfiles_GetCurrentLanguage
,
743 InputProcessorProfiles_ChangeCurrentLanguage
,
744 InputProcessorProfiles_GetLanguageList
,
745 InputProcessorProfiles_EnumLanguageProfiles
,
746 InputProcessorProfiles_EnableLanguageProfile
,
747 InputProcessorProfiles_IsEnabledLanguageProfile
,
748 InputProcessorProfiles_EnableLanguageProfileByDefault
,
749 InputProcessorProfiles_SubstituteKeyboardLayout
752 static inline InputProcessorProfiles
*impl_from_ITfInputProcessorProfileMgr(ITfInputProcessorProfileMgr
*iface
)
754 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfInputProcessorProfileMgr_iface
);
757 static HRESULT WINAPI
InputProcessorProfileMgr_QueryInterface(ITfInputProcessorProfileMgr
*iface
, REFIID riid
, void **ppv
)
759 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
760 return ITfInputProcessorProfiles_QueryInterface(&This
->ITfInputProcessorProfiles_iface
, riid
, ppv
);
763 static ULONG WINAPI
InputProcessorProfileMgr_AddRef(ITfInputProcessorProfileMgr
*iface
)
765 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
766 return ITfInputProcessorProfiles_AddRef(&This
->ITfInputProcessorProfiles_iface
);
769 static ULONG WINAPI
InputProcessorProfileMgr_Release(ITfInputProcessorProfileMgr
*iface
)
771 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
772 return ITfInputProcessorProfiles_Release(&This
->ITfInputProcessorProfiles_iface
);
775 static HRESULT WINAPI
InputProcessorProfileMgr_ActivateProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
776 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, DWORD dwFlags
)
778 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
779 FIXME("(%p)->(%d %x %s %s %p %x)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
780 debugstr_guid(guidProfile
), hkl
, dwFlags
);
784 static HRESULT WINAPI
InputProcessorProfileMgr_DeactivateProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
785 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, DWORD dwFlags
)
787 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
788 FIXME("(%p)->(%d %x %s %s %p %x)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
789 debugstr_guid(guidProfile
), hkl
, dwFlags
);
793 static HRESULT WINAPI
InputProcessorProfileMgr_GetProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
794 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, TF_INPUTPROCESSORPROFILE
*pProfile
)
796 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
797 FIXME("(%p)->(%d %x %s %s %p %p)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
798 debugstr_guid(guidProfile
), hkl
, pProfile
);
802 static HRESULT WINAPI
InputProcessorProfileMgr_EnumProfiles(ITfInputProcessorProfileMgr
*iface
, LANGID langid
,
803 IEnumTfInputProcessorProfiles
**ppEnum
)
805 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
806 EnumTfInputProcessorProfiles
*enum_profiles
;
808 TRACE("(%p)->(%x %p)\n", This
, langid
, ppEnum
);
810 enum_profiles
= HeapAlloc(GetProcessHeap(), 0, sizeof(*enum_profiles
));
812 return E_OUTOFMEMORY
;
814 enum_profiles
->IEnumTfInputProcessorProfiles_iface
.lpVtbl
= &EnumTfInputProcessorProfilesVtbl
;
815 enum_profiles
->ref
= 1;
817 *ppEnum
= &enum_profiles
->IEnumTfInputProcessorProfiles_iface
;
821 static HRESULT WINAPI
InputProcessorProfileMgr_ReleaseInputProcessor(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
824 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
825 FIXME("(%p)->(%s %x)\n", This
, debugstr_guid(rclsid
), dwFlags
);
829 static HRESULT WINAPI
InputProcessorProfileMgr_RegisterProfile(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
830 LANGID langid
, REFGUID guidProfile
, const WCHAR
*pchDesc
, ULONG cchDesc
, const WCHAR
*pchIconFile
,
831 ULONG cchFile
, ULONG uIconIndex
, HKL hklsubstitute
, DWORD dwPreferredLayout
, BOOL bEnabledByDefault
,
834 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
835 FIXME("(%p)->(%s %x %s %s %d %s %u %u %p %x %x %x)\n", This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
),
836 debugstr_w(pchDesc
), cchDesc
, debugstr_w(pchIconFile
), cchFile
, uIconIndex
, hklsubstitute
, dwPreferredLayout
,
837 bEnabledByDefault
, dwFlags
);
841 static HRESULT WINAPI
InputProcessorProfileMgr_UnregisterProfile(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
842 LANGID langid
, REFGUID guidProfile
, DWORD dwFlags
)
844 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
845 FIXME("(%p)->(%s %x %s %x)\n", This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
), dwFlags
);
849 static HRESULT WINAPI
InputProcessorProfileMgr_GetActiveProfile(ITfInputProcessorProfileMgr
*iface
, REFGUID catid
,
850 TF_INPUTPROCESSORPROFILE
*pProfile
)
852 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
853 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(catid
), pProfile
);
857 static const ITfInputProcessorProfileMgrVtbl InputProcessorProfileMgrVtbl
= {
858 InputProcessorProfileMgr_QueryInterface
,
859 InputProcessorProfileMgr_AddRef
,
860 InputProcessorProfileMgr_Release
,
861 InputProcessorProfileMgr_ActivateProfile
,
862 InputProcessorProfileMgr_DeactivateProfile
,
863 InputProcessorProfileMgr_GetProfile
,
864 InputProcessorProfileMgr_EnumProfiles
,
865 InputProcessorProfileMgr_ReleaseInputProcessor
,
866 InputProcessorProfileMgr_RegisterProfile
,
867 InputProcessorProfileMgr_UnregisterProfile
,
868 InputProcessorProfileMgr_GetActiveProfile
871 /*****************************************************
872 * ITfSource functions
873 *****************************************************/
874 static HRESULT WINAPI
IPPSource_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
876 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
877 return ITfInputProcessorProfiles_QueryInterface(&This
->ITfInputProcessorProfiles_iface
, iid
, ppvOut
);
880 static ULONG WINAPI
IPPSource_AddRef(ITfSource
*iface
)
882 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
883 return ITfInputProcessorProfiles_AddRef(&This
->ITfInputProcessorProfiles_iface
);
886 static ULONG WINAPI
IPPSource_Release(ITfSource
*iface
)
888 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
889 return ITfInputProcessorProfiles_Release(&This
->ITfInputProcessorProfiles_iface
);
892 static HRESULT WINAPI
IPPSource_AdviseSink(ITfSource
*iface
,
893 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
895 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
897 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
899 if (!riid
|| !punk
|| !pdwCookie
)
902 if (IsEqualIID(riid
, &IID_ITfLanguageProfileNotifySink
))
903 return advise_sink(&This
->LanguageProfileNotifySink
, &IID_ITfLanguageProfileNotifySink
,
904 COOKIE_MAGIC_IPPSINK
, punk
, pdwCookie
);
906 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
910 static HRESULT WINAPI
IPPSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
912 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
914 TRACE("(%p) %x\n",This
,pdwCookie
);
916 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_IPPSINK
)
919 return unadvise_sink(pdwCookie
);
922 static const ITfSourceVtbl InputProcessorProfilesSourceVtbl
=
924 IPPSource_QueryInterface
,
927 IPPSource_AdviseSink
,
928 IPPSource_UnadviseSink
,
931 HRESULT
InputProcessorProfiles_Constructor(IUnknown
*pUnkOuter
, IUnknown
**ppOut
)
933 InputProcessorProfiles
*This
;
935 return CLASS_E_NOAGGREGATION
;
937 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(InputProcessorProfiles
));
939 return E_OUTOFMEMORY
;
941 This
->ITfInputProcessorProfiles_iface
.lpVtbl
= &InputProcessorProfilesVtbl
;
942 This
->ITfSource_iface
.lpVtbl
= &InputProcessorProfilesSourceVtbl
;
943 This
->ITfInputProcessorProfileMgr_iface
.lpVtbl
= &InputProcessorProfileMgrVtbl
;
945 This
->currentLanguage
= GetUserDefaultLCID();
947 list_init(&This
->LanguageProfileNotifySink
);
949 *ppOut
= (IUnknown
*)&This
->ITfInputProcessorProfiles_iface
;
950 TRACE("returning %p\n", *ppOut
);
954 /**************************************************
955 * IEnumGUID implementation for ITfInputProcessorProfiles::EnumInputProcessorInfo
956 **************************************************/
957 static void ProfilesEnumGuid_Destructor(ProfilesEnumGuid
*This
)
959 TRACE("destroying %p\n", This
);
960 RegCloseKey(This
->key
);
961 HeapFree(GetProcessHeap(),0,This
);
964 static HRESULT WINAPI
ProfilesEnumGuid_QueryInterface(IEnumGUID
*iface
, REFIID iid
, LPVOID
*ppvOut
)
966 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
969 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumGUID
))
971 *ppvOut
= &This
->IEnumGUID_iface
;
976 IEnumGUID_AddRef(iface
);
980 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
981 return E_NOINTERFACE
;
984 static ULONG WINAPI
ProfilesEnumGuid_AddRef(IEnumGUID
*iface
)
986 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
987 return InterlockedIncrement(&This
->refCount
);
990 static ULONG WINAPI
ProfilesEnumGuid_Release(IEnumGUID
*iface
)
992 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
995 ret
= InterlockedDecrement(&This
->refCount
);
997 ProfilesEnumGuid_Destructor(This
);
1001 /*****************************************************
1002 * IEnumGuid functions
1003 *****************************************************/
1004 static HRESULT WINAPI
ProfilesEnumGuid_Next( LPENUMGUID iface
,
1005 ULONG celt
, GUID
*rgelt
, ULONG
*pceltFetched
)
1007 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1010 TRACE("(%p)\n",This
);
1012 if (rgelt
== NULL
) return E_POINTER
;
1014 if (This
->key
) while (fetched
< celt
)
1021 res
= RegEnumKeyExW(This
->key
, This
->next_index
, catid
, &cName
,
1022 NULL
, NULL
, NULL
, NULL
);
1023 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
) break;
1024 ++(This
->next_index
);
1026 hr
= CLSIDFromString(catid
, rgelt
);
1027 if (FAILED(hr
)) continue;
1033 if (pceltFetched
) *pceltFetched
= fetched
;
1034 return fetched
== celt
? S_OK
: S_FALSE
;
1037 static HRESULT WINAPI
ProfilesEnumGuid_Skip( LPENUMGUID iface
, ULONG celt
)
1039 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1040 TRACE("(%p)\n",This
);
1042 This
->next_index
+= celt
;
1046 static HRESULT WINAPI
ProfilesEnumGuid_Reset( LPENUMGUID iface
)
1048 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1049 TRACE("(%p)\n",This
);
1050 This
->next_index
= 0;
1054 static HRESULT WINAPI
ProfilesEnumGuid_Clone( LPENUMGUID iface
,
1057 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1060 TRACE("(%p)\n",This
);
1062 if (ppenum
== NULL
) return E_POINTER
;
1064 res
= ProfilesEnumGuid_Constructor(ppenum
);
1067 ProfilesEnumGuid
*new_This
= impl_from_IEnumGUID(*ppenum
);
1068 new_This
->next_index
= This
->next_index
;
1073 static const IEnumGUIDVtbl EnumGUIDVtbl
=
1075 ProfilesEnumGuid_QueryInterface
,
1076 ProfilesEnumGuid_AddRef
,
1077 ProfilesEnumGuid_Release
,
1078 ProfilesEnumGuid_Next
,
1079 ProfilesEnumGuid_Skip
,
1080 ProfilesEnumGuid_Reset
,
1081 ProfilesEnumGuid_Clone
1084 static HRESULT
ProfilesEnumGuid_Constructor(IEnumGUID
**ppOut
)
1086 ProfilesEnumGuid
*This
;
1088 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ProfilesEnumGuid
));
1090 return E_OUTOFMEMORY
;
1092 This
->IEnumGUID_iface
.lpVtbl
= &EnumGUIDVtbl
;
1095 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
, szwSystemTIPKey
, 0, NULL
, 0,
1096 KEY_READ
| KEY_WRITE
, NULL
, &This
->key
, NULL
) != ERROR_SUCCESS
)
1098 HeapFree(GetProcessHeap(), 0, This
);
1102 *ppOut
= &This
->IEnumGUID_iface
;
1103 TRACE("returning %p\n", *ppOut
);
1107 /**************************************************
1108 * IEnumTfLanguageProfiles implementation
1109 **************************************************/
1110 static void EnumTfLanguageProfiles_Destructor(EnumTfLanguageProfiles
*This
)
1112 TRACE("destroying %p\n", This
);
1113 RegCloseKey(This
->tipkey
);
1115 RegCloseKey(This
->langkey
);
1116 ITfCategoryMgr_Release(This
->catmgr
);
1117 HeapFree(GetProcessHeap(),0,This
);
1120 static HRESULT WINAPI
EnumTfLanguageProfiles_QueryInterface(IEnumTfLanguageProfiles
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1122 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1126 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumTfLanguageProfiles
))
1128 *ppvOut
= &This
->IEnumTfLanguageProfiles_iface
;
1133 IEnumTfLanguageProfiles_AddRef(iface
);
1137 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
1138 return E_NOINTERFACE
;
1141 static ULONG WINAPI
EnumTfLanguageProfiles_AddRef(IEnumTfLanguageProfiles
*iface
)
1143 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1144 return InterlockedIncrement(&This
->refCount
);
1147 static ULONG WINAPI
EnumTfLanguageProfiles_Release(IEnumTfLanguageProfiles
*iface
)
1149 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1152 ret
= InterlockedDecrement(&This
->refCount
);
1154 EnumTfLanguageProfiles_Destructor(This
);
1158 /*****************************************************
1159 * IEnumGuid functions
1160 *****************************************************/
1161 static INT
next_LanguageProfile(EnumTfLanguageProfiles
*This
, CLSID clsid
, TF_LANGUAGEPROFILE
*tflp
)
1165 WCHAR profileid
[39];
1169 static const WCHAR fmt
[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
1171 if (This
->langkey
== NULL
)
1173 sprintfW(fullkey
,fmt
,This
->szwCurrentClsid
,szwLngp
,This
->langid
);
1174 res
= RegOpenKeyExW(This
->tipkey
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &This
->langkey
);
1177 This
->langkey
= NULL
;
1180 This
->lang_index
= 0;
1182 res
= RegEnumKeyExW(This
->langkey
, This
->lang_index
, profileid
, &cName
,
1183 NULL
, NULL
, NULL
, NULL
);
1184 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
)
1186 RegCloseKey(This
->langkey
);
1187 This
->langkey
= NULL
;
1190 ++(This
->lang_index
);
1194 static const GUID
* tipcats
[3] = { &GUID_TFCAT_TIP_KEYBOARD
,
1195 &GUID_TFCAT_TIP_SPEECH
,
1196 &GUID_TFCAT_TIP_HANDWRITING
};
1197 res
= CLSIDFromString(profileid
, &profile
);
1198 if (FAILED(res
)) return 0;
1200 tflp
->clsid
= clsid
;
1201 tflp
->langid
= This
->langid
;
1202 tflp
->fActive
= get_active_textservice(&clsid
, NULL
);
1203 tflp
->guidProfile
= profile
;
1204 if (ITfCategoryMgr_FindClosestCategory(This
->catmgr
, &clsid
,
1205 &tflp
->catid
, tipcats
, 3) != S_OK
)
1206 ITfCategoryMgr_FindClosestCategory(This
->catmgr
, &clsid
,
1207 &tflp
->catid
, NULL
, 0);
1213 static HRESULT WINAPI
EnumTfLanguageProfiles_Next(IEnumTfLanguageProfiles
*iface
,
1214 ULONG ulCount
, TF_LANGUAGEPROFILE
*pProfile
, ULONG
*pcFetch
)
1216 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1219 TRACE("(%p)\n",This
);
1221 if (pProfile
== NULL
) return E_POINTER
;
1223 if (This
->tipkey
) while (fetched
< ulCount
)
1230 res
= RegEnumKeyExW(This
->tipkey
, This
->tip_index
,
1231 This
->szwCurrentClsid
, &cName
, NULL
, NULL
, NULL
, NULL
);
1232 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
) break;
1233 ++(This
->tip_index
);
1234 hr
= CLSIDFromString(This
->szwCurrentClsid
, &clsid
);
1235 if (FAILED(hr
)) continue;
1237 while ( fetched
< ulCount
)
1239 INT res
= next_LanguageProfile(This
, clsid
, pProfile
);
1252 if (pcFetch
) *pcFetch
= fetched
;
1253 return fetched
== ulCount
? S_OK
: S_FALSE
;
1256 static HRESULT WINAPI
EnumTfLanguageProfiles_Skip( IEnumTfLanguageProfiles
* iface
, ULONG celt
)
1258 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1259 FIXME("STUB (%p)\n",This
);
1263 static HRESULT WINAPI
EnumTfLanguageProfiles_Reset( IEnumTfLanguageProfiles
* iface
)
1265 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1266 TRACE("(%p)\n",This
);
1267 This
->tip_index
= 0;
1269 RegCloseKey(This
->langkey
);
1270 This
->langkey
= NULL
;
1271 This
->lang_index
= 0;
1275 static HRESULT WINAPI
EnumTfLanguageProfiles_Clone( IEnumTfLanguageProfiles
*iface
,
1276 IEnumTfLanguageProfiles
**ppenum
)
1278 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1279 EnumTfLanguageProfiles
*new_This
;
1282 TRACE("(%p)\n",This
);
1284 if (ppenum
== NULL
) return E_POINTER
;
1286 res
= EnumTfLanguageProfiles_Constructor(This
->langid
, &new_This
);
1289 new_This
->tip_index
= This
->tip_index
;
1290 lstrcpynW(new_This
->szwCurrentClsid
,This
->szwCurrentClsid
,39);
1295 static const WCHAR fmt
[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
1297 sprintfW(fullkey
,fmt
,This
->szwCurrentClsid
,szwLngp
,This
->langid
);
1298 res
= RegOpenKeyExW(new_This
->tipkey
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &This
->langkey
);
1299 new_This
->lang_index
= This
->lang_index
;
1301 *ppenum
= &new_This
->IEnumTfLanguageProfiles_iface
;
1306 static const IEnumTfLanguageProfilesVtbl EnumTfLanguageProfilesVtbl
=
1308 EnumTfLanguageProfiles_QueryInterface
,
1309 EnumTfLanguageProfiles_AddRef
,
1310 EnumTfLanguageProfiles_Release
,
1311 EnumTfLanguageProfiles_Clone
,
1312 EnumTfLanguageProfiles_Next
,
1313 EnumTfLanguageProfiles_Reset
,
1314 EnumTfLanguageProfiles_Skip
1317 static HRESULT
EnumTfLanguageProfiles_Constructor(LANGID langid
, EnumTfLanguageProfiles
**out
)
1320 EnumTfLanguageProfiles
*This
;
1322 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(EnumTfLanguageProfiles
));
1324 return E_OUTOFMEMORY
;
1326 This
->IEnumTfLanguageProfiles_iface
.lpVtbl
= &EnumTfLanguageProfilesVtbl
;
1328 This
->langid
= langid
;
1330 hr
= CategoryMgr_Constructor(NULL
,(IUnknown
**)&This
->catmgr
);
1333 HeapFree(GetProcessHeap(),0,This
);
1337 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
, szwSystemTIPKey
, 0, NULL
, 0,
1338 KEY_READ
| KEY_WRITE
, NULL
, &This
->tipkey
, NULL
) != ERROR_SUCCESS
)
1340 HeapFree(GetProcessHeap(), 0, This
);
1345 TRACE("returning %p\n", *out
);