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"
40 #include "msctf_internal.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(msctf
);
44 static const WCHAR szwLngp
[] = {'L','a','n','g','u','a','g','e','P','r','o','f','i','l','e',0};
45 static const WCHAR szwEnable
[] = {'E','n','a','b','l','e',0};
46 static const WCHAR szwTipfmt
[] = {'%','s','\\','%','s',0};
47 static const WCHAR szwFullLangfmt
[] = {'%','s','\\','%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
49 static const WCHAR szwAssemblies
[] = {'A','s','s','e','m','b','l','i','e','s',0};
50 static const WCHAR szwDefault
[] = {'D','e','f','a','u','l','t',0};
51 static const WCHAR szwProfile
[] = {'P','r','o','f','i','l','e',0};
52 static const WCHAR szwDefaultFmt
[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
54 typedef struct tagInputProcessorProfiles
{
55 ITfInputProcessorProfiles ITfInputProcessorProfiles_iface
;
56 ITfSource ITfSource_iface
;
57 ITfInputProcessorProfileMgr ITfInputProcessorProfileMgr_iface
;
58 /* const ITfInputProcessorProfilesExVtbl *InputProcessorProfilesExVtbl; */
59 /* const ITfInputProcessorProfileSubstituteLayoutVtbl *InputProcessorProfileSubstituteLayoutVtbl; */
62 LANGID currentLanguage
;
64 struct list LanguageProfileNotifySink
;
65 } InputProcessorProfiles
;
67 typedef struct tagProfilesEnumGuid
{
68 IEnumGUID IEnumGUID_iface
;
75 typedef struct tagEnumTfLanguageProfiles
{
76 IEnumTfLanguageProfiles IEnumTfLanguageProfiles_iface
;
81 WCHAR szwCurrentClsid
[39];
87 ITfCategoryMgr
*catmgr
;
88 } EnumTfLanguageProfiles
;
91 IEnumTfInputProcessorProfiles IEnumTfInputProcessorProfiles_iface
;
93 } EnumTfInputProcessorProfiles
;
95 static HRESULT
ProfilesEnumGuid_Constructor(IEnumGUID
**ppOut
);
96 static HRESULT
EnumTfLanguageProfiles_Constructor(LANGID langid
, EnumTfLanguageProfiles
**out
);
98 static inline EnumTfInputProcessorProfiles
*impl_from_IEnumTfInputProcessorProfiles(IEnumTfInputProcessorProfiles
*iface
)
100 return CONTAINING_RECORD(iface
, EnumTfInputProcessorProfiles
, IEnumTfInputProcessorProfiles_iface
);
103 static HRESULT WINAPI
EnumTfInputProcessorProfiles_QueryInterface(IEnumTfInputProcessorProfiles
*iface
,
104 REFIID riid
, void **ppv
)
106 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
108 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
109 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
110 *ppv
= &This
->IEnumTfInputProcessorProfiles_iface
;
111 }else if(IsEqualGUID(riid
, &IID_IEnumTfInputProcessorProfiles
)) {
112 TRACE("(%p)->(IID_IEnumTfInputProcessorProfiles %p)\n", This
, ppv
);
113 *ppv
= &This
->IEnumTfInputProcessorProfiles_iface
;
116 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
117 return E_NOINTERFACE
;
120 IUnknown_AddRef((IUnknown
*)*ppv
);
124 static ULONG WINAPI
EnumTfInputProcessorProfiles_AddRef(IEnumTfInputProcessorProfiles
*iface
)
126 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
127 LONG ref
= InterlockedIncrement(&This
->ref
);
129 TRACE("(%p) ref=%d\n", This
, ref
);
134 static ULONG WINAPI
EnumTfInputProcessorProfiles_Release(IEnumTfInputProcessorProfiles
*iface
)
136 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
137 LONG ref
= InterlockedDecrement(&This
->ref
);
139 TRACE("(%p) ref=%d\n", This
, ref
);
142 HeapFree(GetProcessHeap(), 0, This
);
147 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Clone(IEnumTfInputProcessorProfiles
*iface
,
148 IEnumTfInputProcessorProfiles
**ret
)
150 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
151 FIXME("(%p)->(%p)\n", This
, ret
);
155 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Next(IEnumTfInputProcessorProfiles
*iface
, ULONG count
,
156 TF_INPUTPROCESSORPROFILE
*profile
, ULONG
*fetch
)
158 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
160 FIXME("(%p)->(%u %p %p)\n", This
, count
, profile
, fetch
);
167 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Reset(IEnumTfInputProcessorProfiles
*iface
)
169 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
170 FIXME("(%p)\n", This
);
174 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Skip(IEnumTfInputProcessorProfiles
*iface
, ULONG count
)
176 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
177 FIXME("(%p)->(%u)\n", This
, count
);
181 static const IEnumTfInputProcessorProfilesVtbl EnumTfInputProcessorProfilesVtbl
= {
182 EnumTfInputProcessorProfiles_QueryInterface
,
183 EnumTfInputProcessorProfiles_AddRef
,
184 EnumTfInputProcessorProfiles_Release
,
185 EnumTfInputProcessorProfiles_Clone
,
186 EnumTfInputProcessorProfiles_Next
,
187 EnumTfInputProcessorProfiles_Reset
,
188 EnumTfInputProcessorProfiles_Skip
191 static inline InputProcessorProfiles
*impl_from_ITfInputProcessorProfiles(ITfInputProcessorProfiles
*iface
)
193 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfInputProcessorProfiles_iface
);
196 static inline InputProcessorProfiles
*impl_from_ITfSource(ITfSource
*iface
)
198 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfSource_iface
);
201 static inline ProfilesEnumGuid
*impl_from_IEnumGUID(IEnumGUID
*iface
)
203 return CONTAINING_RECORD(iface
, ProfilesEnumGuid
, IEnumGUID_iface
);
206 static inline EnumTfLanguageProfiles
*impl_from_IEnumTfLanguageProfiles(IEnumTfLanguageProfiles
*iface
)
208 return CONTAINING_RECORD(iface
, EnumTfLanguageProfiles
, IEnumTfLanguageProfiles_iface
);
211 static void InputProcessorProfiles_Destructor(InputProcessorProfiles
*This
)
213 TRACE("destroying %p\n", This
);
215 free_sinks(&This
->LanguageProfileNotifySink
);
216 HeapFree(GetProcessHeap(),0,This
);
219 static void add_userkey( REFCLSID rclsid
, LANGID langid
,
226 DWORD disposition
= 0;
231 StringFromGUID2(rclsid
, buf
, 39);
232 StringFromGUID2(guidProfile
, buf2
, 39);
233 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
235 res
= RegCreateKeyExW(HKEY_CURRENT_USER
,fullkey
, 0, NULL
, 0,
236 KEY_READ
| KEY_WRITE
, NULL
, &key
, &disposition
);
238 if (!res
&& disposition
== REG_CREATED_NEW_KEY
)
241 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&zero
, sizeof(DWORD
));
248 static HRESULT WINAPI
InputProcessorProfiles_QueryInterface(ITfInputProcessorProfiles
*iface
, REFIID iid
, void **ppv
)
250 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
252 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfInputProcessorProfiles
))
254 *ppv
= &This
->ITfInputProcessorProfiles_iface
;
256 else if (IsEqualIID(iid
, &IID_ITfInputProcessorProfileMgr
))
258 *ppv
= &This
->ITfInputProcessorProfileMgr_iface
;
260 else if (IsEqualIID(iid
, &IID_ITfSource
))
262 *ppv
= &This
->ITfSource_iface
;
267 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
268 return E_NOINTERFACE
;
271 ITfInputProcessorProfiles_AddRef(iface
);
275 static ULONG WINAPI
InputProcessorProfiles_AddRef(ITfInputProcessorProfiles
*iface
)
277 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
278 return InterlockedIncrement(&This
->refCount
);
281 static ULONG WINAPI
InputProcessorProfiles_Release(ITfInputProcessorProfiles
*iface
)
283 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
286 ret
= InterlockedDecrement(&This
->refCount
);
288 InputProcessorProfiles_Destructor(This
);
292 /*****************************************************
293 * ITfInputProcessorProfiles functions
294 *****************************************************/
295 static HRESULT WINAPI
InputProcessorProfiles_Register(
296 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
)
298 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 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,fullkey
, 0, NULL
, 0,
309 KEY_READ
| KEY_WRITE
, NULL
, &tipkey
, NULL
) != ERROR_SUCCESS
)
317 static HRESULT WINAPI
InputProcessorProfiles_Unregister(
318 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
)
320 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
324 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
326 StringFromGUID2(rclsid
, buf
, 39);
327 sprintfW(fullkey
,szwTipfmt
,szwSystemTIPKey
,buf
);
329 RegDeleteTreeW(HKEY_LOCAL_MACHINE
, fullkey
);
330 RegDeleteTreeW(HKEY_CURRENT_USER
, fullkey
);
335 static HRESULT WINAPI
InputProcessorProfiles_AddLanguageProfile(
336 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
,
337 LANGID langid
, REFGUID guidProfile
, const WCHAR
*pchDesc
,
338 ULONG cchDesc
, const WCHAR
*pchIconFile
, ULONG cchFile
,
341 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
346 DWORD disposition
= 0;
348 static const WCHAR fmt2
[] = {'%','s','\\','0','x','%','0','8','x','\\','%','s',0};
349 static const WCHAR desc
[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
350 static const WCHAR icnf
[] = {'I','c','o','n','F','i','l','e',0};
351 static const WCHAR icni
[] = {'I','c','o','n','I','n','d','e','x',0};
353 TRACE("(%p) %s %x %s %s %s %i\n",This
,debugstr_guid(rclsid
), langid
,
354 debugstr_guid(guidProfile
), debugstr_wn(pchDesc
,cchDesc
),
355 debugstr_wn(pchIconFile
,cchFile
),uIconIndex
);
357 StringFromGUID2(rclsid
, buf
, 39);
358 sprintfW(fullkey
,szwTipfmt
,szwSystemTIPKey
,buf
);
360 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,fullkey
, 0, KEY_READ
| KEY_WRITE
,
361 &tipkey
) != ERROR_SUCCESS
)
364 StringFromGUID2(guidProfile
, buf
, 39);
365 sprintfW(fullkey
,fmt2
,szwLngp
,langid
,buf
);
367 res
= RegCreateKeyExW(tipkey
,fullkey
, 0, NULL
, 0, KEY_READ
| KEY_WRITE
,
368 NULL
, &fmtkey
, &disposition
);
373 RegSetValueExW(fmtkey
, desc
, 0, REG_SZ
, (const BYTE
*)pchDesc
, cchDesc
* sizeof(WCHAR
));
374 RegSetValueExW(fmtkey
, icnf
, 0, REG_SZ
, (const BYTE
*)pchIconFile
, cchFile
* sizeof(WCHAR
));
375 RegSetValueExW(fmtkey
, icni
, 0, REG_DWORD
, (LPBYTE
)&uIconIndex
, sizeof(DWORD
));
376 if (disposition
== REG_CREATED_NEW_KEY
)
377 RegSetValueExW(fmtkey
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&zero
, sizeof(DWORD
));
380 add_userkey(rclsid
, langid
, guidProfile
);
390 static HRESULT WINAPI
InputProcessorProfiles_RemoveLanguageProfile(
391 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
394 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
395 FIXME("STUB:(%p)\n",This
);
399 static HRESULT WINAPI
InputProcessorProfiles_EnumInputProcessorInfo(
400 ITfInputProcessorProfiles
*iface
, IEnumGUID
**ppEnum
)
402 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
403 TRACE("(%p) %p\n",This
,ppEnum
);
404 return ProfilesEnumGuid_Constructor(ppEnum
);
407 static HRESULT WINAPI
InputProcessorProfiles_GetDefaultLanguageProfile(
408 ITfInputProcessorProfiles
*iface
, LANGID langid
, REFGUID catid
,
409 CLSID
*pclsid
, GUID
*pguidProfile
)
411 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
418 TRACE("%p) %x %s %p %p\n",This
, langid
, debugstr_guid(catid
),pclsid
,pguidProfile
);
420 if (!catid
|| !pclsid
|| !pguidProfile
)
423 StringFromGUID2(catid
, buf
, 39);
424 sprintfW(fullkey
, szwDefaultFmt
, szwSystemCTFKey
, szwAssemblies
, langid
, buf
);
426 if (RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
,
427 &hkey
) != ERROR_SUCCESS
)
431 res
= RegQueryValueExW(hkey
, szwDefault
, 0, NULL
, (LPBYTE
)buf
, &count
);
432 if (res
!= ERROR_SUCCESS
)
437 CLSIDFromString(buf
,pclsid
);
439 res
= RegQueryValueExW(hkey
, szwProfile
, 0, NULL
, (LPBYTE
)buf
, &count
);
440 if (res
== ERROR_SUCCESS
)
441 CLSIDFromString(buf
,pguidProfile
);
448 static HRESULT WINAPI
InputProcessorProfiles_SetDefaultLanguageProfile(
449 ITfInputProcessorProfiles
*iface
, LANGID langid
, REFCLSID rclsid
,
450 REFGUID guidProfiles
)
452 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
458 ITfCategoryMgr
*catmgr
;
459 static const GUID
* tipcats
[3] = { &GUID_TFCAT_TIP_KEYBOARD
,
460 &GUID_TFCAT_TIP_SPEECH
,
461 &GUID_TFCAT_TIP_HANDWRITING
};
463 TRACE("%p) %x %s %s\n",This
, langid
, debugstr_guid(rclsid
),debugstr_guid(guidProfiles
));
465 if (!rclsid
|| !guidProfiles
)
468 hr
= CategoryMgr_Constructor(NULL
,(IUnknown
**)&catmgr
);
473 if (ITfCategoryMgr_FindClosestCategory(catmgr
, rclsid
,
474 &catid
, tipcats
, 3) != S_OK
)
475 hr
= ITfCategoryMgr_FindClosestCategory(catmgr
, rclsid
,
477 ITfCategoryMgr_Release(catmgr
);
482 StringFromGUID2(&catid
, buf
, 39);
483 sprintfW(fullkey
, szwDefaultFmt
, szwSystemCTFKey
, szwAssemblies
, langid
, buf
);
485 if (RegCreateKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, NULL
, 0, KEY_READ
| KEY_WRITE
,
486 NULL
, &hkey
, NULL
) != ERROR_SUCCESS
)
489 StringFromGUID2(rclsid
, buf
, 39);
490 RegSetValueExW(hkey
, szwDefault
, 0, REG_SZ
, (LPBYTE
)buf
, sizeof(buf
));
491 StringFromGUID2(guidProfiles
, buf
, 39);
492 RegSetValueExW(hkey
, szwProfile
, 0, REG_SZ
, (LPBYTE
)buf
, sizeof(buf
));
498 static HRESULT WINAPI
InputProcessorProfiles_ActivateLanguageProfile(
499 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
500 REFGUID guidProfiles
)
502 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
505 TF_LANGUAGEPROFILE LanguageProfile
;
507 TRACE("(%p) %s %x %s\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfiles
));
509 if (langid
!= This
->currentLanguage
) return E_INVALIDARG
;
511 if (get_active_textservice(rclsid
,NULL
))
513 TRACE("Already Active\n");
517 hr
= ITfInputProcessorProfiles_IsEnabledLanguageProfile(iface
, rclsid
,
518 langid
, guidProfiles
, &enabled
);
519 if (FAILED(hr
) || !enabled
)
521 TRACE("Not Enabled\n");
525 LanguageProfile
.clsid
= *rclsid
;
526 LanguageProfile
.langid
= langid
;
527 LanguageProfile
.guidProfile
= *guidProfiles
;
528 LanguageProfile
.fActive
= TRUE
;
530 return add_active_textservice(&LanguageProfile
);
533 static HRESULT WINAPI
InputProcessorProfiles_GetActiveLanguageProfile(
534 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID
*plangid
,
537 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
538 TF_LANGUAGEPROFILE profile
;
540 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(rclsid
),plangid
,pguidProfile
);
542 if (!rclsid
|| !plangid
|| !pguidProfile
)
545 if (get_active_textservice(rclsid
, &profile
))
547 *plangid
= profile
.langid
;
548 *pguidProfile
= profile
.guidProfile
;
553 *pguidProfile
= GUID_NULL
;
558 static HRESULT WINAPI
InputProcessorProfiles_GetLanguageProfileDescription(
559 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
560 REFGUID guidProfile
, BSTR
*pbstrProfile
)
562 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
563 FIXME("STUB:(%p)\n",This
);
567 static HRESULT WINAPI
InputProcessorProfiles_GetCurrentLanguage(
568 ITfInputProcessorProfiles
*iface
, LANGID
*plangid
)
570 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
571 TRACE("(%p) 0x%x\n",This
,This
->currentLanguage
);
576 *plangid
= This
->currentLanguage
;
581 static HRESULT WINAPI
InputProcessorProfiles_ChangeCurrentLanguage(
582 ITfInputProcessorProfiles
*iface
, LANGID langid
)
584 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
585 ITfLanguageProfileNotifySink
*sink
;
589 FIXME("STUB:(%p)\n",This
);
591 SINK_FOR_EACH(cursor
, &This
->LanguageProfileNotifySink
, ITfLanguageProfileNotifySink
, sink
)
594 ITfLanguageProfileNotifySink_OnLanguageChange(sink
, langid
, &accept
);
599 /* TODO: On successful language change call OnLanguageChanged sink */
603 static HRESULT WINAPI
InputProcessorProfiles_GetLanguageList(
604 ITfInputProcessorProfiles
*iface
, LANGID
**ppLangId
, ULONG
*pulCount
)
606 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
607 FIXME("Semi-STUB:(%p)\n",This
);
608 *ppLangId
= CoTaskMemAlloc(sizeof(LANGID
));
609 **ppLangId
= This
->currentLanguage
;
614 static HRESULT WINAPI
InputProcessorProfiles_EnumLanguageProfiles(
615 ITfInputProcessorProfiles
*iface
, LANGID langid
,
616 IEnumTfLanguageProfiles
**ppEnum
)
618 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
619 EnumTfLanguageProfiles
*profenum
;
622 TRACE("(%p) %x %p\n",This
,langid
,ppEnum
);
626 hr
= EnumTfLanguageProfiles_Constructor(langid
, &profenum
);
627 *ppEnum
= &profenum
->IEnumTfLanguageProfiles_iface
;
632 static HRESULT WINAPI
InputProcessorProfiles_EnableLanguageProfile(
633 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
634 REFGUID guidProfile
, BOOL fEnable
)
636 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
643 TRACE("(%p) %s %x %s %i\n",This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
), fEnable
);
645 StringFromGUID2(rclsid
, buf
, 39);
646 StringFromGUID2(guidProfile
, buf2
, 39);
647 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
649 res
= RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
653 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&fEnable
, sizeof(DWORD
));
662 static HRESULT WINAPI
InputProcessorProfiles_IsEnabledLanguageProfile(
663 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
664 REFGUID guidProfile
, BOOL
*pfEnable
)
666 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
673 TRACE("(%p) %s, %i, %s, %p\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfile
),pfEnable
);
678 StringFromGUID2(rclsid
, buf
, 39);
679 StringFromGUID2(guidProfile
, buf2
, 39);
680 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
682 res
= RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
686 DWORD count
= sizeof(DWORD
);
687 res
= RegQueryValueExW(key
, szwEnable
, 0, NULL
, (LPBYTE
)pfEnable
, &count
);
691 if (res
) /* Try Default */
693 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
697 DWORD count
= sizeof(DWORD
);
698 res
= RegQueryValueExW(key
, szwEnable
, 0, NULL
, (LPBYTE
)pfEnable
, &count
);
709 static HRESULT WINAPI
InputProcessorProfiles_EnableLanguageProfileByDefault(
710 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
711 REFGUID guidProfile
, BOOL fEnable
)
713 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
720 TRACE("(%p) %s %x %s %i\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfile
),fEnable
);
722 StringFromGUID2(rclsid
, buf
, 39);
723 StringFromGUID2(guidProfile
, buf2
, 39);
724 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
726 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
730 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&fEnable
, sizeof(DWORD
));
739 static HRESULT WINAPI
InputProcessorProfiles_SubstituteKeyboardLayout(
740 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
741 REFGUID guidProfile
, HKL hKL
)
743 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
744 FIXME("STUB:(%p)\n",This
);
748 static const ITfInputProcessorProfilesVtbl InputProcessorProfilesVtbl
=
750 InputProcessorProfiles_QueryInterface
,
751 InputProcessorProfiles_AddRef
,
752 InputProcessorProfiles_Release
,
753 InputProcessorProfiles_Register
,
754 InputProcessorProfiles_Unregister
,
755 InputProcessorProfiles_AddLanguageProfile
,
756 InputProcessorProfiles_RemoveLanguageProfile
,
757 InputProcessorProfiles_EnumInputProcessorInfo
,
758 InputProcessorProfiles_GetDefaultLanguageProfile
,
759 InputProcessorProfiles_SetDefaultLanguageProfile
,
760 InputProcessorProfiles_ActivateLanguageProfile
,
761 InputProcessorProfiles_GetActiveLanguageProfile
,
762 InputProcessorProfiles_GetLanguageProfileDescription
,
763 InputProcessorProfiles_GetCurrentLanguage
,
764 InputProcessorProfiles_ChangeCurrentLanguage
,
765 InputProcessorProfiles_GetLanguageList
,
766 InputProcessorProfiles_EnumLanguageProfiles
,
767 InputProcessorProfiles_EnableLanguageProfile
,
768 InputProcessorProfiles_IsEnabledLanguageProfile
,
769 InputProcessorProfiles_EnableLanguageProfileByDefault
,
770 InputProcessorProfiles_SubstituteKeyboardLayout
773 static inline InputProcessorProfiles
*impl_from_ITfInputProcessorProfileMgr(ITfInputProcessorProfileMgr
*iface
)
775 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfInputProcessorProfileMgr_iface
);
778 static HRESULT WINAPI
InputProcessorProfileMgr_QueryInterface(ITfInputProcessorProfileMgr
*iface
, REFIID riid
, void **ppv
)
780 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
781 return ITfInputProcessorProfiles_QueryInterface(&This
->ITfInputProcessorProfiles_iface
, riid
, ppv
);
784 static ULONG WINAPI
InputProcessorProfileMgr_AddRef(ITfInputProcessorProfileMgr
*iface
)
786 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
787 return ITfInputProcessorProfiles_AddRef(&This
->ITfInputProcessorProfiles_iface
);
790 static ULONG WINAPI
InputProcessorProfileMgr_Release(ITfInputProcessorProfileMgr
*iface
)
792 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
793 return ITfInputProcessorProfiles_Release(&This
->ITfInputProcessorProfiles_iface
);
796 static HRESULT WINAPI
InputProcessorProfileMgr_ActivateProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
797 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, DWORD dwFlags
)
799 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
800 FIXME("(%p)->(%d %x %s %s %p %x)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
801 debugstr_guid(guidProfile
), hkl
, dwFlags
);
805 static HRESULT WINAPI
InputProcessorProfileMgr_DeactivateProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
806 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, DWORD dwFlags
)
808 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
809 FIXME("(%p)->(%d %x %s %s %p %x)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
810 debugstr_guid(guidProfile
), hkl
, dwFlags
);
814 static HRESULT WINAPI
InputProcessorProfileMgr_GetProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
815 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, TF_INPUTPROCESSORPROFILE
*pProfile
)
817 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
818 FIXME("(%p)->(%d %x %s %s %p %p)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
819 debugstr_guid(guidProfile
), hkl
, pProfile
);
823 static HRESULT WINAPI
InputProcessorProfileMgr_EnumProfiles(ITfInputProcessorProfileMgr
*iface
, LANGID langid
,
824 IEnumTfInputProcessorProfiles
**ppEnum
)
826 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
827 EnumTfInputProcessorProfiles
*enum_profiles
;
829 TRACE("(%p)->(%x %p)\n", This
, langid
, ppEnum
);
831 enum_profiles
= HeapAlloc(GetProcessHeap(), 0, sizeof(*enum_profiles
));
833 return E_OUTOFMEMORY
;
835 enum_profiles
->IEnumTfInputProcessorProfiles_iface
.lpVtbl
= &EnumTfInputProcessorProfilesVtbl
;
836 enum_profiles
->ref
= 1;
838 *ppEnum
= &enum_profiles
->IEnumTfInputProcessorProfiles_iface
;
842 static HRESULT WINAPI
InputProcessorProfileMgr_ReleaseInputProcessor(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
845 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
846 FIXME("(%p)->(%s %x)\n", This
, debugstr_guid(rclsid
), dwFlags
);
850 static HRESULT WINAPI
InputProcessorProfileMgr_RegisterProfile(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
851 LANGID langid
, REFGUID guidProfile
, const WCHAR
*pchDesc
, ULONG cchDesc
, const WCHAR
*pchIconFile
,
852 ULONG cchFile
, ULONG uIconIndex
, HKL hklsubstitute
, DWORD dwPreferredLayout
, BOOL bEnabledByDefault
,
855 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
856 FIXME("(%p)->(%s %x %s %s %d %s %u %u %p %x %x %x)\n", This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
),
857 debugstr_w(pchDesc
), cchDesc
, debugstr_w(pchIconFile
), cchFile
, uIconIndex
, hklsubstitute
, dwPreferredLayout
,
858 bEnabledByDefault
, dwFlags
);
862 static HRESULT WINAPI
InputProcessorProfileMgr_UnregisterProfile(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
863 LANGID langid
, REFGUID guidProfile
, DWORD dwFlags
)
865 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
866 FIXME("(%p)->(%s %x %s %x)\n", This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
), dwFlags
);
870 static HRESULT WINAPI
InputProcessorProfileMgr_GetActiveProfile(ITfInputProcessorProfileMgr
*iface
, REFGUID catid
,
871 TF_INPUTPROCESSORPROFILE
*pProfile
)
873 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
874 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(catid
), pProfile
);
878 static const ITfInputProcessorProfileMgrVtbl InputProcessorProfileMgrVtbl
= {
879 InputProcessorProfileMgr_QueryInterface
,
880 InputProcessorProfileMgr_AddRef
,
881 InputProcessorProfileMgr_Release
,
882 InputProcessorProfileMgr_ActivateProfile
,
883 InputProcessorProfileMgr_DeactivateProfile
,
884 InputProcessorProfileMgr_GetProfile
,
885 InputProcessorProfileMgr_EnumProfiles
,
886 InputProcessorProfileMgr_ReleaseInputProcessor
,
887 InputProcessorProfileMgr_RegisterProfile
,
888 InputProcessorProfileMgr_UnregisterProfile
,
889 InputProcessorProfileMgr_GetActiveProfile
892 /*****************************************************
893 * ITfSource functions
894 *****************************************************/
895 static HRESULT WINAPI
IPPSource_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
897 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
898 return ITfInputProcessorProfiles_QueryInterface(&This
->ITfInputProcessorProfiles_iface
, iid
, ppvOut
);
901 static ULONG WINAPI
IPPSource_AddRef(ITfSource
*iface
)
903 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
904 return ITfInputProcessorProfiles_AddRef(&This
->ITfInputProcessorProfiles_iface
);
907 static ULONG WINAPI
IPPSource_Release(ITfSource
*iface
)
909 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
910 return ITfInputProcessorProfiles_Release(&This
->ITfInputProcessorProfiles_iface
);
913 static HRESULT WINAPI
IPPSource_AdviseSink(ITfSource
*iface
,
914 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
916 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
918 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
920 if (!riid
|| !punk
|| !pdwCookie
)
923 if (IsEqualIID(riid
, &IID_ITfLanguageProfileNotifySink
))
924 return advise_sink(&This
->LanguageProfileNotifySink
, &IID_ITfLanguageProfileNotifySink
,
925 COOKIE_MAGIC_IPPSINK
, punk
, pdwCookie
);
927 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
931 static HRESULT WINAPI
IPPSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
933 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
935 TRACE("(%p) %x\n",This
,pdwCookie
);
937 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_IPPSINK
)
940 return unadvise_sink(pdwCookie
);
943 static const ITfSourceVtbl InputProcessorProfilesSourceVtbl
=
945 IPPSource_QueryInterface
,
948 IPPSource_AdviseSink
,
949 IPPSource_UnadviseSink
,
952 HRESULT
InputProcessorProfiles_Constructor(IUnknown
*pUnkOuter
, IUnknown
**ppOut
)
954 InputProcessorProfiles
*This
;
956 return CLASS_E_NOAGGREGATION
;
958 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(InputProcessorProfiles
));
960 return E_OUTOFMEMORY
;
962 This
->ITfInputProcessorProfiles_iface
.lpVtbl
= &InputProcessorProfilesVtbl
;
963 This
->ITfSource_iface
.lpVtbl
= &InputProcessorProfilesSourceVtbl
;
964 This
->ITfInputProcessorProfileMgr_iface
.lpVtbl
= &InputProcessorProfileMgrVtbl
;
966 This
->currentLanguage
= GetUserDefaultLCID();
968 list_init(&This
->LanguageProfileNotifySink
);
970 *ppOut
= (IUnknown
*)&This
->ITfInputProcessorProfiles_iface
;
971 TRACE("returning %p\n", *ppOut
);
975 /**************************************************
976 * IEnumGUID implementation for ITfInputProcessorProfiles::EnumInputProcessorInfo
977 **************************************************/
978 static void ProfilesEnumGuid_Destructor(ProfilesEnumGuid
*This
)
980 TRACE("destroying %p\n", This
);
981 RegCloseKey(This
->key
);
982 HeapFree(GetProcessHeap(),0,This
);
985 static HRESULT WINAPI
ProfilesEnumGuid_QueryInterface(IEnumGUID
*iface
, REFIID iid
, LPVOID
*ppvOut
)
987 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
990 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumGUID
))
992 *ppvOut
= &This
->IEnumGUID_iface
;
997 IEnumGUID_AddRef(iface
);
1001 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
1002 return E_NOINTERFACE
;
1005 static ULONG WINAPI
ProfilesEnumGuid_AddRef(IEnumGUID
*iface
)
1007 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1008 return InterlockedIncrement(&This
->refCount
);
1011 static ULONG WINAPI
ProfilesEnumGuid_Release(IEnumGUID
*iface
)
1013 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1016 ret
= InterlockedDecrement(&This
->refCount
);
1018 ProfilesEnumGuid_Destructor(This
);
1022 /*****************************************************
1023 * IEnumGuid functions
1024 *****************************************************/
1025 static HRESULT WINAPI
ProfilesEnumGuid_Next( LPENUMGUID iface
,
1026 ULONG celt
, GUID
*rgelt
, ULONG
*pceltFetched
)
1028 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1031 TRACE("(%p)\n",This
);
1033 if (rgelt
== NULL
) return E_POINTER
;
1035 if (This
->key
) while (fetched
< celt
)
1042 res
= RegEnumKeyExW(This
->key
, This
->next_index
, catid
, &cName
,
1043 NULL
, NULL
, NULL
, NULL
);
1044 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
) break;
1045 ++(This
->next_index
);
1047 hr
= CLSIDFromString(catid
, rgelt
);
1048 if (FAILED(hr
)) continue;
1054 if (pceltFetched
) *pceltFetched
= fetched
;
1055 return fetched
== celt
? S_OK
: S_FALSE
;
1058 static HRESULT WINAPI
ProfilesEnumGuid_Skip( LPENUMGUID iface
, ULONG celt
)
1060 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1061 TRACE("(%p)\n",This
);
1063 This
->next_index
+= celt
;
1067 static HRESULT WINAPI
ProfilesEnumGuid_Reset( LPENUMGUID iface
)
1069 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1070 TRACE("(%p)\n",This
);
1071 This
->next_index
= 0;
1075 static HRESULT WINAPI
ProfilesEnumGuid_Clone( LPENUMGUID iface
,
1078 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1081 TRACE("(%p)\n",This
);
1083 if (ppenum
== NULL
) return E_POINTER
;
1085 res
= ProfilesEnumGuid_Constructor(ppenum
);
1088 ProfilesEnumGuid
*new_This
= impl_from_IEnumGUID(*ppenum
);
1089 new_This
->next_index
= This
->next_index
;
1094 static const IEnumGUIDVtbl EnumGUIDVtbl
=
1096 ProfilesEnumGuid_QueryInterface
,
1097 ProfilesEnumGuid_AddRef
,
1098 ProfilesEnumGuid_Release
,
1099 ProfilesEnumGuid_Next
,
1100 ProfilesEnumGuid_Skip
,
1101 ProfilesEnumGuid_Reset
,
1102 ProfilesEnumGuid_Clone
1105 static HRESULT
ProfilesEnumGuid_Constructor(IEnumGUID
**ppOut
)
1107 ProfilesEnumGuid
*This
;
1109 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ProfilesEnumGuid
));
1111 return E_OUTOFMEMORY
;
1113 This
->IEnumGUID_iface
.lpVtbl
= &EnumGUIDVtbl
;
1116 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
, szwSystemTIPKey
, 0, NULL
, 0,
1117 KEY_READ
| KEY_WRITE
, NULL
, &This
->key
, NULL
) != ERROR_SUCCESS
)
1119 HeapFree(GetProcessHeap(), 0, This
);
1123 *ppOut
= &This
->IEnumGUID_iface
;
1124 TRACE("returning %p\n", *ppOut
);
1128 /**************************************************
1129 * IEnumTfLanguageProfiles implementation
1130 **************************************************/
1131 static void EnumTfLanguageProfiles_Destructor(EnumTfLanguageProfiles
*This
)
1133 TRACE("destroying %p\n", This
);
1134 RegCloseKey(This
->tipkey
);
1136 RegCloseKey(This
->langkey
);
1137 ITfCategoryMgr_Release(This
->catmgr
);
1138 HeapFree(GetProcessHeap(),0,This
);
1141 static HRESULT WINAPI
EnumTfLanguageProfiles_QueryInterface(IEnumTfLanguageProfiles
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1143 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1147 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumTfLanguageProfiles
))
1149 *ppvOut
= &This
->IEnumTfLanguageProfiles_iface
;
1154 IEnumTfLanguageProfiles_AddRef(iface
);
1158 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
1159 return E_NOINTERFACE
;
1162 static ULONG WINAPI
EnumTfLanguageProfiles_AddRef(IEnumTfLanguageProfiles
*iface
)
1164 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1165 return InterlockedIncrement(&This
->refCount
);
1168 static ULONG WINAPI
EnumTfLanguageProfiles_Release(IEnumTfLanguageProfiles
*iface
)
1170 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1173 ret
= InterlockedDecrement(&This
->refCount
);
1175 EnumTfLanguageProfiles_Destructor(This
);
1179 /*****************************************************
1180 * IEnumGuid functions
1181 *****************************************************/
1182 static INT
next_LanguageProfile(EnumTfLanguageProfiles
*This
, CLSID clsid
, TF_LANGUAGEPROFILE
*tflp
)
1186 WCHAR profileid
[39];
1190 static const WCHAR fmt
[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
1192 if (This
->langkey
== NULL
)
1194 sprintfW(fullkey
,fmt
,This
->szwCurrentClsid
,szwLngp
,This
->langid
);
1195 res
= RegOpenKeyExW(This
->tipkey
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &This
->langkey
);
1198 This
->langkey
= NULL
;
1201 This
->lang_index
= 0;
1203 res
= RegEnumKeyExW(This
->langkey
, This
->lang_index
, profileid
, &cName
,
1204 NULL
, NULL
, NULL
, NULL
);
1205 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
)
1207 RegCloseKey(This
->langkey
);
1208 This
->langkey
= NULL
;
1211 ++(This
->lang_index
);
1215 static const GUID
* tipcats
[3] = { &GUID_TFCAT_TIP_KEYBOARD
,
1216 &GUID_TFCAT_TIP_SPEECH
,
1217 &GUID_TFCAT_TIP_HANDWRITING
};
1218 res
= CLSIDFromString(profileid
, &profile
);
1219 if (FAILED(res
)) return 0;
1221 tflp
->clsid
= clsid
;
1222 tflp
->langid
= This
->langid
;
1223 tflp
->fActive
= get_active_textservice(&clsid
, NULL
);
1224 tflp
->guidProfile
= profile
;
1225 if (ITfCategoryMgr_FindClosestCategory(This
->catmgr
, &clsid
,
1226 &tflp
->catid
, tipcats
, 3) != S_OK
)
1227 ITfCategoryMgr_FindClosestCategory(This
->catmgr
, &clsid
,
1228 &tflp
->catid
, NULL
, 0);
1234 static HRESULT WINAPI
EnumTfLanguageProfiles_Next(IEnumTfLanguageProfiles
*iface
,
1235 ULONG ulCount
, TF_LANGUAGEPROFILE
*pProfile
, ULONG
*pcFetch
)
1237 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1240 TRACE("(%p)\n",This
);
1242 if (pProfile
== NULL
) return E_POINTER
;
1244 if (This
->tipkey
) while (fetched
< ulCount
)
1251 res
= RegEnumKeyExW(This
->tipkey
, This
->tip_index
,
1252 This
->szwCurrentClsid
, &cName
, NULL
, NULL
, NULL
, NULL
);
1253 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
) break;
1254 ++(This
->tip_index
);
1255 hr
= CLSIDFromString(This
->szwCurrentClsid
, &clsid
);
1256 if (FAILED(hr
)) continue;
1258 while ( fetched
< ulCount
)
1260 INT res
= next_LanguageProfile(This
, clsid
, pProfile
);
1273 if (pcFetch
) *pcFetch
= fetched
;
1274 return fetched
== ulCount
? S_OK
: S_FALSE
;
1277 static HRESULT WINAPI
EnumTfLanguageProfiles_Skip( IEnumTfLanguageProfiles
* iface
, ULONG celt
)
1279 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1280 FIXME("STUB (%p)\n",This
);
1284 static HRESULT WINAPI
EnumTfLanguageProfiles_Reset( IEnumTfLanguageProfiles
* iface
)
1286 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1287 TRACE("(%p)\n",This
);
1288 This
->tip_index
= 0;
1290 RegCloseKey(This
->langkey
);
1291 This
->langkey
= NULL
;
1292 This
->lang_index
= 0;
1296 static HRESULT WINAPI
EnumTfLanguageProfiles_Clone( IEnumTfLanguageProfiles
*iface
,
1297 IEnumTfLanguageProfiles
**ppenum
)
1299 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1300 EnumTfLanguageProfiles
*new_This
;
1303 TRACE("(%p)\n",This
);
1305 if (ppenum
== NULL
) return E_POINTER
;
1307 res
= EnumTfLanguageProfiles_Constructor(This
->langid
, &new_This
);
1310 new_This
->tip_index
= This
->tip_index
;
1311 lstrcpynW(new_This
->szwCurrentClsid
,This
->szwCurrentClsid
,39);
1316 static const WCHAR fmt
[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
1318 sprintfW(fullkey
,fmt
,This
->szwCurrentClsid
,szwLngp
,This
->langid
);
1319 res
= RegOpenKeyExW(new_This
->tipkey
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &This
->langkey
);
1320 new_This
->lang_index
= This
->lang_index
;
1322 *ppenum
= &new_This
->IEnumTfLanguageProfiles_iface
;
1327 static const IEnumTfLanguageProfilesVtbl EnumTfLanguageProfilesVtbl
=
1329 EnumTfLanguageProfiles_QueryInterface
,
1330 EnumTfLanguageProfiles_AddRef
,
1331 EnumTfLanguageProfiles_Release
,
1332 EnumTfLanguageProfiles_Clone
,
1333 EnumTfLanguageProfiles_Next
,
1334 EnumTfLanguageProfiles_Reset
,
1335 EnumTfLanguageProfiles_Skip
1338 static HRESULT
EnumTfLanguageProfiles_Constructor(LANGID langid
, EnumTfLanguageProfiles
**out
)
1341 EnumTfLanguageProfiles
*This
;
1343 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(EnumTfLanguageProfiles
));
1345 return E_OUTOFMEMORY
;
1347 This
->IEnumTfLanguageProfiles_iface
.lpVtbl
= &EnumTfLanguageProfilesVtbl
;
1349 This
->langid
= langid
;
1351 hr
= CategoryMgr_Constructor(NULL
,(IUnknown
**)&This
->catmgr
);
1354 HeapFree(GetProcessHeap(),0,This
);
1358 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
, szwSystemTIPKey
, 0, NULL
, 0,
1359 KEY_READ
| KEY_WRITE
, NULL
, &This
->tipkey
, NULL
) != ERROR_SUCCESS
)
1361 HeapFree(GetProcessHeap(), 0, This
);
1366 TRACE("returning %p\n", *out
);