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
25 #include "wine/debug.h"
36 #include "msctf_internal.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(msctf
);
40 static const WCHAR szwLngp
[] = {'L','a','n','g','u','a','g','e','P','r','o','f','i','l','e',0};
41 static const WCHAR szwEnable
[] = {'E','n','a','b','l','e',0};
42 static const WCHAR szwTipfmt
[] = {'%','s','\\','%','s',0};
43 static const WCHAR szwFullLangfmt
[] = {'%','s','\\','%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
45 static const WCHAR szwAssemblies
[] = {'A','s','s','e','m','b','l','i','e','s',0};
46 static const WCHAR szwDefault
[] = {'D','e','f','a','u','l','t',0};
47 static const WCHAR szwProfile
[] = {'P','r','o','f','i','l','e',0};
48 static const WCHAR szwDefaultFmt
[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
50 typedef struct tagInputProcessorProfiles
{
51 ITfInputProcessorProfiles ITfInputProcessorProfiles_iface
;
52 ITfSource ITfSource_iface
;
53 ITfInputProcessorProfileMgr ITfInputProcessorProfileMgr_iface
;
54 /* const ITfInputProcessorProfilesExVtbl *InputProcessorProfilesExVtbl; */
55 /* const ITfInputProcessorProfileSubstituteLayoutVtbl *InputProcessorProfileSubstituteLayoutVtbl; */
58 LANGID currentLanguage
;
60 struct list LanguageProfileNotifySink
;
61 } InputProcessorProfiles
;
63 typedef struct tagProfilesEnumGuid
{
64 IEnumGUID IEnumGUID_iface
;
71 typedef struct tagEnumTfLanguageProfiles
{
72 IEnumTfLanguageProfiles IEnumTfLanguageProfiles_iface
;
77 WCHAR szwCurrentClsid
[39];
83 ITfCategoryMgr
*catmgr
;
84 } EnumTfLanguageProfiles
;
87 IEnumTfInputProcessorProfiles IEnumTfInputProcessorProfiles_iface
;
89 } EnumTfInputProcessorProfiles
;
91 static HRESULT
ProfilesEnumGuid_Constructor(IEnumGUID
**ppOut
);
92 static HRESULT
EnumTfLanguageProfiles_Constructor(LANGID langid
, EnumTfLanguageProfiles
**out
);
94 static inline EnumTfInputProcessorProfiles
*impl_from_IEnumTfInputProcessorProfiles(IEnumTfInputProcessorProfiles
*iface
)
96 return CONTAINING_RECORD(iface
, EnumTfInputProcessorProfiles
, IEnumTfInputProcessorProfiles_iface
);
99 static HRESULT WINAPI
EnumTfInputProcessorProfiles_QueryInterface(IEnumTfInputProcessorProfiles
*iface
,
100 REFIID riid
, void **ppv
)
102 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
104 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
105 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
106 *ppv
= &This
->IEnumTfInputProcessorProfiles_iface
;
107 }else if(IsEqualGUID(riid
, &IID_IEnumTfInputProcessorProfiles
)) {
108 TRACE("(%p)->(IID_IEnumTfInputProcessorProfiles %p)\n", This
, ppv
);
109 *ppv
= &This
->IEnumTfInputProcessorProfiles_iface
;
112 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
113 return E_NOINTERFACE
;
116 IUnknown_AddRef((IUnknown
*)*ppv
);
120 static ULONG WINAPI
EnumTfInputProcessorProfiles_AddRef(IEnumTfInputProcessorProfiles
*iface
)
122 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
123 LONG ref
= InterlockedIncrement(&This
->ref
);
125 TRACE("(%p) ref=%ld\n", This
, ref
);
130 static ULONG WINAPI
EnumTfInputProcessorProfiles_Release(IEnumTfInputProcessorProfiles
*iface
)
132 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
133 LONG ref
= InterlockedDecrement(&This
->ref
);
135 TRACE("(%p) ref=%ld\n", This
, ref
);
138 HeapFree(GetProcessHeap(), 0, This
);
143 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Clone(IEnumTfInputProcessorProfiles
*iface
,
144 IEnumTfInputProcessorProfiles
**ret
)
146 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
147 FIXME("(%p)->(%p)\n", This
, ret
);
151 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Next(IEnumTfInputProcessorProfiles
*iface
, ULONG count
,
152 TF_INPUTPROCESSORPROFILE
*profile
, ULONG
*fetch
)
154 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
156 FIXME("(%p)->(%lu %p %p)\n", This
, count
, profile
, fetch
);
163 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Reset(IEnumTfInputProcessorProfiles
*iface
)
165 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
166 FIXME("(%p)\n", This
);
170 static HRESULT WINAPI
EnumTfInputProcessorProfiles_Skip(IEnumTfInputProcessorProfiles
*iface
, ULONG count
)
172 EnumTfInputProcessorProfiles
*This
= impl_from_IEnumTfInputProcessorProfiles(iface
);
173 FIXME("(%p)->(%lu)\n", This
, count
);
177 static const IEnumTfInputProcessorProfilesVtbl EnumTfInputProcessorProfilesVtbl
= {
178 EnumTfInputProcessorProfiles_QueryInterface
,
179 EnumTfInputProcessorProfiles_AddRef
,
180 EnumTfInputProcessorProfiles_Release
,
181 EnumTfInputProcessorProfiles_Clone
,
182 EnumTfInputProcessorProfiles_Next
,
183 EnumTfInputProcessorProfiles_Reset
,
184 EnumTfInputProcessorProfiles_Skip
187 static inline InputProcessorProfiles
*impl_from_ITfInputProcessorProfiles(ITfInputProcessorProfiles
*iface
)
189 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfInputProcessorProfiles_iface
);
192 static inline InputProcessorProfiles
*impl_from_ITfSource(ITfSource
*iface
)
194 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfSource_iface
);
197 static inline ProfilesEnumGuid
*impl_from_IEnumGUID(IEnumGUID
*iface
)
199 return CONTAINING_RECORD(iface
, ProfilesEnumGuid
, IEnumGUID_iface
);
202 static inline EnumTfLanguageProfiles
*impl_from_IEnumTfLanguageProfiles(IEnumTfLanguageProfiles
*iface
)
204 return CONTAINING_RECORD(iface
, EnumTfLanguageProfiles
, IEnumTfLanguageProfiles_iface
);
207 static void InputProcessorProfiles_Destructor(InputProcessorProfiles
*This
)
209 TRACE("destroying %p\n", This
);
211 free_sinks(&This
->LanguageProfileNotifySink
);
212 HeapFree(GetProcessHeap(),0,This
);
215 static void add_userkey( REFCLSID rclsid
, LANGID langid
,
222 DWORD disposition
= 0;
227 StringFromGUID2(rclsid
, buf
, 39);
228 StringFromGUID2(guidProfile
, buf2
, 39);
229 swprintf(fullkey
,ARRAY_SIZE(fullkey
),szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
231 res
= RegCreateKeyExW(HKEY_CURRENT_USER
,fullkey
, 0, NULL
, 0,
232 KEY_READ
| KEY_WRITE
, NULL
, &key
, &disposition
);
234 if (!res
&& disposition
== REG_CREATED_NEW_KEY
)
237 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&zero
, sizeof(DWORD
));
244 static HRESULT WINAPI
InputProcessorProfiles_QueryInterface(ITfInputProcessorProfiles
*iface
, REFIID iid
, void **ppv
)
246 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
248 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfInputProcessorProfiles
))
250 *ppv
= &This
->ITfInputProcessorProfiles_iface
;
252 else if (IsEqualIID(iid
, &IID_ITfInputProcessorProfileMgr
))
254 *ppv
= &This
->ITfInputProcessorProfileMgr_iface
;
256 else if (IsEqualIID(iid
, &IID_ITfSource
))
258 *ppv
= &This
->ITfSource_iface
;
263 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
264 return E_NOINTERFACE
;
267 ITfInputProcessorProfiles_AddRef(iface
);
271 static ULONG WINAPI
InputProcessorProfiles_AddRef(ITfInputProcessorProfiles
*iface
)
273 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
274 return InterlockedIncrement(&This
->refCount
);
277 static ULONG WINAPI
InputProcessorProfiles_Release(ITfInputProcessorProfiles
*iface
)
279 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
282 ret
= InterlockedDecrement(&This
->refCount
);
284 InputProcessorProfiles_Destructor(This
);
288 /*****************************************************
289 * ITfInputProcessorProfiles functions
290 *****************************************************/
291 static HRESULT WINAPI
InputProcessorProfiles_Register(
292 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
)
294 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
299 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
301 StringFromGUID2(rclsid
, buf
, 39);
302 swprintf(fullkey
,ARRAY_SIZE(fullkey
),szwTipfmt
,szwSystemTIPKey
,buf
);
304 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,fullkey
, 0, NULL
, 0,
305 KEY_READ
| KEY_WRITE
, NULL
, &tipkey
, NULL
) != ERROR_SUCCESS
)
313 static HRESULT WINAPI
InputProcessorProfiles_Unregister(
314 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
)
316 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
320 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
322 StringFromGUID2(rclsid
, buf
, 39);
323 swprintf(fullkey
,ARRAY_SIZE(fullkey
),szwTipfmt
,szwSystemTIPKey
,buf
);
325 RegDeleteTreeW(HKEY_LOCAL_MACHINE
, fullkey
);
326 RegDeleteTreeW(HKEY_CURRENT_USER
, fullkey
);
331 static HRESULT WINAPI
InputProcessorProfiles_AddLanguageProfile(
332 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
,
333 LANGID langid
, REFGUID guidProfile
, const WCHAR
*pchDesc
,
334 ULONG cchDesc
, const WCHAR
*pchIconFile
, ULONG cchFile
,
337 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
342 DWORD disposition
= 0;
344 static const WCHAR fmt2
[] = {'%','s','\\','0','x','%','0','8','x','\\','%','s',0};
345 static const WCHAR desc
[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
346 static const WCHAR icnf
[] = {'I','c','o','n','F','i','l','e',0};
347 static const WCHAR icni
[] = {'I','c','o','n','I','n','d','e','x',0};
349 TRACE("(%p) %s %x %s %s %s %li\n",This
,debugstr_guid(rclsid
), langid
,
350 debugstr_guid(guidProfile
), debugstr_wn(pchDesc
,cchDesc
),
351 debugstr_wn(pchIconFile
,cchFile
),uIconIndex
);
353 StringFromGUID2(rclsid
, buf
, 39);
354 swprintf(fullkey
,ARRAY_SIZE(fullkey
),szwTipfmt
,szwSystemTIPKey
,buf
);
356 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,fullkey
, 0, KEY_READ
| KEY_WRITE
,
357 &tipkey
) != ERROR_SUCCESS
)
360 StringFromGUID2(guidProfile
, buf
, 39);
361 swprintf(fullkey
,ARRAY_SIZE(fullkey
),fmt2
,szwLngp
,langid
,buf
);
363 res
= RegCreateKeyExW(tipkey
,fullkey
, 0, NULL
, 0, KEY_READ
| KEY_WRITE
,
364 NULL
, &fmtkey
, &disposition
);
369 RegSetValueExW(fmtkey
, desc
, 0, REG_SZ
, (const BYTE
*)pchDesc
, cchDesc
* sizeof(WCHAR
));
370 RegSetValueExW(fmtkey
, icnf
, 0, REG_SZ
, (const BYTE
*)pchIconFile
, cchFile
* sizeof(WCHAR
));
371 RegSetValueExW(fmtkey
, icni
, 0, REG_DWORD
, (LPBYTE
)&uIconIndex
, sizeof(DWORD
));
372 if (disposition
== REG_CREATED_NEW_KEY
)
373 RegSetValueExW(fmtkey
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&zero
, sizeof(DWORD
));
376 add_userkey(rclsid
, langid
, guidProfile
);
386 static HRESULT WINAPI
InputProcessorProfiles_RemoveLanguageProfile(
387 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
390 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
391 FIXME("STUB:(%p)\n",This
);
395 static HRESULT WINAPI
InputProcessorProfiles_EnumInputProcessorInfo(
396 ITfInputProcessorProfiles
*iface
, IEnumGUID
**ppEnum
)
398 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
399 TRACE("(%p) %p\n",This
,ppEnum
);
400 return ProfilesEnumGuid_Constructor(ppEnum
);
403 static HRESULT WINAPI
InputProcessorProfiles_GetDefaultLanguageProfile(
404 ITfInputProcessorProfiles
*iface
, LANGID langid
, REFGUID catid
,
405 CLSID
*pclsid
, GUID
*pguidProfile
)
407 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
414 TRACE("%p) %x %s %p %p\n",This
, langid
, debugstr_guid(catid
),pclsid
,pguidProfile
);
416 if (!catid
|| !pclsid
|| !pguidProfile
)
419 StringFromGUID2(catid
, buf
, 39);
420 swprintf(fullkey
, ARRAY_SIZE(fullkey
), szwDefaultFmt
, szwSystemCTFKey
, szwAssemblies
, langid
, buf
);
422 if (RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
,
423 &hkey
) != ERROR_SUCCESS
)
427 res
= RegQueryValueExW(hkey
, szwDefault
, 0, NULL
, (LPBYTE
)buf
, &count
);
428 if (res
!= ERROR_SUCCESS
)
433 CLSIDFromString(buf
,pclsid
);
436 res
= RegQueryValueExW(hkey
, szwProfile
, 0, NULL
, (LPBYTE
)buf
, &count
);
437 if (res
== ERROR_SUCCESS
)
438 CLSIDFromString(buf
,pguidProfile
);
445 static HRESULT WINAPI
InputProcessorProfiles_SetDefaultLanguageProfile(
446 ITfInputProcessorProfiles
*iface
, LANGID langid
, REFCLSID rclsid
,
447 REFGUID guidProfiles
)
449 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
455 ITfCategoryMgr
*catmgr
;
456 static const GUID
* tipcats
[3] = { &GUID_TFCAT_TIP_KEYBOARD
,
457 &GUID_TFCAT_TIP_SPEECH
,
458 &GUID_TFCAT_TIP_HANDWRITING
};
460 TRACE("%p) %x %s %s\n",This
, langid
, debugstr_guid(rclsid
),debugstr_guid(guidProfiles
));
462 if (!rclsid
|| !guidProfiles
)
465 hr
= CategoryMgr_Constructor(NULL
,(IUnknown
**)&catmgr
);
470 if (ITfCategoryMgr_FindClosestCategory(catmgr
, rclsid
,
471 &catid
, tipcats
, 3) != S_OK
)
472 hr
= ITfCategoryMgr_FindClosestCategory(catmgr
, rclsid
,
474 ITfCategoryMgr_Release(catmgr
);
479 StringFromGUID2(&catid
, buf
, 39);
480 swprintf(fullkey
, ARRAY_SIZE(fullkey
), szwDefaultFmt
, szwSystemCTFKey
, szwAssemblies
, langid
, buf
);
482 if (RegCreateKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, NULL
, 0, KEY_READ
| KEY_WRITE
,
483 NULL
, &hkey
, NULL
) != ERROR_SUCCESS
)
486 StringFromGUID2(rclsid
, buf
, 39);
487 RegSetValueExW(hkey
, szwDefault
, 0, REG_SZ
, (LPBYTE
)buf
, sizeof(buf
));
488 StringFromGUID2(guidProfiles
, buf
, 39);
489 RegSetValueExW(hkey
, szwProfile
, 0, REG_SZ
, (LPBYTE
)buf
, sizeof(buf
));
495 static HRESULT WINAPI
InputProcessorProfiles_ActivateLanguageProfile(
496 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
497 REFGUID guidProfiles
)
499 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
502 TF_LANGUAGEPROFILE LanguageProfile
;
504 TRACE("(%p) %s %x %s\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfiles
));
506 if (langid
!= This
->currentLanguage
) return E_INVALIDARG
;
508 if (get_active_textservice(rclsid
,NULL
))
510 TRACE("Already Active\n");
514 hr
= ITfInputProcessorProfiles_IsEnabledLanguageProfile(iface
, rclsid
,
515 langid
, guidProfiles
, &enabled
);
516 if (FAILED(hr
) || !enabled
)
518 TRACE("Not Enabled\n");
522 LanguageProfile
.clsid
= *rclsid
;
523 LanguageProfile
.langid
= langid
;
524 LanguageProfile
.guidProfile
= *guidProfiles
;
525 LanguageProfile
.fActive
= TRUE
;
527 return add_active_textservice(&LanguageProfile
);
530 static HRESULT WINAPI
InputProcessorProfiles_GetActiveLanguageProfile(
531 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID
*plangid
,
534 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
535 TF_LANGUAGEPROFILE profile
;
537 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(rclsid
),plangid
,pguidProfile
);
539 if (!rclsid
|| !plangid
|| !pguidProfile
)
542 if (get_active_textservice(rclsid
, &profile
))
544 *plangid
= profile
.langid
;
545 *pguidProfile
= profile
.guidProfile
;
550 *pguidProfile
= GUID_NULL
;
555 static HRESULT WINAPI
InputProcessorProfiles_GetLanguageProfileDescription(
556 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
557 REFGUID guidProfile
, BSTR
*pbstrProfile
)
559 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
560 FIXME("STUB:(%p)\n",This
);
564 static HRESULT WINAPI
InputProcessorProfiles_GetCurrentLanguage(
565 ITfInputProcessorProfiles
*iface
, LANGID
*plangid
)
567 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
568 TRACE("(%p) 0x%x\n",This
,This
->currentLanguage
);
573 *plangid
= This
->currentLanguage
;
578 static HRESULT WINAPI
InputProcessorProfiles_ChangeCurrentLanguage(
579 ITfInputProcessorProfiles
*iface
, LANGID langid
)
581 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
582 ITfLanguageProfileNotifySink
*sink
;
586 FIXME("STUB:(%p)\n",This
);
588 SINK_FOR_EACH(cursor
, &This
->LanguageProfileNotifySink
, ITfLanguageProfileNotifySink
, sink
)
591 ITfLanguageProfileNotifySink_OnLanguageChange(sink
, langid
, &accept
);
596 /* TODO: On successful language change call OnLanguageChanged sink */
600 static HRESULT WINAPI
InputProcessorProfiles_GetLanguageList(
601 ITfInputProcessorProfiles
*iface
, LANGID
**ppLangId
, ULONG
*pulCount
)
603 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
604 FIXME("Semi-STUB:(%p)\n",This
);
605 *ppLangId
= CoTaskMemAlloc(sizeof(LANGID
));
606 **ppLangId
= This
->currentLanguage
;
611 static HRESULT WINAPI
InputProcessorProfiles_EnumLanguageProfiles(
612 ITfInputProcessorProfiles
*iface
, LANGID langid
,
613 IEnumTfLanguageProfiles
**ppEnum
)
615 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
616 EnumTfLanguageProfiles
*profenum
;
619 TRACE("(%p) %x %p\n",This
,langid
,ppEnum
);
623 hr
= EnumTfLanguageProfiles_Constructor(langid
, &profenum
);
624 *ppEnum
= &profenum
->IEnumTfLanguageProfiles_iface
;
629 static HRESULT WINAPI
InputProcessorProfiles_EnableLanguageProfile(
630 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
631 REFGUID guidProfile
, BOOL fEnable
)
633 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
640 TRACE("(%p) %s %x %s %i\n",This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
), fEnable
);
642 StringFromGUID2(rclsid
, buf
, 39);
643 StringFromGUID2(guidProfile
, buf2
, 39);
644 swprintf(fullkey
,ARRAY_SIZE(fullkey
),szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
646 res
= RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
650 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&fEnable
, sizeof(DWORD
));
659 static HRESULT WINAPI
InputProcessorProfiles_IsEnabledLanguageProfile(
660 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
661 REFGUID guidProfile
, BOOL
*pfEnable
)
663 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
670 TRACE("(%p) %s, %i, %s, %p\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfile
),pfEnable
);
675 StringFromGUID2(rclsid
, buf
, 39);
676 StringFromGUID2(guidProfile
, buf2
, 39);
677 swprintf(fullkey
,ARRAY_SIZE(fullkey
),szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
679 res
= RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
683 DWORD count
= sizeof(DWORD
);
684 res
= RegQueryValueExW(key
, szwEnable
, 0, NULL
, (LPBYTE
)pfEnable
, &count
);
688 if (res
) /* Try Default */
690 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
694 DWORD count
= sizeof(DWORD
);
695 res
= RegQueryValueExW(key
, szwEnable
, 0, NULL
, (LPBYTE
)pfEnable
, &count
);
706 static HRESULT WINAPI
InputProcessorProfiles_EnableLanguageProfileByDefault(
707 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
708 REFGUID guidProfile
, BOOL fEnable
)
710 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
717 TRACE("(%p) %s %x %s %i\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfile
),fEnable
);
719 StringFromGUID2(rclsid
, buf
, 39);
720 StringFromGUID2(guidProfile
, buf2
, 39);
721 swprintf(fullkey
,ARRAY_SIZE(fullkey
),szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
723 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
727 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&fEnable
, sizeof(DWORD
));
736 static HRESULT WINAPI
InputProcessorProfiles_SubstituteKeyboardLayout(
737 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
738 REFGUID guidProfile
, HKL hKL
)
740 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
741 FIXME("STUB:(%p)\n",This
);
745 static const ITfInputProcessorProfilesVtbl InputProcessorProfilesVtbl
=
747 InputProcessorProfiles_QueryInterface
,
748 InputProcessorProfiles_AddRef
,
749 InputProcessorProfiles_Release
,
750 InputProcessorProfiles_Register
,
751 InputProcessorProfiles_Unregister
,
752 InputProcessorProfiles_AddLanguageProfile
,
753 InputProcessorProfiles_RemoveLanguageProfile
,
754 InputProcessorProfiles_EnumInputProcessorInfo
,
755 InputProcessorProfiles_GetDefaultLanguageProfile
,
756 InputProcessorProfiles_SetDefaultLanguageProfile
,
757 InputProcessorProfiles_ActivateLanguageProfile
,
758 InputProcessorProfiles_GetActiveLanguageProfile
,
759 InputProcessorProfiles_GetLanguageProfileDescription
,
760 InputProcessorProfiles_GetCurrentLanguage
,
761 InputProcessorProfiles_ChangeCurrentLanguage
,
762 InputProcessorProfiles_GetLanguageList
,
763 InputProcessorProfiles_EnumLanguageProfiles
,
764 InputProcessorProfiles_EnableLanguageProfile
,
765 InputProcessorProfiles_IsEnabledLanguageProfile
,
766 InputProcessorProfiles_EnableLanguageProfileByDefault
,
767 InputProcessorProfiles_SubstituteKeyboardLayout
770 static inline InputProcessorProfiles
*impl_from_ITfInputProcessorProfileMgr(ITfInputProcessorProfileMgr
*iface
)
772 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfInputProcessorProfileMgr_iface
);
775 static HRESULT WINAPI
InputProcessorProfileMgr_QueryInterface(ITfInputProcessorProfileMgr
*iface
, REFIID riid
, void **ppv
)
777 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
778 return ITfInputProcessorProfiles_QueryInterface(&This
->ITfInputProcessorProfiles_iface
, riid
, ppv
);
781 static ULONG WINAPI
InputProcessorProfileMgr_AddRef(ITfInputProcessorProfileMgr
*iface
)
783 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
784 return ITfInputProcessorProfiles_AddRef(&This
->ITfInputProcessorProfiles_iface
);
787 static ULONG WINAPI
InputProcessorProfileMgr_Release(ITfInputProcessorProfileMgr
*iface
)
789 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
790 return ITfInputProcessorProfiles_Release(&This
->ITfInputProcessorProfiles_iface
);
793 static HRESULT WINAPI
InputProcessorProfileMgr_ActivateProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
794 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, DWORD dwFlags
)
796 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
797 FIXME("(%p)->(%ld %x %s %s %p %lx)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
798 debugstr_guid(guidProfile
), hkl
, dwFlags
);
802 static HRESULT WINAPI
InputProcessorProfileMgr_DeactivateProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
803 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, DWORD dwFlags
)
805 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
806 FIXME("(%p)->(%ld %x %s %s %p %lx)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
807 debugstr_guid(guidProfile
), hkl
, dwFlags
);
811 static HRESULT WINAPI
InputProcessorProfileMgr_GetProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
812 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, TF_INPUTPROCESSORPROFILE
*pProfile
)
814 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
815 FIXME("(%p)->(%ld %x %s %s %p %p)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
816 debugstr_guid(guidProfile
), hkl
, pProfile
);
820 static HRESULT WINAPI
InputProcessorProfileMgr_EnumProfiles(ITfInputProcessorProfileMgr
*iface
, LANGID langid
,
821 IEnumTfInputProcessorProfiles
**ppEnum
)
823 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
824 EnumTfInputProcessorProfiles
*enum_profiles
;
826 TRACE("(%p)->(%x %p)\n", This
, langid
, ppEnum
);
828 enum_profiles
= HeapAlloc(GetProcessHeap(), 0, sizeof(*enum_profiles
));
830 return E_OUTOFMEMORY
;
832 enum_profiles
->IEnumTfInputProcessorProfiles_iface
.lpVtbl
= &EnumTfInputProcessorProfilesVtbl
;
833 enum_profiles
->ref
= 1;
835 *ppEnum
= &enum_profiles
->IEnumTfInputProcessorProfiles_iface
;
839 static HRESULT WINAPI
InputProcessorProfileMgr_ReleaseInputProcessor(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
842 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
843 FIXME("(%p)->(%s %lx)\n", This
, debugstr_guid(rclsid
), dwFlags
);
847 static HRESULT WINAPI
InputProcessorProfileMgr_RegisterProfile(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
848 LANGID langid
, REFGUID guidProfile
, const WCHAR
*pchDesc
, ULONG cchDesc
, const WCHAR
*pchIconFile
,
849 ULONG cchFile
, ULONG uIconIndex
, HKL hklsubstitute
, DWORD dwPreferredLayout
, BOOL bEnabledByDefault
,
852 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
853 FIXME("(%p)->(%s %x %s %s %ld %s %lu %lu %p %lx %x %lx)\n", This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
),
854 debugstr_w(pchDesc
), cchDesc
, debugstr_w(pchIconFile
), cchFile
, uIconIndex
, hklsubstitute
, dwPreferredLayout
,
855 bEnabledByDefault
, dwFlags
);
859 static HRESULT WINAPI
InputProcessorProfileMgr_UnregisterProfile(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
860 LANGID langid
, REFGUID guidProfile
, DWORD dwFlags
)
862 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
863 FIXME("(%p)->(%s %x %s %lx)\n", This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
), dwFlags
);
867 static HRESULT WINAPI
InputProcessorProfileMgr_GetActiveProfile(ITfInputProcessorProfileMgr
*iface
, REFGUID catid
,
868 TF_INPUTPROCESSORPROFILE
*pProfile
)
874 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
875 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(catid
), pProfile
);
881 static const ITfInputProcessorProfileMgrVtbl InputProcessorProfileMgrVtbl
= {
882 InputProcessorProfileMgr_QueryInterface
,
883 InputProcessorProfileMgr_AddRef
,
884 InputProcessorProfileMgr_Release
,
885 InputProcessorProfileMgr_ActivateProfile
,
886 InputProcessorProfileMgr_DeactivateProfile
,
887 InputProcessorProfileMgr_GetProfile
,
888 InputProcessorProfileMgr_EnumProfiles
,
889 InputProcessorProfileMgr_ReleaseInputProcessor
,
890 InputProcessorProfileMgr_RegisterProfile
,
891 InputProcessorProfileMgr_UnregisterProfile
,
892 InputProcessorProfileMgr_GetActiveProfile
895 /*****************************************************
896 * ITfSource functions
897 *****************************************************/
898 static HRESULT WINAPI
IPPSource_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
900 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
901 return ITfInputProcessorProfiles_QueryInterface(&This
->ITfInputProcessorProfiles_iface
, iid
, ppvOut
);
904 static ULONG WINAPI
IPPSource_AddRef(ITfSource
*iface
)
906 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
907 return ITfInputProcessorProfiles_AddRef(&This
->ITfInputProcessorProfiles_iface
);
910 static ULONG WINAPI
IPPSource_Release(ITfSource
*iface
)
912 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
913 return ITfInputProcessorProfiles_Release(&This
->ITfInputProcessorProfiles_iface
);
916 static HRESULT WINAPI
IPPSource_AdviseSink(ITfSource
*iface
,
917 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
919 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
921 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
923 if (!riid
|| !punk
|| !pdwCookie
)
926 if (IsEqualIID(riid
, &IID_ITfLanguageProfileNotifySink
))
927 return advise_sink(&This
->LanguageProfileNotifySink
, &IID_ITfLanguageProfileNotifySink
,
928 COOKIE_MAGIC_IPPSINK
, punk
, pdwCookie
);
930 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
934 static HRESULT WINAPI
IPPSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
936 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
938 TRACE("(%p) %lx\n",This
,pdwCookie
);
940 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_IPPSINK
)
943 return unadvise_sink(pdwCookie
);
946 static const ITfSourceVtbl InputProcessorProfilesSourceVtbl
=
948 IPPSource_QueryInterface
,
951 IPPSource_AdviseSink
,
952 IPPSource_UnadviseSink
,
955 HRESULT
InputProcessorProfiles_Constructor(IUnknown
*pUnkOuter
, IUnknown
**ppOut
)
957 InputProcessorProfiles
*This
;
959 return CLASS_E_NOAGGREGATION
;
961 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(InputProcessorProfiles
));
963 return E_OUTOFMEMORY
;
965 This
->ITfInputProcessorProfiles_iface
.lpVtbl
= &InputProcessorProfilesVtbl
;
966 This
->ITfSource_iface
.lpVtbl
= &InputProcessorProfilesSourceVtbl
;
967 This
->ITfInputProcessorProfileMgr_iface
.lpVtbl
= &InputProcessorProfileMgrVtbl
;
969 This
->currentLanguage
= GetUserDefaultLCID();
971 list_init(&This
->LanguageProfileNotifySink
);
973 *ppOut
= (IUnknown
*)&This
->ITfInputProcessorProfiles_iface
;
974 TRACE("returning %p\n", *ppOut
);
978 /**************************************************
979 * IEnumGUID implementation for ITfInputProcessorProfiles::EnumInputProcessorInfo
980 **************************************************/
981 static void ProfilesEnumGuid_Destructor(ProfilesEnumGuid
*This
)
983 TRACE("destroying %p\n", This
);
984 RegCloseKey(This
->key
);
985 HeapFree(GetProcessHeap(),0,This
);
988 static HRESULT WINAPI
ProfilesEnumGuid_QueryInterface(IEnumGUID
*iface
, REFIID iid
, LPVOID
*ppvOut
)
990 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
993 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumGUID
))
995 *ppvOut
= &This
->IEnumGUID_iface
;
1000 IEnumGUID_AddRef(iface
);
1004 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
1005 return E_NOINTERFACE
;
1008 static ULONG WINAPI
ProfilesEnumGuid_AddRef(IEnumGUID
*iface
)
1010 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1011 return InterlockedIncrement(&This
->refCount
);
1014 static ULONG WINAPI
ProfilesEnumGuid_Release(IEnumGUID
*iface
)
1016 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1019 ret
= InterlockedDecrement(&This
->refCount
);
1021 ProfilesEnumGuid_Destructor(This
);
1025 /*****************************************************
1026 * IEnumGuid functions
1027 *****************************************************/
1028 static HRESULT WINAPI
ProfilesEnumGuid_Next( LPENUMGUID iface
,
1029 ULONG celt
, GUID
*rgelt
, ULONG
*pceltFetched
)
1031 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1034 TRACE("(%p)\n",This
);
1036 if (rgelt
== NULL
) return E_POINTER
;
1038 if (This
->key
) while (fetched
< celt
)
1045 res
= RegEnumKeyExW(This
->key
, This
->next_index
, catid
, &cName
,
1046 NULL
, NULL
, NULL
, NULL
);
1047 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
) break;
1048 ++(This
->next_index
);
1050 hr
= CLSIDFromString(catid
, rgelt
);
1051 if (FAILED(hr
)) continue;
1057 if (pceltFetched
) *pceltFetched
= fetched
;
1058 return fetched
== celt
? S_OK
: S_FALSE
;
1061 static HRESULT WINAPI
ProfilesEnumGuid_Skip( LPENUMGUID iface
, ULONG celt
)
1063 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1064 TRACE("(%p)\n",This
);
1066 This
->next_index
+= celt
;
1070 static HRESULT WINAPI
ProfilesEnumGuid_Reset( LPENUMGUID iface
)
1072 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1073 TRACE("(%p)\n",This
);
1074 This
->next_index
= 0;
1078 static HRESULT WINAPI
ProfilesEnumGuid_Clone( LPENUMGUID iface
,
1081 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1084 TRACE("(%p)\n",This
);
1086 if (ppenum
== NULL
) return E_POINTER
;
1088 res
= ProfilesEnumGuid_Constructor(ppenum
);
1091 ProfilesEnumGuid
*new_This
= impl_from_IEnumGUID(*ppenum
);
1092 new_This
->next_index
= This
->next_index
;
1097 static const IEnumGUIDVtbl EnumGUIDVtbl
=
1099 ProfilesEnumGuid_QueryInterface
,
1100 ProfilesEnumGuid_AddRef
,
1101 ProfilesEnumGuid_Release
,
1102 ProfilesEnumGuid_Next
,
1103 ProfilesEnumGuid_Skip
,
1104 ProfilesEnumGuid_Reset
,
1105 ProfilesEnumGuid_Clone
1108 static HRESULT
ProfilesEnumGuid_Constructor(IEnumGUID
**ppOut
)
1110 ProfilesEnumGuid
*This
;
1112 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ProfilesEnumGuid
));
1114 return E_OUTOFMEMORY
;
1116 This
->IEnumGUID_iface
.lpVtbl
= &EnumGUIDVtbl
;
1119 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
, szwSystemTIPKey
, 0, NULL
, 0,
1120 KEY_READ
| KEY_WRITE
, NULL
, &This
->key
, NULL
) != ERROR_SUCCESS
)
1122 HeapFree(GetProcessHeap(), 0, This
);
1126 *ppOut
= &This
->IEnumGUID_iface
;
1127 TRACE("returning %p\n", *ppOut
);
1131 /**************************************************
1132 * IEnumTfLanguageProfiles implementation
1133 **************************************************/
1134 static void EnumTfLanguageProfiles_Destructor(EnumTfLanguageProfiles
*This
)
1136 TRACE("destroying %p\n", This
);
1137 RegCloseKey(This
->tipkey
);
1139 RegCloseKey(This
->langkey
);
1140 ITfCategoryMgr_Release(This
->catmgr
);
1141 HeapFree(GetProcessHeap(),0,This
);
1144 static HRESULT WINAPI
EnumTfLanguageProfiles_QueryInterface(IEnumTfLanguageProfiles
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1146 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1150 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumTfLanguageProfiles
))
1152 *ppvOut
= &This
->IEnumTfLanguageProfiles_iface
;
1157 IEnumTfLanguageProfiles_AddRef(iface
);
1161 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
1162 return E_NOINTERFACE
;
1165 static ULONG WINAPI
EnumTfLanguageProfiles_AddRef(IEnumTfLanguageProfiles
*iface
)
1167 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1168 return InterlockedIncrement(&This
->refCount
);
1171 static ULONG WINAPI
EnumTfLanguageProfiles_Release(IEnumTfLanguageProfiles
*iface
)
1173 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1176 ret
= InterlockedDecrement(&This
->refCount
);
1178 EnumTfLanguageProfiles_Destructor(This
);
1182 /*****************************************************
1183 * IEnumGuid functions
1184 *****************************************************/
1185 static INT
next_LanguageProfile(EnumTfLanguageProfiles
*This
, CLSID clsid
, TF_LANGUAGEPROFILE
*tflp
)
1189 WCHAR profileid
[39];
1193 static const WCHAR fmt
[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
1195 if (This
->langkey
== NULL
)
1197 swprintf(fullkey
,ARRAY_SIZE(fullkey
),fmt
,This
->szwCurrentClsid
,szwLngp
,This
->langid
);
1198 res
= RegOpenKeyExW(This
->tipkey
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &This
->langkey
);
1201 This
->langkey
= NULL
;
1204 This
->lang_index
= 0;
1206 res
= RegEnumKeyExW(This
->langkey
, This
->lang_index
, profileid
, &cName
,
1207 NULL
, NULL
, NULL
, NULL
);
1208 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
)
1210 RegCloseKey(This
->langkey
);
1211 This
->langkey
= NULL
;
1214 ++(This
->lang_index
);
1218 static const GUID
* tipcats
[3] = { &GUID_TFCAT_TIP_KEYBOARD
,
1219 &GUID_TFCAT_TIP_SPEECH
,
1220 &GUID_TFCAT_TIP_HANDWRITING
};
1221 res
= CLSIDFromString(profileid
, &profile
);
1222 if (FAILED(res
)) return 0;
1224 tflp
->clsid
= clsid
;
1225 tflp
->langid
= This
->langid
;
1226 tflp
->fActive
= get_active_textservice(&clsid
, NULL
);
1227 tflp
->guidProfile
= profile
;
1228 if (ITfCategoryMgr_FindClosestCategory(This
->catmgr
, &clsid
,
1229 &tflp
->catid
, tipcats
, 3) != S_OK
)
1230 ITfCategoryMgr_FindClosestCategory(This
->catmgr
, &clsid
,
1231 &tflp
->catid
, NULL
, 0);
1237 static HRESULT WINAPI
EnumTfLanguageProfiles_Next(IEnumTfLanguageProfiles
*iface
,
1238 ULONG ulCount
, TF_LANGUAGEPROFILE
*pProfile
, ULONG
*pcFetch
)
1240 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1243 TRACE("(%p)\n",This
);
1245 if (pProfile
== NULL
) return E_POINTER
;
1247 if (This
->tipkey
) while (fetched
< ulCount
)
1254 res
= RegEnumKeyExW(This
->tipkey
, This
->tip_index
,
1255 This
->szwCurrentClsid
, &cName
, NULL
, NULL
, NULL
, NULL
);
1256 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
) break;
1257 ++(This
->tip_index
);
1258 hr
= CLSIDFromString(This
->szwCurrentClsid
, &clsid
);
1259 if (FAILED(hr
)) continue;
1261 while ( fetched
< ulCount
)
1263 INT res
= next_LanguageProfile(This
, clsid
, pProfile
);
1276 if (pcFetch
) *pcFetch
= fetched
;
1277 return fetched
== ulCount
? S_OK
: S_FALSE
;
1280 static HRESULT WINAPI
EnumTfLanguageProfiles_Skip( IEnumTfLanguageProfiles
* iface
, ULONG celt
)
1282 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1283 FIXME("STUB (%p)\n",This
);
1287 static HRESULT WINAPI
EnumTfLanguageProfiles_Reset( IEnumTfLanguageProfiles
* iface
)
1289 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1290 TRACE("(%p)\n",This
);
1291 This
->tip_index
= 0;
1293 RegCloseKey(This
->langkey
);
1294 This
->langkey
= NULL
;
1295 This
->lang_index
= 0;
1299 static HRESULT WINAPI
EnumTfLanguageProfiles_Clone( IEnumTfLanguageProfiles
*iface
,
1300 IEnumTfLanguageProfiles
**ppenum
)
1302 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1303 EnumTfLanguageProfiles
*new_This
;
1306 TRACE("(%p)\n",This
);
1308 if (ppenum
== NULL
) return E_POINTER
;
1310 res
= EnumTfLanguageProfiles_Constructor(This
->langid
, &new_This
);
1313 new_This
->tip_index
= This
->tip_index
;
1314 lstrcpynW(new_This
->szwCurrentClsid
,This
->szwCurrentClsid
,39);
1319 static const WCHAR fmt
[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
1321 swprintf(fullkey
,ARRAY_SIZE(fullkey
),fmt
,This
->szwCurrentClsid
,szwLngp
,This
->langid
);
1322 res
= RegOpenKeyExW(new_This
->tipkey
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &This
->langkey
);
1323 new_This
->lang_index
= This
->lang_index
;
1325 *ppenum
= &new_This
->IEnumTfLanguageProfiles_iface
;
1330 static const IEnumTfLanguageProfilesVtbl EnumTfLanguageProfilesVtbl
=
1332 EnumTfLanguageProfiles_QueryInterface
,
1333 EnumTfLanguageProfiles_AddRef
,
1334 EnumTfLanguageProfiles_Release
,
1335 EnumTfLanguageProfiles_Clone
,
1336 EnumTfLanguageProfiles_Next
,
1337 EnumTfLanguageProfiles_Reset
,
1338 EnumTfLanguageProfiles_Skip
1341 static HRESULT
EnumTfLanguageProfiles_Constructor(LANGID langid
, EnumTfLanguageProfiles
**out
)
1344 EnumTfLanguageProfiles
*This
;
1346 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(EnumTfLanguageProfiles
));
1348 return E_OUTOFMEMORY
;
1350 This
->IEnumTfLanguageProfiles_iface
.lpVtbl
= &EnumTfLanguageProfilesVtbl
;
1352 This
->langid
= langid
;
1354 hr
= CategoryMgr_Constructor(NULL
,(IUnknown
**)&This
->catmgr
);
1357 HeapFree(GetProcessHeap(),0,This
);
1361 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
, szwSystemTIPKey
, 0, NULL
, 0,
1362 KEY_READ
| KEY_WRITE
, NULL
, &This
->tipkey
, NULL
) != ERROR_SUCCESS
)
1364 HeapFree(GetProcessHeap(), 0, This
);
1369 TRACE("returning %p\n", *out
);