Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninputprocessor.c
Go to the documentation of this file.
00001 /* 00002 * ITfInputProcessorProfiles implementation 00003 * 00004 * Copyright 2009 Aric Stewart, CodeWeavers 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include "config.h" 00022 00023 #include <stdarg.h> 00024 00025 #define COBJMACROS 00026 00027 #include "wine/debug.h" 00028 #include "windef.h" 00029 #include "winbase.h" 00030 #include "winreg.h" 00031 #include "winuser.h" 00032 #include "shlwapi.h" 00033 #include "winerror.h" 00034 #include "objbase.h" 00035 #include "olectl.h" 00036 00037 #include "wine/unicode.h" 00038 #include "wine/list.h" 00039 00040 #include "msctf.h" 00041 #include "msctf_internal.h" 00042 00043 WINE_DEFAULT_DEBUG_CHANNEL(msctf); 00044 00045 static const WCHAR szwLngp[] = {'L','a','n','g','u','a','g','e','P','r','o','f','i','l','e',0}; 00046 static const WCHAR szwEnable[] = {'E','n','a','b','l','e',0}; 00047 static const WCHAR szwTipfmt[] = {'%','s','\\','%','s',0}; 00048 static const WCHAR szwFullLangfmt[] = {'%','s','\\','%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0}; 00049 00050 static const WCHAR szwAssemblies[] = {'A','s','s','e','m','b','l','i','e','s',0}; 00051 static const WCHAR szwDefault[] = {'D','e','f','a','u','l','t',0}; 00052 static const WCHAR szwProfile[] = {'P','r','o','f','i','l','e',0}; 00053 static const WCHAR szwDefaultFmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0}; 00054 00055 typedef struct tagInputProcessorProfilesSink { 00056 struct list entry; 00057 union { 00058 /* InputProcessorProfile Sinks */ 00059 IUnknown *pIUnknown; 00060 ITfLanguageProfileNotifySink *pITfLanguageProfileNotifySink; 00061 } interfaces; 00062 } InputProcessorProfilesSink; 00063 00064 typedef struct tagInputProcessorProfiles { 00065 const ITfInputProcessorProfilesVtbl *InputProcessorProfilesVtbl; 00066 const ITfSourceVtbl *SourceVtbl; 00067 /* const ITfInputProcessorProfileMgrVtbl *InputProcessorProfileMgrVtbl; */ 00068 /* const ITfInputProcessorProfilesExVtbl *InputProcessorProfilesExVtbl; */ 00069 /* const ITfInputProcessorProfileSubstituteLayoutVtbl *InputProcessorProfileSubstituteLayoutVtbl; */ 00070 LONG refCount; 00071 00072 LANGID currentLanguage; 00073 00074 struct list LanguageProfileNotifySink; 00075 } InputProcessorProfiles; 00076 00077 typedef struct tagProfilesEnumGuid { 00078 const IEnumGUIDVtbl *Vtbl; 00079 LONG refCount; 00080 00081 HKEY key; 00082 DWORD next_index; 00083 } ProfilesEnumGuid; 00084 00085 typedef struct tagEnumTfLanguageProfiles { 00086 const IEnumTfLanguageProfilesVtbl *Vtbl; 00087 LONG refCount; 00088 00089 HKEY tipkey; 00090 DWORD tip_index; 00091 WCHAR szwCurrentClsid[39]; 00092 00093 HKEY langkey; 00094 DWORD lang_index; 00095 00096 LANGID langid; 00097 ITfCategoryMgr *catmgr; 00098 } EnumTfLanguageProfiles; 00099 00100 static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut); 00101 static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut); 00102 00103 static inline InputProcessorProfiles *impl_from_ITfSourceVtbl(ITfSource *iface) 00104 { 00105 return (InputProcessorProfiles *)((char *)iface - FIELD_OFFSET(InputProcessorProfiles,SourceVtbl)); 00106 } 00107 00108 static void free_sink(InputProcessorProfilesSink *sink) 00109 { 00110 IUnknown_Release(sink->interfaces.pIUnknown); 00111 HeapFree(GetProcessHeap(),0,sink); 00112 } 00113 00114 static void InputProcessorProfiles_Destructor(InputProcessorProfiles *This) 00115 { 00116 struct list *cursor, *cursor2; 00117 TRACE("destroying %p\n", This); 00118 00119 /* free sinks */ 00120 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->LanguageProfileNotifySink) 00121 { 00122 InputProcessorProfilesSink* sink = LIST_ENTRY(cursor,InputProcessorProfilesSink,entry); 00123 list_remove(cursor); 00124 free_sink(sink); 00125 } 00126 00127 HeapFree(GetProcessHeap(),0,This); 00128 } 00129 00130 static void add_userkey( REFCLSID rclsid, LANGID langid, 00131 REFGUID guidProfile) 00132 { 00133 HKEY key; 00134 WCHAR buf[39]; 00135 WCHAR buf2[39]; 00136 WCHAR fullkey[168]; 00137 DWORD disposition = 0; 00138 ULONG res; 00139 00140 TRACE("\n"); 00141 00142 StringFromGUID2(rclsid, buf, 39); 00143 StringFromGUID2(guidProfile, buf2, 39); 00144 sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2); 00145 00146 res = RegCreateKeyExW(HKEY_CURRENT_USER,fullkey, 0, NULL, 0, 00147 KEY_READ | KEY_WRITE, NULL, &key, &disposition); 00148 00149 if (!res && disposition == REG_CREATED_NEW_KEY) 00150 { 00151 DWORD zero = 0x0; 00152 RegSetValueExW(key, szwEnable, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD)); 00153 } 00154 00155 if (!res) 00156 RegCloseKey(key); 00157 } 00158 00159 static HRESULT WINAPI InputProcessorProfiles_QueryInterface(ITfInputProcessorProfiles *iface, REFIID iid, LPVOID *ppvOut) 00160 { 00161 InputProcessorProfiles *This = (InputProcessorProfiles *)iface; 00162 *ppvOut = NULL; 00163 00164 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfInputProcessorProfiles)) 00165 { 00166 *ppvOut = This; 00167 } 00168 else if (IsEqualIID(iid, &IID_ITfSource)) 00169 { 00170 *ppvOut = &This->SourceVtbl; 00171 } 00172 00173 if (*ppvOut) 00174 { 00175 IUnknown_AddRef(iface); 00176 return S_OK; 00177 } 00178 00179 WARN("unsupported interface: %s\n", debugstr_guid(iid)); 00180 return E_NOINTERFACE; 00181 } 00182 00183 static ULONG WINAPI InputProcessorProfiles_AddRef(ITfInputProcessorProfiles *iface) 00184 { 00185 InputProcessorProfiles *This = (InputProcessorProfiles *)iface; 00186 return InterlockedIncrement(&This->refCount); 00187 } 00188 00189 static ULONG WINAPI InputProcessorProfiles_Release(ITfInputProcessorProfiles *iface) 00190 { 00191 InputProcessorProfiles *This = (InputProcessorProfiles *)iface; 00192 ULONG ret; 00193 00194 ret = InterlockedDecrement(&This->refCount); 00195 if (ret == 0) 00196 InputProcessorProfiles_Destructor(This); 00197 return ret; 00198 } 00199 00200 /***************************************************** 00201 * ITfInputProcessorProfiles functions 00202 *****************************************************/ 00203 static HRESULT WINAPI InputProcessorProfiles_Register( 00204 ITfInputProcessorProfiles *iface, REFCLSID rclsid) 00205 { 00206 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00207 HKEY tipkey; 00208 WCHAR buf[39]; 00209 WCHAR fullkey[68]; 00210 00211 TRACE("(%p) %s\n",This,debugstr_guid(rclsid)); 00212 00213 StringFromGUID2(rclsid, buf, 39); 00214 sprintfW(fullkey,szwTipfmt,szwSystemTIPKey,buf); 00215 00216 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, NULL, 0, 00217 KEY_READ | KEY_WRITE, NULL, &tipkey, NULL) != ERROR_SUCCESS) 00218 return E_FAIL; 00219 00220 RegCloseKey(tipkey); 00221 00222 return S_OK; 00223 } 00224 00225 static HRESULT WINAPI InputProcessorProfiles_Unregister( 00226 ITfInputProcessorProfiles *iface, REFCLSID rclsid) 00227 { 00228 WCHAR buf[39]; 00229 WCHAR fullkey[68]; 00230 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00231 00232 TRACE("(%p) %s\n",This,debugstr_guid(rclsid)); 00233 00234 StringFromGUID2(rclsid, buf, 39); 00235 sprintfW(fullkey,szwTipfmt,szwSystemTIPKey,buf); 00236 00237 RegDeleteTreeW(HKEY_LOCAL_MACHINE, fullkey); 00238 RegDeleteTreeW(HKEY_CURRENT_USER, fullkey); 00239 00240 return S_OK; 00241 } 00242 00243 static HRESULT WINAPI InputProcessorProfiles_AddLanguageProfile( 00244 ITfInputProcessorProfiles *iface, REFCLSID rclsid, 00245 LANGID langid, REFGUID guidProfile, const WCHAR *pchDesc, 00246 ULONG cchDesc, const WCHAR *pchIconFile, ULONG cchFile, 00247 ULONG uIconIndex) 00248 { 00249 HKEY tipkey,fmtkey; 00250 WCHAR buf[39]; 00251 WCHAR fullkey[100]; 00252 ULONG res; 00253 DWORD disposition = 0; 00254 00255 static const WCHAR fmt2[] = {'%','s','\\','0','x','%','0','8','x','\\','%','s',0}; 00256 static const WCHAR desc[] = {'D','e','s','c','r','i','p','t','i','o','n',0}; 00257 static const WCHAR icnf[] = {'I','c','o','n','F','i','l','e',0}; 00258 static const WCHAR icni[] = {'I','c','o','n','I','n','d','e','x',0}; 00259 00260 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00261 00262 TRACE("(%p) %s %x %s %s %s %i\n",This,debugstr_guid(rclsid), langid, 00263 debugstr_guid(guidProfile), debugstr_wn(pchDesc,cchDesc), 00264 debugstr_wn(pchIconFile,cchFile),uIconIndex); 00265 00266 StringFromGUID2(rclsid, buf, 39); 00267 sprintfW(fullkey,szwTipfmt,szwSystemTIPKey,buf); 00268 00269 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, KEY_READ | KEY_WRITE, 00270 &tipkey ) != ERROR_SUCCESS) 00271 return E_FAIL; 00272 00273 StringFromGUID2(guidProfile, buf, 39); 00274 sprintfW(fullkey,fmt2,szwLngp,langid,buf); 00275 00276 res = RegCreateKeyExW(tipkey,fullkey, 0, NULL, 0, KEY_READ | KEY_WRITE, 00277 NULL, &fmtkey, &disposition); 00278 00279 if (!res) 00280 { 00281 DWORD zero = 0x0; 00282 RegSetValueExW(fmtkey, desc, 0, REG_SZ, (const BYTE*)pchDesc, cchDesc * sizeof(WCHAR)); 00283 RegSetValueExW(fmtkey, icnf, 0, REG_SZ, (const BYTE*)pchIconFile, cchFile * sizeof(WCHAR)); 00284 RegSetValueExW(fmtkey, icni, 0, REG_DWORD, (LPBYTE)&uIconIndex, sizeof(DWORD)); 00285 if (disposition == REG_CREATED_NEW_KEY) 00286 RegSetValueExW(fmtkey, szwEnable, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD)); 00287 RegCloseKey(fmtkey); 00288 00289 add_userkey(rclsid, langid, guidProfile); 00290 } 00291 RegCloseKey(tipkey); 00292 00293 if (!res) 00294 return S_OK; 00295 else 00296 return E_FAIL; 00297 } 00298 00299 static HRESULT WINAPI InputProcessorProfiles_RemoveLanguageProfile( 00300 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid, 00301 REFGUID guidProfile) 00302 { 00303 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00304 FIXME("STUB:(%p)\n",This); 00305 return E_NOTIMPL; 00306 } 00307 00308 static HRESULT WINAPI InputProcessorProfiles_EnumInputProcessorInfo( 00309 ITfInputProcessorProfiles *iface, IEnumGUID **ppEnum) 00310 { 00311 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00312 TRACE("(%p) %p\n",This,ppEnum); 00313 return ProfilesEnumGuid_Constructor(ppEnum); 00314 } 00315 00316 static HRESULT WINAPI InputProcessorProfiles_GetDefaultLanguageProfile( 00317 ITfInputProcessorProfiles *iface, LANGID langid, REFGUID catid, 00318 CLSID *pclsid, GUID *pguidProfile) 00319 { 00320 WCHAR fullkey[168]; 00321 WCHAR buf[39]; 00322 HKEY hkey; 00323 DWORD count; 00324 ULONG res; 00325 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00326 00327 TRACE("%p) %x %s %p %p\n",This, langid, debugstr_guid(catid),pclsid,pguidProfile); 00328 00329 if (!catid || !pclsid || !pguidProfile) 00330 return E_INVALIDARG; 00331 00332 StringFromGUID2(catid, buf, 39); 00333 sprintfW(fullkey, szwDefaultFmt, szwSystemCTFKey, szwAssemblies, langid, buf); 00334 00335 if (RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE, 00336 &hkey ) != ERROR_SUCCESS) 00337 return S_FALSE; 00338 00339 count = sizeof(buf); 00340 res = RegQueryValueExW(hkey, szwDefault, 0, NULL, (LPBYTE)buf, &count); 00341 if (res != ERROR_SUCCESS) 00342 { 00343 RegCloseKey(hkey); 00344 return S_FALSE; 00345 } 00346 CLSIDFromString(buf,pclsid); 00347 00348 res = RegQueryValueExW(hkey, szwProfile, 0, NULL, (LPBYTE)buf, &count); 00349 if (res == ERROR_SUCCESS) 00350 CLSIDFromString(buf,pguidProfile); 00351 00352 RegCloseKey(hkey); 00353 00354 return S_OK; 00355 } 00356 00357 static HRESULT WINAPI InputProcessorProfiles_SetDefaultLanguageProfile( 00358 ITfInputProcessorProfiles *iface, LANGID langid, REFCLSID rclsid, 00359 REFGUID guidProfiles) 00360 { 00361 WCHAR fullkey[168]; 00362 WCHAR buf[39]; 00363 HKEY hkey; 00364 GUID catid; 00365 HRESULT hr; 00366 ITfCategoryMgr *catmgr; 00367 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00368 static const GUID * tipcats[3] = { &GUID_TFCAT_TIP_KEYBOARD, 00369 &GUID_TFCAT_TIP_SPEECH, 00370 &GUID_TFCAT_TIP_HANDWRITING }; 00371 00372 TRACE("%p) %x %s %s\n",This, langid, debugstr_guid(rclsid),debugstr_guid(guidProfiles)); 00373 00374 if (!rclsid || !guidProfiles) 00375 return E_INVALIDARG; 00376 00377 hr = CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr); 00378 00379 if (FAILED(hr)) 00380 return hr; 00381 00382 if (ITfCategoryMgr_FindClosestCategory(catmgr, rclsid, 00383 &catid, tipcats, 3) != S_OK) 00384 hr = ITfCategoryMgr_FindClosestCategory(catmgr, rclsid, 00385 &catid, NULL, 0); 00386 ITfCategoryMgr_Release(catmgr); 00387 00388 if (FAILED(hr)) 00389 return E_FAIL; 00390 00391 StringFromGUID2(&catid, buf, 39); 00392 sprintfW(fullkey, szwDefaultFmt, szwSystemCTFKey, szwAssemblies, langid, buf); 00393 00394 if (RegCreateKeyExW(HKEY_CURRENT_USER, fullkey, 0, NULL, 0, KEY_READ | KEY_WRITE, 00395 NULL, &hkey, NULL ) != ERROR_SUCCESS) 00396 return E_FAIL; 00397 00398 StringFromGUID2(rclsid, buf, 39); 00399 RegSetValueExW(hkey, szwDefault, 0, REG_SZ, (LPBYTE)buf, sizeof(buf)); 00400 StringFromGUID2(guidProfiles, buf, 39); 00401 RegSetValueExW(hkey, szwProfile, 0, REG_SZ, (LPBYTE)buf, sizeof(buf)); 00402 RegCloseKey(hkey); 00403 00404 return S_OK; 00405 } 00406 00407 static HRESULT WINAPI InputProcessorProfiles_ActivateLanguageProfile( 00408 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid, 00409 REFGUID guidProfiles) 00410 { 00411 HRESULT hr; 00412 BOOL enabled; 00413 TF_LANGUAGEPROFILE LanguageProfile; 00414 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00415 00416 TRACE("(%p) %s %x %s\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfiles)); 00417 00418 if (langid != This->currentLanguage) return E_INVALIDARG; 00419 00420 if (get_active_textservice(rclsid,NULL)) 00421 { 00422 TRACE("Already Active\n"); 00423 return E_FAIL; 00424 } 00425 00426 hr = ITfInputProcessorProfiles_IsEnabledLanguageProfile(iface, rclsid, 00427 langid, guidProfiles, &enabled); 00428 if (FAILED(hr) || !enabled) 00429 { 00430 TRACE("Not Enabled\n"); 00431 return E_FAIL; 00432 } 00433 00434 LanguageProfile.clsid = *rclsid; 00435 LanguageProfile.langid = langid; 00436 LanguageProfile.guidProfile = *guidProfiles; 00437 00438 hr = add_active_textservice(&LanguageProfile); 00439 00440 return hr; 00441 } 00442 00443 static HRESULT WINAPI InputProcessorProfiles_GetActiveLanguageProfile( 00444 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID *plangid, 00445 GUID *pguidProfile) 00446 { 00447 TF_LANGUAGEPROFILE profile; 00448 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00449 00450 TRACE("(%p) %s %p %p\n",This,debugstr_guid(rclsid),plangid,pguidProfile); 00451 00452 if (!rclsid || !plangid || !pguidProfile) 00453 return E_INVALIDARG; 00454 00455 if (get_active_textservice(rclsid, &profile)) 00456 { 00457 *plangid = profile.langid; 00458 *pguidProfile = profile.guidProfile; 00459 return S_OK; 00460 } 00461 else 00462 { 00463 *pguidProfile = GUID_NULL; 00464 return S_FALSE; 00465 } 00466 } 00467 00468 static HRESULT WINAPI InputProcessorProfiles_GetLanguageProfileDescription( 00469 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid, 00470 REFGUID guidProfile, BSTR *pbstrProfile) 00471 { 00472 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00473 FIXME("STUB:(%p)\n",This); 00474 return E_NOTIMPL; 00475 } 00476 00477 static HRESULT WINAPI InputProcessorProfiles_GetCurrentLanguage( 00478 ITfInputProcessorProfiles *iface, LANGID *plangid) 00479 { 00480 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00481 TRACE("(%p) 0x%x\n",This,This->currentLanguage); 00482 00483 if (!plangid) 00484 return E_INVALIDARG; 00485 00486 *plangid = This->currentLanguage; 00487 00488 return S_OK; 00489 } 00490 00491 static HRESULT WINAPI InputProcessorProfiles_ChangeCurrentLanguage( 00492 ITfInputProcessorProfiles *iface, LANGID langid) 00493 { 00494 struct list *cursor; 00495 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00496 BOOL accept; 00497 00498 FIXME("STUB:(%p)\n",This); 00499 00500 LIST_FOR_EACH(cursor, &This->LanguageProfileNotifySink) 00501 { 00502 InputProcessorProfilesSink* sink = LIST_ENTRY(cursor,InputProcessorProfilesSink,entry); 00503 accept = TRUE; 00504 ITfLanguageProfileNotifySink_OnLanguageChange(sink->interfaces.pITfLanguageProfileNotifySink, langid, &accept); 00505 if (!accept) 00506 return E_FAIL; 00507 } 00508 00509 /* TODO: On successful language change call OnLanguageChanged sink */ 00510 return E_NOTIMPL; 00511 } 00512 00513 static HRESULT WINAPI InputProcessorProfiles_GetLanguageList( 00514 ITfInputProcessorProfiles *iface, LANGID **ppLangId, ULONG *pulCount) 00515 { 00516 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00517 FIXME("Semi-STUB:(%p)\n",This); 00518 *ppLangId = CoTaskMemAlloc(sizeof(LANGID)); 00519 **ppLangId = This->currentLanguage; 00520 *pulCount = 1; 00521 return S_OK; 00522 } 00523 00524 static HRESULT WINAPI InputProcessorProfiles_EnumLanguageProfiles( 00525 ITfInputProcessorProfiles *iface, LANGID langid, 00526 IEnumTfLanguageProfiles **ppEnum) 00527 { 00528 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00529 TRACE("(%p) %x %p\n",This,langid,ppEnum); 00530 return EnumTfLanguageProfiles_Constructor(langid, ppEnum); 00531 } 00532 00533 static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfile( 00534 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid, 00535 REFGUID guidProfile, BOOL fEnable) 00536 { 00537 HKEY key; 00538 WCHAR buf[39]; 00539 WCHAR buf2[39]; 00540 WCHAR fullkey[168]; 00541 ULONG res; 00542 00543 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00544 TRACE("(%p) %s %x %s %i\n",This, debugstr_guid(rclsid), langid, debugstr_guid(guidProfile), fEnable); 00545 00546 StringFromGUID2(rclsid, buf, 39); 00547 StringFromGUID2(guidProfile, buf2, 39); 00548 sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2); 00549 00550 res = RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE, &key); 00551 00552 if (!res) 00553 { 00554 RegSetValueExW(key, szwEnable, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD)); 00555 RegCloseKey(key); 00556 } 00557 else 00558 return E_FAIL; 00559 00560 return S_OK; 00561 } 00562 00563 static HRESULT WINAPI InputProcessorProfiles_IsEnabledLanguageProfile( 00564 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid, 00565 REFGUID guidProfile, BOOL *pfEnable) 00566 { 00567 HKEY key; 00568 WCHAR buf[39]; 00569 WCHAR buf2[39]; 00570 WCHAR fullkey[168]; 00571 ULONG res; 00572 00573 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00574 TRACE("(%p) %s, %i, %s, %p\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfile),pfEnable); 00575 00576 if (!pfEnable) 00577 return E_INVALIDARG; 00578 00579 StringFromGUID2(rclsid, buf, 39); 00580 StringFromGUID2(guidProfile, buf2, 39); 00581 sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2); 00582 00583 res = RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE, &key); 00584 00585 if (!res) 00586 { 00587 DWORD count = sizeof(DWORD); 00588 res = RegQueryValueExW(key, szwEnable, 0, NULL, (LPBYTE)pfEnable, &count); 00589 RegCloseKey(key); 00590 } 00591 00592 if (res) /* Try Default */ 00593 { 00594 res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | KEY_WRITE, &key); 00595 00596 if (!res) 00597 { 00598 DWORD count = sizeof(DWORD); 00599 res = RegQueryValueExW(key, szwEnable, 0, NULL, (LPBYTE)pfEnable, &count); 00600 RegCloseKey(key); 00601 } 00602 } 00603 00604 if (!res) 00605 return S_OK; 00606 else 00607 return E_FAIL; 00608 } 00609 00610 static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfileByDefault( 00611 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid, 00612 REFGUID guidProfile, BOOL fEnable) 00613 { 00614 HKEY key; 00615 WCHAR buf[39]; 00616 WCHAR buf2[39]; 00617 WCHAR fullkey[168]; 00618 ULONG res; 00619 00620 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00621 TRACE("(%p) %s %x %s %i\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfile),fEnable); 00622 00623 StringFromGUID2(rclsid, buf, 39); 00624 StringFromGUID2(guidProfile, buf2, 39); 00625 sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2); 00626 00627 res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | KEY_WRITE, &key); 00628 00629 if (!res) 00630 { 00631 RegSetValueExW(key, szwEnable, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD)); 00632 RegCloseKey(key); 00633 } 00634 else 00635 return E_FAIL; 00636 00637 return S_OK; 00638 } 00639 00640 static HRESULT WINAPI InputProcessorProfiles_SubstituteKeyboardLayout( 00641 ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid, 00642 REFGUID guidProfile, HKL hKL) 00643 { 00644 InputProcessorProfiles *This = (InputProcessorProfiles*)iface; 00645 FIXME("STUB:(%p)\n",This); 00646 return E_NOTIMPL; 00647 } 00648 00649 00650 static const ITfInputProcessorProfilesVtbl InputProcessorProfiles_InputProcessorProfilesVtbl = 00651 { 00652 InputProcessorProfiles_QueryInterface, 00653 InputProcessorProfiles_AddRef, 00654 InputProcessorProfiles_Release, 00655 00656 InputProcessorProfiles_Register, 00657 InputProcessorProfiles_Unregister, 00658 InputProcessorProfiles_AddLanguageProfile, 00659 InputProcessorProfiles_RemoveLanguageProfile, 00660 InputProcessorProfiles_EnumInputProcessorInfo, 00661 InputProcessorProfiles_GetDefaultLanguageProfile, 00662 InputProcessorProfiles_SetDefaultLanguageProfile, 00663 InputProcessorProfiles_ActivateLanguageProfile, 00664 InputProcessorProfiles_GetActiveLanguageProfile, 00665 InputProcessorProfiles_GetLanguageProfileDescription, 00666 InputProcessorProfiles_GetCurrentLanguage, 00667 InputProcessorProfiles_ChangeCurrentLanguage, 00668 InputProcessorProfiles_GetLanguageList, 00669 InputProcessorProfiles_EnumLanguageProfiles, 00670 InputProcessorProfiles_EnableLanguageProfile, 00671 InputProcessorProfiles_IsEnabledLanguageProfile, 00672 InputProcessorProfiles_EnableLanguageProfileByDefault, 00673 InputProcessorProfiles_SubstituteKeyboardLayout 00674 }; 00675 00676 /***************************************************** 00677 * ITfSource functions 00678 *****************************************************/ 00679 static HRESULT WINAPI IPPSource_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut) 00680 { 00681 InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface); 00682 return InputProcessorProfiles_QueryInterface((ITfInputProcessorProfiles *)This, iid, *ppvOut); 00683 } 00684 00685 static ULONG WINAPI IPPSource_AddRef(ITfSource *iface) 00686 { 00687 InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface); 00688 return InputProcessorProfiles_AddRef((ITfInputProcessorProfiles*)This); 00689 } 00690 00691 static ULONG WINAPI IPPSource_Release(ITfSource *iface) 00692 { 00693 InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface); 00694 return InputProcessorProfiles_Release((ITfInputProcessorProfiles *)This); 00695 } 00696 00697 static HRESULT WINAPI IPPSource_AdviseSink(ITfSource *iface, 00698 REFIID riid, IUnknown *punk, DWORD *pdwCookie) 00699 { 00700 InputProcessorProfilesSink *ipps; 00701 InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface); 00702 00703 TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie); 00704 00705 if (!riid || !punk || !pdwCookie) 00706 return E_INVALIDARG; 00707 00708 if (IsEqualIID(riid, &IID_ITfLanguageProfileNotifySink)) 00709 { 00710 ipps = HeapAlloc(GetProcessHeap(),0,sizeof(InputProcessorProfilesSink)); 00711 if (!ipps) 00712 return E_OUTOFMEMORY; 00713 if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&ipps->interfaces.pITfLanguageProfileNotifySink))) 00714 { 00715 HeapFree(GetProcessHeap(),0,ipps); 00716 return CONNECT_E_CANNOTCONNECT; 00717 } 00718 list_add_head(&This->LanguageProfileNotifySink,&ipps->entry); 00719 *pdwCookie = generate_Cookie(COOKIE_MAGIC_IPPSINK, ipps); 00720 } 00721 else 00722 { 00723 FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid)); 00724 return E_NOTIMPL; 00725 } 00726 00727 TRACE("cookie %x\n",*pdwCookie); 00728 00729 return S_OK; 00730 } 00731 00732 static HRESULT WINAPI IPPSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie) 00733 { 00734 InputProcessorProfilesSink *sink; 00735 InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface); 00736 00737 TRACE("(%p) %x\n",This,pdwCookie); 00738 00739 if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_IPPSINK) 00740 return E_INVALIDARG; 00741 00742 sink = (InputProcessorProfilesSink*)remove_Cookie(pdwCookie); 00743 if (!sink) 00744 return CONNECT_E_NOCONNECTION; 00745 00746 list_remove(&sink->entry); 00747 free_sink(sink); 00748 00749 return S_OK; 00750 } 00751 00752 static const ITfSourceVtbl InputProcessorProfiles_SourceVtbl = 00753 { 00754 IPPSource_QueryInterface, 00755 IPPSource_AddRef, 00756 IPPSource_Release, 00757 00758 IPPSource_AdviseSink, 00759 IPPSource_UnadviseSink, 00760 }; 00761 00762 HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut) 00763 { 00764 InputProcessorProfiles *This; 00765 if (pUnkOuter) 00766 return CLASS_E_NOAGGREGATION; 00767 00768 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputProcessorProfiles)); 00769 if (This == NULL) 00770 return E_OUTOFMEMORY; 00771 00772 This->InputProcessorProfilesVtbl= &InputProcessorProfiles_InputProcessorProfilesVtbl; 00773 This->SourceVtbl = &InputProcessorProfiles_SourceVtbl; 00774 This->refCount = 1; 00775 This->currentLanguage = GetUserDefaultLCID(); 00776 00777 list_init(&This->LanguageProfileNotifySink); 00778 00779 TRACE("returning %p\n", This); 00780 *ppOut = (IUnknown *)This; 00781 return S_OK; 00782 } 00783 00784 /************************************************** 00785 * IEnumGUID implementation for ITfInputProcessorProfiles::EnumInputProcessorInfo 00786 **************************************************/ 00787 static void ProfilesEnumGuid_Destructor(ProfilesEnumGuid *This) 00788 { 00789 TRACE("destroying %p\n", This); 00790 RegCloseKey(This->key); 00791 HeapFree(GetProcessHeap(),0,This); 00792 } 00793 00794 static HRESULT WINAPI ProfilesEnumGuid_QueryInterface(IEnumGUID *iface, REFIID iid, LPVOID *ppvOut) 00795 { 00796 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface; 00797 *ppvOut = NULL; 00798 00799 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumGUID)) 00800 { 00801 *ppvOut = This; 00802 } 00803 00804 if (*ppvOut) 00805 { 00806 IUnknown_AddRef(iface); 00807 return S_OK; 00808 } 00809 00810 WARN("unsupported interface: %s\n", debugstr_guid(iid)); 00811 return E_NOINTERFACE; 00812 } 00813 00814 static ULONG WINAPI ProfilesEnumGuid_AddRef(IEnumGUID *iface) 00815 { 00816 ProfilesEnumGuid *This = (ProfilesEnumGuid*)iface; 00817 return InterlockedIncrement(&This->refCount); 00818 } 00819 00820 static ULONG WINAPI ProfilesEnumGuid_Release(IEnumGUID *iface) 00821 { 00822 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface; 00823 ULONG ret; 00824 00825 ret = InterlockedDecrement(&This->refCount); 00826 if (ret == 0) 00827 ProfilesEnumGuid_Destructor(This); 00828 return ret; 00829 } 00830 00831 /***************************************************** 00832 * IEnumGuid functions 00833 *****************************************************/ 00834 static HRESULT WINAPI ProfilesEnumGuid_Next( LPENUMGUID iface, 00835 ULONG celt, GUID *rgelt, ULONG *pceltFetched) 00836 { 00837 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface; 00838 ULONG fetched = 0; 00839 00840 TRACE("(%p)\n",This); 00841 00842 if (rgelt == NULL) return E_POINTER; 00843 00844 if (This->key) while (fetched < celt) 00845 { 00846 LSTATUS res; 00847 HRESULT hr; 00848 WCHAR catid[39]; 00849 DWORD cName = 39; 00850 00851 res = RegEnumKeyExW(This->key, This->next_index, catid, &cName, 00852 NULL, NULL, NULL, NULL); 00853 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break; 00854 ++(This->next_index); 00855 00856 hr = CLSIDFromString(catid, rgelt); 00857 if (FAILED(hr)) continue; 00858 00859 ++fetched; 00860 ++rgelt; 00861 } 00862 00863 if (pceltFetched) *pceltFetched = fetched; 00864 return fetched == celt ? S_OK : S_FALSE; 00865 } 00866 00867 static HRESULT WINAPI ProfilesEnumGuid_Skip( LPENUMGUID iface, ULONG celt) 00868 { 00869 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface; 00870 TRACE("(%p)\n",This); 00871 00872 This->next_index += celt; 00873 return S_OK; 00874 } 00875 00876 static HRESULT WINAPI ProfilesEnumGuid_Reset( LPENUMGUID iface) 00877 { 00878 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface; 00879 TRACE("(%p)\n",This); 00880 This->next_index = 0; 00881 return S_OK; 00882 } 00883 00884 static HRESULT WINAPI ProfilesEnumGuid_Clone( LPENUMGUID iface, 00885 IEnumGUID **ppenum) 00886 { 00887 ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface; 00888 HRESULT res; 00889 00890 TRACE("(%p)\n",This); 00891 00892 if (ppenum == NULL) return E_POINTER; 00893 00894 res = ProfilesEnumGuid_Constructor(ppenum); 00895 if (SUCCEEDED(res)) 00896 { 00897 ProfilesEnumGuid *new_This = (ProfilesEnumGuid *)*ppenum; 00898 new_This->next_index = This->next_index; 00899 } 00900 return res; 00901 } 00902 00903 static const IEnumGUIDVtbl IEnumGUID_Vtbl ={ 00904 ProfilesEnumGuid_QueryInterface, 00905 ProfilesEnumGuid_AddRef, 00906 ProfilesEnumGuid_Release, 00907 00908 ProfilesEnumGuid_Next, 00909 ProfilesEnumGuid_Skip, 00910 ProfilesEnumGuid_Reset, 00911 ProfilesEnumGuid_Clone 00912 }; 00913 00914 static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut) 00915 { 00916 ProfilesEnumGuid *This; 00917 00918 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ProfilesEnumGuid)); 00919 if (This == NULL) 00920 return E_OUTOFMEMORY; 00921 00922 This->Vtbl= &IEnumGUID_Vtbl; 00923 This->refCount = 1; 00924 00925 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szwSystemTIPKey, 0, NULL, 0, 00926 KEY_READ | KEY_WRITE, NULL, &This->key, NULL) != ERROR_SUCCESS) 00927 { 00928 HeapFree(GetProcessHeap(), 0, This); 00929 return E_FAIL; 00930 } 00931 00932 TRACE("returning %p\n", This); 00933 *ppOut = (IEnumGUID*)This; 00934 return S_OK; 00935 } 00936 00937 /************************************************** 00938 * IEnumTfLanguageProfiles implementation 00939 **************************************************/ 00940 static void EnumTfLanguageProfiles_Destructor(EnumTfLanguageProfiles *This) 00941 { 00942 TRACE("destroying %p\n", This); 00943 RegCloseKey(This->tipkey); 00944 if (This->langkey) 00945 RegCloseKey(This->langkey); 00946 ITfCategoryMgr_Release(This->catmgr); 00947 HeapFree(GetProcessHeap(),0,This); 00948 } 00949 00950 static HRESULT WINAPI EnumTfLanguageProfiles_QueryInterface(IEnumTfLanguageProfiles *iface, REFIID iid, LPVOID *ppvOut) 00951 { 00952 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface; 00953 *ppvOut = NULL; 00954 00955 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumTfLanguageProfiles)) 00956 { 00957 *ppvOut = This; 00958 } 00959 00960 if (*ppvOut) 00961 { 00962 IUnknown_AddRef(iface); 00963 return S_OK; 00964 } 00965 00966 WARN("unsupported interface: %s\n", debugstr_guid(iid)); 00967 return E_NOINTERFACE; 00968 } 00969 00970 static ULONG WINAPI EnumTfLanguageProfiles_AddRef(IEnumTfLanguageProfiles *iface) 00971 { 00972 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles*)iface; 00973 return InterlockedIncrement(&This->refCount); 00974 } 00975 00976 static ULONG WINAPI EnumTfLanguageProfiles_Release(IEnumTfLanguageProfiles *iface) 00977 { 00978 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface; 00979 ULONG ret; 00980 00981 ret = InterlockedDecrement(&This->refCount); 00982 if (ret == 0) 00983 EnumTfLanguageProfiles_Destructor(This); 00984 return ret; 00985 } 00986 00987 /***************************************************** 00988 * IEnumGuid functions 00989 *****************************************************/ 00990 static INT next_LanguageProfile(EnumTfLanguageProfiles *This, CLSID clsid, TF_LANGUAGEPROFILE *tflp) 00991 { 00992 WCHAR fullkey[168]; 00993 ULONG res; 00994 WCHAR profileid[39]; 00995 DWORD cName = 39; 00996 GUID profile; 00997 00998 static const WCHAR fmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0}; 00999 01000 if (This->langkey == NULL) 01001 { 01002 sprintfW(fullkey,fmt,This->szwCurrentClsid,szwLngp,This->langid); 01003 res = RegOpenKeyExW(This->tipkey, fullkey, 0, KEY_READ | KEY_WRITE, &This->langkey); 01004 if (res) 01005 { 01006 This->langkey = NULL; 01007 return -1; 01008 } 01009 This->lang_index = 0; 01010 } 01011 res = RegEnumKeyExW(This->langkey, This->lang_index, profileid, &cName, 01012 NULL, NULL, NULL, NULL); 01013 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) 01014 { 01015 RegCloseKey(This->langkey); 01016 This->langkey = NULL; 01017 return -1; 01018 } 01019 ++(This->lang_index); 01020 01021 if (tflp) 01022 { 01023 static const GUID * tipcats[3] = { &GUID_TFCAT_TIP_KEYBOARD, 01024 &GUID_TFCAT_TIP_SPEECH, 01025 &GUID_TFCAT_TIP_HANDWRITING }; 01026 res = CLSIDFromString(profileid, &profile); 01027 if (FAILED(res)) return 0; 01028 01029 tflp->clsid = clsid; 01030 tflp->langid = This->langid; 01031 tflp->fActive = get_active_textservice(&clsid, NULL); 01032 tflp->guidProfile = profile; 01033 if (ITfCategoryMgr_FindClosestCategory(This->catmgr, &clsid, 01034 &tflp->catid, tipcats, 3) != S_OK) 01035 ITfCategoryMgr_FindClosestCategory(This->catmgr, &clsid, 01036 &tflp->catid, NULL, 0); 01037 } 01038 01039 return 1; 01040 } 01041 01042 static HRESULT WINAPI EnumTfLanguageProfiles_Next(IEnumTfLanguageProfiles *iface, 01043 ULONG ulCount, TF_LANGUAGEPROFILE *pProfile, ULONG *pcFetch) 01044 { 01045 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface; 01046 ULONG fetched = 0; 01047 01048 TRACE("(%p)\n",This); 01049 01050 if (pProfile == NULL) return E_POINTER; 01051 01052 if (This->tipkey) while (fetched < ulCount) 01053 { 01054 LSTATUS res; 01055 HRESULT hr; 01056 DWORD cName = 39; 01057 GUID clsid; 01058 01059 res = RegEnumKeyExW(This->tipkey, This->tip_index, 01060 This->szwCurrentClsid, &cName, NULL, NULL, NULL, NULL); 01061 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break; 01062 ++(This->tip_index); 01063 hr = CLSIDFromString(This->szwCurrentClsid, &clsid); 01064 if (FAILED(hr)) continue; 01065 01066 while ( fetched < ulCount) 01067 { 01068 INT res = next_LanguageProfile(This, clsid, pProfile); 01069 if (res == 1) 01070 { 01071 ++fetched; 01072 ++pProfile; 01073 } 01074 else if (res == -1) 01075 break; 01076 else 01077 continue; 01078 } 01079 } 01080 01081 if (pcFetch) *pcFetch = fetched; 01082 return fetched == ulCount ? S_OK : S_FALSE; 01083 } 01084 01085 static HRESULT WINAPI EnumTfLanguageProfiles_Skip( IEnumTfLanguageProfiles* iface, ULONG celt) 01086 { 01087 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface; 01088 FIXME("STUB (%p)\n",This); 01089 return E_NOTIMPL; 01090 } 01091 01092 static HRESULT WINAPI EnumTfLanguageProfiles_Reset( IEnumTfLanguageProfiles* iface) 01093 { 01094 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface; 01095 TRACE("(%p)\n",This); 01096 This->tip_index = 0; 01097 if (This->langkey) 01098 RegCloseKey(This->langkey); 01099 This->langkey = NULL; 01100 This->lang_index = 0; 01101 return S_OK; 01102 } 01103 01104 static HRESULT WINAPI EnumTfLanguageProfiles_Clone( IEnumTfLanguageProfiles *iface, 01105 IEnumTfLanguageProfiles **ppenum) 01106 { 01107 EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface; 01108 HRESULT res; 01109 01110 TRACE("(%p)\n",This); 01111 01112 if (ppenum == NULL) return E_POINTER; 01113 01114 res = EnumTfLanguageProfiles_Constructor(This->langid, ppenum); 01115 if (SUCCEEDED(res)) 01116 { 01117 EnumTfLanguageProfiles *new_This = (EnumTfLanguageProfiles *)*ppenum; 01118 new_This->tip_index = This->tip_index; 01119 lstrcpynW(new_This->szwCurrentClsid,This->szwCurrentClsid,39); 01120 01121 if (This->langkey) 01122 { 01123 WCHAR fullkey[168]; 01124 static const WCHAR fmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0}; 01125 01126 sprintfW(fullkey,fmt,This->szwCurrentClsid,szwLngp,This->langid); 01127 res = RegOpenKeyExW(new_This->tipkey, fullkey, 0, KEY_READ | KEY_WRITE, &This->langkey); 01128 new_This->lang_index = This->lang_index; 01129 } 01130 } 01131 return res; 01132 } 01133 01134 static const IEnumTfLanguageProfilesVtbl IEnumTfLanguageProfiles_Vtbl ={ 01135 EnumTfLanguageProfiles_QueryInterface, 01136 EnumTfLanguageProfiles_AddRef, 01137 EnumTfLanguageProfiles_Release, 01138 01139 EnumTfLanguageProfiles_Clone, 01140 EnumTfLanguageProfiles_Next, 01141 EnumTfLanguageProfiles_Reset, 01142 EnumTfLanguageProfiles_Skip 01143 }; 01144 01145 static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut) 01146 { 01147 HRESULT hr; 01148 EnumTfLanguageProfiles *This; 01149 01150 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EnumTfLanguageProfiles)); 01151 if (This == NULL) 01152 return E_OUTOFMEMORY; 01153 01154 This->Vtbl= &IEnumTfLanguageProfiles_Vtbl; 01155 This->refCount = 1; 01156 This->langid = langid; 01157 01158 hr = CategoryMgr_Constructor(NULL,(IUnknown**)&This->catmgr); 01159 if (FAILED(hr)) 01160 { 01161 HeapFree(GetProcessHeap(),0,This); 01162 return hr; 01163 } 01164 01165 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szwSystemTIPKey, 0, NULL, 0, 01166 KEY_READ | KEY_WRITE, NULL, &This->tipkey, NULL) != ERROR_SUCCESS) 01167 { 01168 HeapFree(GetProcessHeap(), 0, This); 01169 return E_FAIL; 01170 } 01171 01172 TRACE("returning %p\n", This); 01173 *ppOut = (IEnumTfLanguageProfiles*)This; 01174 return S_OK; 01175 } Generated on Sun May 27 2012 04:24:49 for ReactOS by
1.7.6.1
|