2 * ITfInputProcessorProfiles implementation
4 * Copyright 2009 Aric Stewart, CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/debug.h"
37 #include "wine/unicode.h"
38 #include "wine/list.h"
41 #include "msctf_internal.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(msctf
);
45 static const WCHAR szwLngp
[] = {'L','a','n','g','u','a','g','e','P','r','o','f','i','l','e',0};
46 static const WCHAR szwEnable
[] = {'E','n','a','b','l','e',0};
47 static const WCHAR szwTipfmt
[] = {'%','s','\\','%','s',0};
48 static const WCHAR szwFullLangfmt
[] = {'%','s','\\','%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
50 static const WCHAR szwAssemblies
[] = {'A','s','s','e','m','b','l','i','e','s',0};
51 static const WCHAR szwDefault
[] = {'D','e','f','a','u','l','t',0};
52 static const WCHAR szwProfile
[] = {'P','r','o','f','i','l','e',0};
53 static const WCHAR szwDefaultFmt
[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
55 typedef struct tagInputProcessorProfilesSink
{
58 /* InputProcessorProfile Sinks */
60 ITfLanguageProfileNotifySink
*pITfLanguageProfileNotifySink
;
62 } InputProcessorProfilesSink
;
64 typedef struct tagInputProcessorProfiles
{
65 ITfInputProcessorProfiles ITfInputProcessorProfiles_iface
;
66 ITfSource ITfSource_iface
;
67 ITfInputProcessorProfileMgr ITfInputProcessorProfileMgr_iface
;
68 /* const ITfInputProcessorProfilesExVtbl *InputProcessorProfilesExVtbl; */
69 /* const ITfInputProcessorProfileSubstituteLayoutVtbl *InputProcessorProfileSubstituteLayoutVtbl; */
72 LANGID currentLanguage
;
74 struct list LanguageProfileNotifySink
;
75 } InputProcessorProfiles
;
77 typedef struct tagProfilesEnumGuid
{
78 IEnumGUID IEnumGUID_iface
;
85 typedef struct tagEnumTfLanguageProfiles
{
86 IEnumTfLanguageProfiles IEnumTfLanguageProfiles_iface
;
91 WCHAR szwCurrentClsid
[39];
97 ITfCategoryMgr
*catmgr
;
98 } EnumTfLanguageProfiles
;
100 static HRESULT
ProfilesEnumGuid_Constructor(IEnumGUID
**ppOut
);
101 static HRESULT
EnumTfLanguageProfiles_Constructor(LANGID langid
, IEnumTfLanguageProfiles
**ppOut
);
103 static inline InputProcessorProfiles
*impl_from_ITfInputProcessorProfiles(ITfInputProcessorProfiles
*iface
)
105 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfInputProcessorProfiles_iface
);
108 static inline InputProcessorProfiles
*impl_from_ITfSource(ITfSource
*iface
)
110 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfSource_iface
);
113 static inline ProfilesEnumGuid
*impl_from_IEnumGUID(IEnumGUID
*iface
)
115 return CONTAINING_RECORD(iface
, ProfilesEnumGuid
, IEnumGUID_iface
);
118 static inline EnumTfLanguageProfiles
*impl_from_IEnumTfLanguageProfiles(IEnumTfLanguageProfiles
*iface
)
120 return CONTAINING_RECORD(iface
, EnumTfLanguageProfiles
, IEnumTfLanguageProfiles_iface
);
123 static void free_sink(InputProcessorProfilesSink
*sink
)
125 IUnknown_Release(sink
->interfaces
.pIUnknown
);
126 HeapFree(GetProcessHeap(),0,sink
);
129 static void InputProcessorProfiles_Destructor(InputProcessorProfiles
*This
)
131 struct list
*cursor
, *cursor2
;
132 TRACE("destroying %p\n", This
);
135 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->LanguageProfileNotifySink
)
137 InputProcessorProfilesSink
* sink
= LIST_ENTRY(cursor
,InputProcessorProfilesSink
,entry
);
142 HeapFree(GetProcessHeap(),0,This
);
145 static void add_userkey( REFCLSID rclsid
, LANGID langid
,
152 DWORD disposition
= 0;
157 StringFromGUID2(rclsid
, buf
, 39);
158 StringFromGUID2(guidProfile
, buf2
, 39);
159 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
161 res
= RegCreateKeyExW(HKEY_CURRENT_USER
,fullkey
, 0, NULL
, 0,
162 KEY_READ
| KEY_WRITE
, NULL
, &key
, &disposition
);
164 if (!res
&& disposition
== REG_CREATED_NEW_KEY
)
167 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&zero
, sizeof(DWORD
));
174 static HRESULT WINAPI
InputProcessorProfiles_QueryInterface(ITfInputProcessorProfiles
*iface
, REFIID iid
, void **ppv
)
176 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
178 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfInputProcessorProfiles
))
180 *ppv
= &This
->ITfInputProcessorProfiles_iface
;
182 else if (IsEqualIID(iid
, &IID_ITfInputProcessorProfileMgr
))
184 *ppv
= &This
->ITfInputProcessorProfileMgr_iface
;
186 else if (IsEqualIID(iid
, &IID_ITfSource
))
188 *ppv
= &This
->ITfSource_iface
;
193 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
194 return E_NOINTERFACE
;
197 ITfInputProcessorProfiles_AddRef(iface
);
201 static ULONG WINAPI
InputProcessorProfiles_AddRef(ITfInputProcessorProfiles
*iface
)
203 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
204 return InterlockedIncrement(&This
->refCount
);
207 static ULONG WINAPI
InputProcessorProfiles_Release(ITfInputProcessorProfiles
*iface
)
209 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
212 ret
= InterlockedDecrement(&This
->refCount
);
214 InputProcessorProfiles_Destructor(This
);
218 /*****************************************************
219 * ITfInputProcessorProfiles functions
220 *****************************************************/
221 static HRESULT WINAPI
InputProcessorProfiles_Register(
222 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
)
224 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
229 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
231 StringFromGUID2(rclsid
, buf
, 39);
232 sprintfW(fullkey
,szwTipfmt
,szwSystemTIPKey
,buf
);
234 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,fullkey
, 0, NULL
, 0,
235 KEY_READ
| KEY_WRITE
, NULL
, &tipkey
, NULL
) != ERROR_SUCCESS
)
243 static HRESULT WINAPI
InputProcessorProfiles_Unregister(
244 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
)
246 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
250 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
252 StringFromGUID2(rclsid
, buf
, 39);
253 sprintfW(fullkey
,szwTipfmt
,szwSystemTIPKey
,buf
);
255 RegDeleteTreeW(HKEY_LOCAL_MACHINE
, fullkey
);
256 RegDeleteTreeW(HKEY_CURRENT_USER
, fullkey
);
261 static HRESULT WINAPI
InputProcessorProfiles_AddLanguageProfile(
262 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
,
263 LANGID langid
, REFGUID guidProfile
, const WCHAR
*pchDesc
,
264 ULONG cchDesc
, const WCHAR
*pchIconFile
, ULONG cchFile
,
267 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
272 DWORD disposition
= 0;
274 static const WCHAR fmt2
[] = {'%','s','\\','0','x','%','0','8','x','\\','%','s',0};
275 static const WCHAR desc
[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
276 static const WCHAR icnf
[] = {'I','c','o','n','F','i','l','e',0};
277 static const WCHAR icni
[] = {'I','c','o','n','I','n','d','e','x',0};
279 TRACE("(%p) %s %x %s %s %s %i\n",This
,debugstr_guid(rclsid
), langid
,
280 debugstr_guid(guidProfile
), debugstr_wn(pchDesc
,cchDesc
),
281 debugstr_wn(pchIconFile
,cchFile
),uIconIndex
);
283 StringFromGUID2(rclsid
, buf
, 39);
284 sprintfW(fullkey
,szwTipfmt
,szwSystemTIPKey
,buf
);
286 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,fullkey
, 0, KEY_READ
| KEY_WRITE
,
287 &tipkey
) != ERROR_SUCCESS
)
290 StringFromGUID2(guidProfile
, buf
, 39);
291 sprintfW(fullkey
,fmt2
,szwLngp
,langid
,buf
);
293 res
= RegCreateKeyExW(tipkey
,fullkey
, 0, NULL
, 0, KEY_READ
| KEY_WRITE
,
294 NULL
, &fmtkey
, &disposition
);
299 RegSetValueExW(fmtkey
, desc
, 0, REG_SZ
, (const BYTE
*)pchDesc
, cchDesc
* sizeof(WCHAR
));
300 RegSetValueExW(fmtkey
, icnf
, 0, REG_SZ
, (const BYTE
*)pchIconFile
, cchFile
* sizeof(WCHAR
));
301 RegSetValueExW(fmtkey
, icni
, 0, REG_DWORD
, (LPBYTE
)&uIconIndex
, sizeof(DWORD
));
302 if (disposition
== REG_CREATED_NEW_KEY
)
303 RegSetValueExW(fmtkey
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&zero
, sizeof(DWORD
));
306 add_userkey(rclsid
, langid
, guidProfile
);
316 static HRESULT WINAPI
InputProcessorProfiles_RemoveLanguageProfile(
317 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
320 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
321 FIXME("STUB:(%p)\n",This
);
325 static HRESULT WINAPI
InputProcessorProfiles_EnumInputProcessorInfo(
326 ITfInputProcessorProfiles
*iface
, IEnumGUID
**ppEnum
)
328 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
329 TRACE("(%p) %p\n",This
,ppEnum
);
330 return ProfilesEnumGuid_Constructor(ppEnum
);
333 static HRESULT WINAPI
InputProcessorProfiles_GetDefaultLanguageProfile(
334 ITfInputProcessorProfiles
*iface
, LANGID langid
, REFGUID catid
,
335 CLSID
*pclsid
, GUID
*pguidProfile
)
337 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
344 TRACE("%p) %x %s %p %p\n",This
, langid
, debugstr_guid(catid
),pclsid
,pguidProfile
);
346 if (!catid
|| !pclsid
|| !pguidProfile
)
349 StringFromGUID2(catid
, buf
, 39);
350 sprintfW(fullkey
, szwDefaultFmt
, szwSystemCTFKey
, szwAssemblies
, langid
, buf
);
352 if (RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
,
353 &hkey
) != ERROR_SUCCESS
)
357 res
= RegQueryValueExW(hkey
, szwDefault
, 0, NULL
, (LPBYTE
)buf
, &count
);
358 if (res
!= ERROR_SUCCESS
)
363 CLSIDFromString(buf
,pclsid
);
365 res
= RegQueryValueExW(hkey
, szwProfile
, 0, NULL
, (LPBYTE
)buf
, &count
);
366 if (res
== ERROR_SUCCESS
)
367 CLSIDFromString(buf
,pguidProfile
);
374 static HRESULT WINAPI
InputProcessorProfiles_SetDefaultLanguageProfile(
375 ITfInputProcessorProfiles
*iface
, LANGID langid
, REFCLSID rclsid
,
376 REFGUID guidProfiles
)
378 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
384 ITfCategoryMgr
*catmgr
;
385 static const GUID
* tipcats
[3] = { &GUID_TFCAT_TIP_KEYBOARD
,
386 &GUID_TFCAT_TIP_SPEECH
,
387 &GUID_TFCAT_TIP_HANDWRITING
};
389 TRACE("%p) %x %s %s\n",This
, langid
, debugstr_guid(rclsid
),debugstr_guid(guidProfiles
));
391 if (!rclsid
|| !guidProfiles
)
394 hr
= CategoryMgr_Constructor(NULL
,(IUnknown
**)&catmgr
);
399 if (ITfCategoryMgr_FindClosestCategory(catmgr
, rclsid
,
400 &catid
, tipcats
, 3) != S_OK
)
401 hr
= ITfCategoryMgr_FindClosestCategory(catmgr
, rclsid
,
403 ITfCategoryMgr_Release(catmgr
);
408 StringFromGUID2(&catid
, buf
, 39);
409 sprintfW(fullkey
, szwDefaultFmt
, szwSystemCTFKey
, szwAssemblies
, langid
, buf
);
411 if (RegCreateKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, NULL
, 0, KEY_READ
| KEY_WRITE
,
412 NULL
, &hkey
, NULL
) != ERROR_SUCCESS
)
415 StringFromGUID2(rclsid
, buf
, 39);
416 RegSetValueExW(hkey
, szwDefault
, 0, REG_SZ
, (LPBYTE
)buf
, sizeof(buf
));
417 StringFromGUID2(guidProfiles
, buf
, 39);
418 RegSetValueExW(hkey
, szwProfile
, 0, REG_SZ
, (LPBYTE
)buf
, sizeof(buf
));
424 static HRESULT WINAPI
InputProcessorProfiles_ActivateLanguageProfile(
425 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
426 REFGUID guidProfiles
)
428 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
431 TF_LANGUAGEPROFILE LanguageProfile
;
433 TRACE("(%p) %s %x %s\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfiles
));
435 if (langid
!= This
->currentLanguage
) return E_INVALIDARG
;
437 if (get_active_textservice(rclsid
,NULL
))
439 TRACE("Already Active\n");
443 hr
= ITfInputProcessorProfiles_IsEnabledLanguageProfile(iface
, rclsid
,
444 langid
, guidProfiles
, &enabled
);
445 if (FAILED(hr
) || !enabled
)
447 TRACE("Not Enabled\n");
451 LanguageProfile
.clsid
= *rclsid
;
452 LanguageProfile
.langid
= langid
;
453 LanguageProfile
.guidProfile
= *guidProfiles
;
455 hr
= add_active_textservice(&LanguageProfile
);
460 static HRESULT WINAPI
InputProcessorProfiles_GetActiveLanguageProfile(
461 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID
*plangid
,
464 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
465 TF_LANGUAGEPROFILE profile
;
467 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(rclsid
),plangid
,pguidProfile
);
469 if (!rclsid
|| !plangid
|| !pguidProfile
)
472 if (get_active_textservice(rclsid
, &profile
))
474 *plangid
= profile
.langid
;
475 *pguidProfile
= profile
.guidProfile
;
480 *pguidProfile
= GUID_NULL
;
485 static HRESULT WINAPI
InputProcessorProfiles_GetLanguageProfileDescription(
486 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
487 REFGUID guidProfile
, BSTR
*pbstrProfile
)
489 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
490 FIXME("STUB:(%p)\n",This
);
494 static HRESULT WINAPI
InputProcessorProfiles_GetCurrentLanguage(
495 ITfInputProcessorProfiles
*iface
, LANGID
*plangid
)
497 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
498 TRACE("(%p) 0x%x\n",This
,This
->currentLanguage
);
503 *plangid
= This
->currentLanguage
;
508 static HRESULT WINAPI
InputProcessorProfiles_ChangeCurrentLanguage(
509 ITfInputProcessorProfiles
*iface
, LANGID langid
)
511 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
515 FIXME("STUB:(%p)\n",This
);
517 LIST_FOR_EACH(cursor
, &This
->LanguageProfileNotifySink
)
519 InputProcessorProfilesSink
* sink
= LIST_ENTRY(cursor
,InputProcessorProfilesSink
,entry
);
521 ITfLanguageProfileNotifySink_OnLanguageChange(sink
->interfaces
.pITfLanguageProfileNotifySink
, langid
, &accept
);
526 /* TODO: On successful language change call OnLanguageChanged sink */
530 static HRESULT WINAPI
InputProcessorProfiles_GetLanguageList(
531 ITfInputProcessorProfiles
*iface
, LANGID
**ppLangId
, ULONG
*pulCount
)
533 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
534 FIXME("Semi-STUB:(%p)\n",This
);
535 *ppLangId
= CoTaskMemAlloc(sizeof(LANGID
));
536 **ppLangId
= This
->currentLanguage
;
541 static HRESULT WINAPI
InputProcessorProfiles_EnumLanguageProfiles(
542 ITfInputProcessorProfiles
*iface
, LANGID langid
,
543 IEnumTfLanguageProfiles
**ppEnum
)
545 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
546 TRACE("(%p) %x %p\n",This
,langid
,ppEnum
);
547 return EnumTfLanguageProfiles_Constructor(langid
, ppEnum
);
550 static HRESULT WINAPI
InputProcessorProfiles_EnableLanguageProfile(
551 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
552 REFGUID guidProfile
, BOOL fEnable
)
554 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
561 TRACE("(%p) %s %x %s %i\n",This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
), fEnable
);
563 StringFromGUID2(rclsid
, buf
, 39);
564 StringFromGUID2(guidProfile
, buf2
, 39);
565 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
567 res
= RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
571 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&fEnable
, sizeof(DWORD
));
580 static HRESULT WINAPI
InputProcessorProfiles_IsEnabledLanguageProfile(
581 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
582 REFGUID guidProfile
, BOOL
*pfEnable
)
584 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
591 TRACE("(%p) %s, %i, %s, %p\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfile
),pfEnable
);
596 StringFromGUID2(rclsid
, buf
, 39);
597 StringFromGUID2(guidProfile
, buf2
, 39);
598 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
600 res
= RegOpenKeyExW(HKEY_CURRENT_USER
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
604 DWORD count
= sizeof(DWORD
);
605 res
= RegQueryValueExW(key
, szwEnable
, 0, NULL
, (LPBYTE
)pfEnable
, &count
);
609 if (res
) /* Try Default */
611 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
615 DWORD count
= sizeof(DWORD
);
616 res
= RegQueryValueExW(key
, szwEnable
, 0, NULL
, (LPBYTE
)pfEnable
, &count
);
627 static HRESULT WINAPI
InputProcessorProfiles_EnableLanguageProfileByDefault(
628 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
629 REFGUID guidProfile
, BOOL fEnable
)
631 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
638 TRACE("(%p) %s %x %s %i\n",This
,debugstr_guid(rclsid
),langid
,debugstr_guid(guidProfile
),fEnable
);
640 StringFromGUID2(rclsid
, buf
, 39);
641 StringFromGUID2(guidProfile
, buf2
, 39);
642 sprintfW(fullkey
,szwFullLangfmt
,szwSystemTIPKey
,buf
,szwLngp
,langid
,buf2
);
644 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &key
);
648 RegSetValueExW(key
, szwEnable
, 0, REG_DWORD
, (LPBYTE
)&fEnable
, sizeof(DWORD
));
657 static HRESULT WINAPI
InputProcessorProfiles_SubstituteKeyboardLayout(
658 ITfInputProcessorProfiles
*iface
, REFCLSID rclsid
, LANGID langid
,
659 REFGUID guidProfile
, HKL hKL
)
661 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfiles(iface
);
662 FIXME("STUB:(%p)\n",This
);
666 static const ITfInputProcessorProfilesVtbl InputProcessorProfilesVtbl
=
668 InputProcessorProfiles_QueryInterface
,
669 InputProcessorProfiles_AddRef
,
670 InputProcessorProfiles_Release
,
671 InputProcessorProfiles_Register
,
672 InputProcessorProfiles_Unregister
,
673 InputProcessorProfiles_AddLanguageProfile
,
674 InputProcessorProfiles_RemoveLanguageProfile
,
675 InputProcessorProfiles_EnumInputProcessorInfo
,
676 InputProcessorProfiles_GetDefaultLanguageProfile
,
677 InputProcessorProfiles_SetDefaultLanguageProfile
,
678 InputProcessorProfiles_ActivateLanguageProfile
,
679 InputProcessorProfiles_GetActiveLanguageProfile
,
680 InputProcessorProfiles_GetLanguageProfileDescription
,
681 InputProcessorProfiles_GetCurrentLanguage
,
682 InputProcessorProfiles_ChangeCurrentLanguage
,
683 InputProcessorProfiles_GetLanguageList
,
684 InputProcessorProfiles_EnumLanguageProfiles
,
685 InputProcessorProfiles_EnableLanguageProfile
,
686 InputProcessorProfiles_IsEnabledLanguageProfile
,
687 InputProcessorProfiles_EnableLanguageProfileByDefault
,
688 InputProcessorProfiles_SubstituteKeyboardLayout
691 static inline InputProcessorProfiles
*impl_from_ITfInputProcessorProfileMgr(ITfInputProcessorProfileMgr
*iface
)
693 return CONTAINING_RECORD(iface
, InputProcessorProfiles
, ITfInputProcessorProfileMgr_iface
);
696 static HRESULT WINAPI
InputProcessorProfileMgr_QueryInterface(ITfInputProcessorProfileMgr
*iface
, REFIID riid
, void **ppv
)
698 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
699 return ITfInputProcessorProfiles_QueryInterface(&This
->ITfInputProcessorProfiles_iface
, riid
, ppv
);
702 static ULONG WINAPI
InputProcessorProfileMgr_AddRef(ITfInputProcessorProfileMgr
*iface
)
704 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
705 return ITfInputProcessorProfiles_AddRef(&This
->ITfInputProcessorProfiles_iface
);
708 static ULONG WINAPI
InputProcessorProfileMgr_Release(ITfInputProcessorProfileMgr
*iface
)
710 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
711 return ITfInputProcessorProfiles_Release(&This
->ITfInputProcessorProfiles_iface
);
714 static HRESULT WINAPI
InputProcessorProfileMgr_ActivateProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
715 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, DWORD dwFlags
)
717 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
718 FIXME("(%p)->(%d %x %s %s %p %x)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
719 debugstr_guid(guidProfile
), hkl
, dwFlags
);
723 static HRESULT WINAPI
InputProcessorProfileMgr_DeactivateProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
724 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, DWORD dwFlags
)
726 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
727 FIXME("(%p)->(%d %x %s %s %p %x)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
728 debugstr_guid(guidProfile
), hkl
, dwFlags
);
732 static HRESULT WINAPI
InputProcessorProfileMgr_GetProfile(ITfInputProcessorProfileMgr
*iface
, DWORD dwProfileType
,
733 LANGID langid
, REFCLSID clsid
, REFGUID guidProfile
, HKL hkl
, TF_INPUTPROCESSORPROFILE
*pProfile
)
735 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
736 FIXME("(%p)->(%d %x %s %s %p %p)\n", This
, dwProfileType
, langid
, debugstr_guid(clsid
),
737 debugstr_guid(guidProfile
), hkl
, pProfile
);
741 static HRESULT WINAPI
InputProcessorProfileMgr_EnumProfiles(ITfInputProcessorProfileMgr
*iface
, LANGID langid
,
742 IEnumTfInputProcessorProfiles
**ppEnum
)
744 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
745 FIXME("(%p)->(%x %p)\n", This
, langid
, ppEnum
);
749 static HRESULT WINAPI
InputProcessorProfileMgr_ReleaseInputProcessor(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
752 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
753 FIXME("(%p)->(%s %x)\n", This
, debugstr_guid(rclsid
), dwFlags
);
757 static HRESULT WINAPI
InputProcessorProfileMgr_RegisterProfile(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
758 LANGID langid
, REFGUID guidProfile
, const WCHAR
*pchDesc
, ULONG cchDesc
, const WCHAR
*pchIconFile
,
759 ULONG cchFile
, ULONG uIconIndex
, HKL hklsubstitute
, DWORD dwPreferredLayout
, BOOL bEnabledByDefault
,
762 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
763 FIXME("(%p)->(%s %x %s %s %d %s %u %u %p %x %x %x)\n", This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
),
764 debugstr_w(pchDesc
), cchDesc
, debugstr_w(pchIconFile
), cchFile
, uIconIndex
, hklsubstitute
, dwPreferredLayout
,
765 bEnabledByDefault
, dwFlags
);
769 static HRESULT WINAPI
InputProcessorProfileMgr_UnregisterProfile(ITfInputProcessorProfileMgr
*iface
, REFCLSID rclsid
,
770 LANGID langid
, REFGUID guidProfile
, DWORD dwFlags
)
772 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
773 FIXME("(%p)->(%s %x %s %x)\n", This
, debugstr_guid(rclsid
), langid
, debugstr_guid(guidProfile
), dwFlags
);
777 static HRESULT WINAPI
InputProcessorProfileMgr_GetActiveProfile(ITfInputProcessorProfileMgr
*iface
, REFGUID catid
,
778 TF_INPUTPROCESSORPROFILE
*pProfile
)
780 InputProcessorProfiles
*This
= impl_from_ITfInputProcessorProfileMgr(iface
);
781 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(catid
), pProfile
);
785 static const ITfInputProcessorProfileMgrVtbl InputProcessorProfileMgrVtbl
= {
786 InputProcessorProfileMgr_QueryInterface
,
787 InputProcessorProfileMgr_AddRef
,
788 InputProcessorProfileMgr_Release
,
789 InputProcessorProfileMgr_ActivateProfile
,
790 InputProcessorProfileMgr_DeactivateProfile
,
791 InputProcessorProfileMgr_GetProfile
,
792 InputProcessorProfileMgr_EnumProfiles
,
793 InputProcessorProfileMgr_ReleaseInputProcessor
,
794 InputProcessorProfileMgr_RegisterProfile
,
795 InputProcessorProfileMgr_UnregisterProfile
,
796 InputProcessorProfileMgr_GetActiveProfile
799 /*****************************************************
800 * ITfSource functions
801 *****************************************************/
802 static HRESULT WINAPI
IPPSource_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
804 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
805 return ITfInputProcessorProfiles_QueryInterface(&This
->ITfInputProcessorProfiles_iface
, iid
, ppvOut
);
808 static ULONG WINAPI
IPPSource_AddRef(ITfSource
*iface
)
810 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
811 return ITfInputProcessorProfiles_AddRef(&This
->ITfInputProcessorProfiles_iface
);
814 static ULONG WINAPI
IPPSource_Release(ITfSource
*iface
)
816 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
817 return ITfInputProcessorProfiles_Release(&This
->ITfInputProcessorProfiles_iface
);
820 static HRESULT WINAPI
IPPSource_AdviseSink(ITfSource
*iface
,
821 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
823 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
824 InputProcessorProfilesSink
*ipps
;
826 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
828 if (!riid
|| !punk
|| !pdwCookie
)
831 if (IsEqualIID(riid
, &IID_ITfLanguageProfileNotifySink
))
833 ipps
= HeapAlloc(GetProcessHeap(),0,sizeof(InputProcessorProfilesSink
));
835 return E_OUTOFMEMORY
;
836 if (FAILED(IUnknown_QueryInterface(punk
, riid
, (LPVOID
*)&ipps
->interfaces
.pITfLanguageProfileNotifySink
)))
838 HeapFree(GetProcessHeap(),0,ipps
);
839 return CONNECT_E_CANNOTCONNECT
;
841 list_add_head(&This
->LanguageProfileNotifySink
,&ipps
->entry
);
842 *pdwCookie
= generate_Cookie(COOKIE_MAGIC_IPPSINK
, ipps
);
846 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
850 TRACE("cookie %x\n",*pdwCookie
);
855 static HRESULT WINAPI
IPPSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
857 InputProcessorProfiles
*This
= impl_from_ITfSource(iface
);
858 InputProcessorProfilesSink
*sink
;
860 TRACE("(%p) %x\n",This
,pdwCookie
);
862 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_IPPSINK
)
865 sink
= remove_Cookie(pdwCookie
);
867 return CONNECT_E_NOCONNECTION
;
869 list_remove(&sink
->entry
);
875 static const ITfSourceVtbl InputProcessorProfilesSourceVtbl
=
877 IPPSource_QueryInterface
,
880 IPPSource_AdviseSink
,
881 IPPSource_UnadviseSink
,
884 HRESULT
InputProcessorProfiles_Constructor(IUnknown
*pUnkOuter
, IUnknown
**ppOut
)
886 InputProcessorProfiles
*This
;
888 return CLASS_E_NOAGGREGATION
;
890 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(InputProcessorProfiles
));
892 return E_OUTOFMEMORY
;
894 This
->ITfInputProcessorProfiles_iface
.lpVtbl
= &InputProcessorProfilesVtbl
;
895 This
->ITfSource_iface
.lpVtbl
= &InputProcessorProfilesSourceVtbl
;
896 This
->ITfInputProcessorProfileMgr_iface
.lpVtbl
= &InputProcessorProfileMgrVtbl
;
898 This
->currentLanguage
= GetUserDefaultLCID();
900 list_init(&This
->LanguageProfileNotifySink
);
902 *ppOut
= (IUnknown
*)&This
->ITfInputProcessorProfiles_iface
;
903 TRACE("returning %p\n", *ppOut
);
907 /**************************************************
908 * IEnumGUID implementation for ITfInputProcessorProfiles::EnumInputProcessorInfo
909 **************************************************/
910 static void ProfilesEnumGuid_Destructor(ProfilesEnumGuid
*This
)
912 TRACE("destroying %p\n", This
);
913 RegCloseKey(This
->key
);
914 HeapFree(GetProcessHeap(),0,This
);
917 static HRESULT WINAPI
ProfilesEnumGuid_QueryInterface(IEnumGUID
*iface
, REFIID iid
, LPVOID
*ppvOut
)
919 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
922 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumGUID
))
924 *ppvOut
= &This
->IEnumGUID_iface
;
929 IEnumGUID_AddRef(iface
);
933 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
934 return E_NOINTERFACE
;
937 static ULONG WINAPI
ProfilesEnumGuid_AddRef(IEnumGUID
*iface
)
939 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
940 return InterlockedIncrement(&This
->refCount
);
943 static ULONG WINAPI
ProfilesEnumGuid_Release(IEnumGUID
*iface
)
945 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
948 ret
= InterlockedDecrement(&This
->refCount
);
950 ProfilesEnumGuid_Destructor(This
);
954 /*****************************************************
955 * IEnumGuid functions
956 *****************************************************/
957 static HRESULT WINAPI
ProfilesEnumGuid_Next( LPENUMGUID iface
,
958 ULONG celt
, GUID
*rgelt
, ULONG
*pceltFetched
)
960 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
963 TRACE("(%p)\n",This
);
965 if (rgelt
== NULL
) return E_POINTER
;
967 if (This
->key
) while (fetched
< celt
)
974 res
= RegEnumKeyExW(This
->key
, This
->next_index
, catid
, &cName
,
975 NULL
, NULL
, NULL
, NULL
);
976 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
) break;
977 ++(This
->next_index
);
979 hr
= CLSIDFromString(catid
, rgelt
);
980 if (FAILED(hr
)) continue;
986 if (pceltFetched
) *pceltFetched
= fetched
;
987 return fetched
== celt
? S_OK
: S_FALSE
;
990 static HRESULT WINAPI
ProfilesEnumGuid_Skip( LPENUMGUID iface
, ULONG celt
)
992 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
993 TRACE("(%p)\n",This
);
995 This
->next_index
+= celt
;
999 static HRESULT WINAPI
ProfilesEnumGuid_Reset( LPENUMGUID iface
)
1001 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1002 TRACE("(%p)\n",This
);
1003 This
->next_index
= 0;
1007 static HRESULT WINAPI
ProfilesEnumGuid_Clone( LPENUMGUID iface
,
1010 ProfilesEnumGuid
*This
= impl_from_IEnumGUID(iface
);
1013 TRACE("(%p)\n",This
);
1015 if (ppenum
== NULL
) return E_POINTER
;
1017 res
= ProfilesEnumGuid_Constructor(ppenum
);
1020 ProfilesEnumGuid
*new_This
= impl_from_IEnumGUID(*ppenum
);
1021 new_This
->next_index
= This
->next_index
;
1026 static const IEnumGUIDVtbl EnumGUIDVtbl
=
1028 ProfilesEnumGuid_QueryInterface
,
1029 ProfilesEnumGuid_AddRef
,
1030 ProfilesEnumGuid_Release
,
1031 ProfilesEnumGuid_Next
,
1032 ProfilesEnumGuid_Skip
,
1033 ProfilesEnumGuid_Reset
,
1034 ProfilesEnumGuid_Clone
1037 static HRESULT
ProfilesEnumGuid_Constructor(IEnumGUID
**ppOut
)
1039 ProfilesEnumGuid
*This
;
1041 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ProfilesEnumGuid
));
1043 return E_OUTOFMEMORY
;
1045 This
->IEnumGUID_iface
.lpVtbl
= &EnumGUIDVtbl
;
1048 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
, szwSystemTIPKey
, 0, NULL
, 0,
1049 KEY_READ
| KEY_WRITE
, NULL
, &This
->key
, NULL
) != ERROR_SUCCESS
)
1051 HeapFree(GetProcessHeap(), 0, This
);
1055 *ppOut
= &This
->IEnumGUID_iface
;
1056 TRACE("returning %p\n", *ppOut
);
1060 /**************************************************
1061 * IEnumTfLanguageProfiles implementation
1062 **************************************************/
1063 static void EnumTfLanguageProfiles_Destructor(EnumTfLanguageProfiles
*This
)
1065 TRACE("destroying %p\n", This
);
1066 RegCloseKey(This
->tipkey
);
1068 RegCloseKey(This
->langkey
);
1069 ITfCategoryMgr_Release(This
->catmgr
);
1070 HeapFree(GetProcessHeap(),0,This
);
1073 static HRESULT WINAPI
EnumTfLanguageProfiles_QueryInterface(IEnumTfLanguageProfiles
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1075 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1079 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumTfLanguageProfiles
))
1081 *ppvOut
= &This
->IEnumTfLanguageProfiles_iface
;
1086 IEnumTfLanguageProfiles_AddRef(iface
);
1090 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
1091 return E_NOINTERFACE
;
1094 static ULONG WINAPI
EnumTfLanguageProfiles_AddRef(IEnumTfLanguageProfiles
*iface
)
1096 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1097 return InterlockedIncrement(&This
->refCount
);
1100 static ULONG WINAPI
EnumTfLanguageProfiles_Release(IEnumTfLanguageProfiles
*iface
)
1102 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1105 ret
= InterlockedDecrement(&This
->refCount
);
1107 EnumTfLanguageProfiles_Destructor(This
);
1111 /*****************************************************
1112 * IEnumGuid functions
1113 *****************************************************/
1114 static INT
next_LanguageProfile(EnumTfLanguageProfiles
*This
, CLSID clsid
, TF_LANGUAGEPROFILE
*tflp
)
1118 WCHAR profileid
[39];
1122 static const WCHAR fmt
[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
1124 if (This
->langkey
== NULL
)
1126 sprintfW(fullkey
,fmt
,This
->szwCurrentClsid
,szwLngp
,This
->langid
);
1127 res
= RegOpenKeyExW(This
->tipkey
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &This
->langkey
);
1130 This
->langkey
= NULL
;
1133 This
->lang_index
= 0;
1135 res
= RegEnumKeyExW(This
->langkey
, This
->lang_index
, profileid
, &cName
,
1136 NULL
, NULL
, NULL
, NULL
);
1137 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
)
1139 RegCloseKey(This
->langkey
);
1140 This
->langkey
= NULL
;
1143 ++(This
->lang_index
);
1147 static const GUID
* tipcats
[3] = { &GUID_TFCAT_TIP_KEYBOARD
,
1148 &GUID_TFCAT_TIP_SPEECH
,
1149 &GUID_TFCAT_TIP_HANDWRITING
};
1150 res
= CLSIDFromString(profileid
, &profile
);
1151 if (FAILED(res
)) return 0;
1153 tflp
->clsid
= clsid
;
1154 tflp
->langid
= This
->langid
;
1155 tflp
->fActive
= get_active_textservice(&clsid
, NULL
);
1156 tflp
->guidProfile
= profile
;
1157 if (ITfCategoryMgr_FindClosestCategory(This
->catmgr
, &clsid
,
1158 &tflp
->catid
, tipcats
, 3) != S_OK
)
1159 ITfCategoryMgr_FindClosestCategory(This
->catmgr
, &clsid
,
1160 &tflp
->catid
, NULL
, 0);
1166 static HRESULT WINAPI
EnumTfLanguageProfiles_Next(IEnumTfLanguageProfiles
*iface
,
1167 ULONG ulCount
, TF_LANGUAGEPROFILE
*pProfile
, ULONG
*pcFetch
)
1169 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1172 TRACE("(%p)\n",This
);
1174 if (pProfile
== NULL
) return E_POINTER
;
1176 if (This
->tipkey
) while (fetched
< ulCount
)
1183 res
= RegEnumKeyExW(This
->tipkey
, This
->tip_index
,
1184 This
->szwCurrentClsid
, &cName
, NULL
, NULL
, NULL
, NULL
);
1185 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
) break;
1186 ++(This
->tip_index
);
1187 hr
= CLSIDFromString(This
->szwCurrentClsid
, &clsid
);
1188 if (FAILED(hr
)) continue;
1190 while ( fetched
< ulCount
)
1192 INT res
= next_LanguageProfile(This
, clsid
, pProfile
);
1205 if (pcFetch
) *pcFetch
= fetched
;
1206 return fetched
== ulCount
? S_OK
: S_FALSE
;
1209 static HRESULT WINAPI
EnumTfLanguageProfiles_Skip( IEnumTfLanguageProfiles
* iface
, ULONG celt
)
1211 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1212 FIXME("STUB (%p)\n",This
);
1216 static HRESULT WINAPI
EnumTfLanguageProfiles_Reset( IEnumTfLanguageProfiles
* iface
)
1218 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1219 TRACE("(%p)\n",This
);
1220 This
->tip_index
= 0;
1222 RegCloseKey(This
->langkey
);
1223 This
->langkey
= NULL
;
1224 This
->lang_index
= 0;
1228 static HRESULT WINAPI
EnumTfLanguageProfiles_Clone( IEnumTfLanguageProfiles
*iface
,
1229 IEnumTfLanguageProfiles
**ppenum
)
1231 EnumTfLanguageProfiles
*This
= impl_from_IEnumTfLanguageProfiles(iface
);
1234 TRACE("(%p)\n",This
);
1236 if (ppenum
== NULL
) return E_POINTER
;
1238 res
= EnumTfLanguageProfiles_Constructor(This
->langid
, ppenum
);
1241 EnumTfLanguageProfiles
*new_This
= (EnumTfLanguageProfiles
*)*ppenum
;
1242 new_This
->tip_index
= This
->tip_index
;
1243 lstrcpynW(new_This
->szwCurrentClsid
,This
->szwCurrentClsid
,39);
1248 static const WCHAR fmt
[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
1250 sprintfW(fullkey
,fmt
,This
->szwCurrentClsid
,szwLngp
,This
->langid
);
1251 res
= RegOpenKeyExW(new_This
->tipkey
, fullkey
, 0, KEY_READ
| KEY_WRITE
, &This
->langkey
);
1252 new_This
->lang_index
= This
->lang_index
;
1258 static const IEnumTfLanguageProfilesVtbl EnumTfLanguageProfilesVtbl
=
1260 EnumTfLanguageProfiles_QueryInterface
,
1261 EnumTfLanguageProfiles_AddRef
,
1262 EnumTfLanguageProfiles_Release
,
1263 EnumTfLanguageProfiles_Clone
,
1264 EnumTfLanguageProfiles_Next
,
1265 EnumTfLanguageProfiles_Reset
,
1266 EnumTfLanguageProfiles_Skip
1269 static HRESULT
EnumTfLanguageProfiles_Constructor(LANGID langid
, IEnumTfLanguageProfiles
**ppOut
)
1272 EnumTfLanguageProfiles
*This
;
1274 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(EnumTfLanguageProfiles
));
1276 return E_OUTOFMEMORY
;
1278 This
->IEnumTfLanguageProfiles_iface
.lpVtbl
= &EnumTfLanguageProfilesVtbl
;
1280 This
->langid
= langid
;
1282 hr
= CategoryMgr_Constructor(NULL
,(IUnknown
**)&This
->catmgr
);
1285 HeapFree(GetProcessHeap(),0,This
);
1289 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
, szwSystemTIPKey
, 0, NULL
, 0,
1290 KEY_READ
| KEY_WRITE
, NULL
, &This
->tipkey
, NULL
) != ERROR_SUCCESS
)
1292 HeapFree(GetProcessHeap(), 0, This
);
1296 *ppOut
= &This
->IEnumTfLanguageProfiles_iface
;
1297 TRACE("returning %p\n", *ppOut
);