Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

immhotky.c

Go to the documentation of this file.
00001 /**************************************************************************\ 00002 * Module Name: immhotky.c (user32 side IME hotkey handling) 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * IME hot key management routines for imm32 dll 00007 * 00008 * History: 00009 * 03-Jan-1996 hiroyama Created 00010 \**************************************************************************/ 00011 00012 #include "precomp.h" 00013 #pragma hdrstop 00014 00015 00016 typedef struct tagFE_KEYBOARDS { 00017 BOOLEAN fJPN : 1; 00018 BOOLEAN fCHT : 1; 00019 BOOLEAN fCHS : 1; 00020 BOOLEAN fKOR : 1; 00021 } FE_KEYBOARDS; 00022 00023 /* 00024 * Function pointers to registry routines in advapi32.dll. 00025 */ 00026 typedef struct { 00027 HMODULE hModule; 00028 LONG (WINAPI* RegCreateKeyW)(HKEY, LPCWSTR, PHKEY); 00029 LONG (WINAPI* RegOpenKeyW)(HKEY, LPCWSTR, PHKEY); 00030 LONG (WINAPI* RegCloseKey)(HKEY); 00031 LONG (WINAPI* RegDeleteKeyW)(HKEY, LPCWSTR); 00032 LONG (WINAPI* RegCreateKeyExW)(HKEY, LPCWSTR, DWORD, LPWSTR, DWORD, REGSAM, LPSECURITY_ATTRIBUTES, PHKEY, LPDWORD); 00033 LONG (WINAPI* RegSetValueExW)(HKEY, LPCWSTR, DWORD Reserved, DWORD, CONST BYTE*, DWORD); 00034 LONG (WINAPI* RegQueryValueExW)(HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD); 00035 } ADVAPI_FN; 00036 00037 // 00038 // internal functions 00039 // 00040 BOOL CliSaveImeHotKey(DWORD dwID, UINT uModifiers, UINT uVKey, HKL hkl, BOOL fDelete); 00041 BOOL CliImmSetHotKeyWorker(DWORD dwID, UINT uModifiers, UINT uVKey, HKL hkl, DWORD dwAction); 00042 VOID NumToHexAscii(DWORD, PTSTR); 00043 BOOL CliGetImeHotKeysFromRegistry(void); 00044 BOOL CliSetSingleHotKey(PKEY_BASIC_INFORMATION pKeyInfo, HANDLE hKey); 00045 VOID CliSetDefaultImeHotKeys(PCIMEHOTKEY ph, INT num, BOOL fCheckExistingHotKey); 00046 VOID CliGetPreloadKeyboardLayouts(FE_KEYBOARDS* pFeKbds); 00047 00048 // 00049 // IMM hotkey related registry keys under HKEY_CURRENT_USER 00050 // 00051 CONST TCHAR *szaRegImmHotKeys[] = { 00052 TEXT("Control Panel"), 00053 TEXT("Input Method"), 00054 TEXT("Hot Keys"), 00055 NULL 00056 }; 00057 00058 CONST TCHAR szRegImeHotKey[] = TEXT("Control Panel\\Input Method\\Hot Keys"); 00059 CONST TCHAR szRegKeyboardPreload[] = TEXT("Keyboard Layout\\Preload"); 00060 00061 CONST TCHAR szRegVK[] = TEXT("Virtual Key"); 00062 CONST TCHAR szRegMOD[] = TEXT("Key Modifiers"); 00063 CONST TCHAR szRegHKL[] = TEXT("Target IME"); 00064 00065 // 00066 // Default IME HotKey Tables 00067 // 00068 // CR:takaok - move this to the resource if you have time 00069 // 00070 CONST IMEHOTKEY DefaultHotKeyTableJ[]= { 00071 {IME_JHOTKEY_CLOSE_OPEN, VK_KANJI, MOD_IGNORE_ALL_MODIFIER, NULL} 00072 }; 00073 CONST INT DefaultHotKeyNumJ = sizeof(DefaultHotKeyTableJ) / sizeof(IMEHOTKEY); 00074 00075 CONST IMEHOTKEY DefaultHotKeyTableT[] = { 00076 { IME_THOTKEY_IME_NONIME_TOGGLE, VK_SPACE, MOD_BOTH_SIDES|MOD_CONTROL, NULL }, 00077 { IME_THOTKEY_SHAPE_TOGGLE, VK_SPACE, MOD_BOTH_SIDES|MOD_SHIFT, NULL } 00078 }; 00079 CONST INT DefaultHotKeyNumT = sizeof(DefaultHotKeyTableT) / sizeof(IMEHOTKEY); 00080 00081 CONST IMEHOTKEY DefaultHotKeyTableC[] = { 00082 { IME_CHOTKEY_IME_NONIME_TOGGLE, VK_SPACE, MOD_BOTH_SIDES|MOD_CONTROL, NULL }, 00083 { IME_CHOTKEY_SHAPE_TOGGLE, VK_SPACE, MOD_BOTH_SIDES|MOD_SHIFT, NULL } 00084 }; 00085 CONST INT DefaultHotKeyNumC = sizeof(DefaultHotKeyTableC) / sizeof(IMEHOTKEY); 00086 00087 #if 0 // just FYI. 00088 CONST IMEHOTKEY DefaultHotKeyTableK[] = { 00089 { IME_KHOTKEY_ENGLISH, VK_HANGEUL, MOD_IGNORE_ALL_MODIFIER, NULL }, 00090 { IME_KHOTKEY_SHAPE_TOGGLE, VK_JUNJA, MOD_IGNORE_ALL_MODIFIER, NULL }, 00091 { IME_KHOTKEY_HANJACONVERT, VK_HANJA, MOD_IGNORE_ALL_MODIFIER, NULL } 00092 }; 00093 CONST INT DefaultHotKeyNumK = sizeof(DefaultHotKeyTableK) / sizeof(IMEHOTKEY); 00094 #endif 00095 00096 // 00097 // Set language flags. 00098 // 00099 VOID SetFeKeyboardFlags(LANGID langid, FE_KEYBOARDS* pFeKbds) 00100 { 00101 switch (langid) { 00102 case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL): 00103 case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_HONGKONG): 00104 pFeKbds->fCHT = TRUE; 00105 break; 00106 case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED): 00107 case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SINGAPORE): 00108 pFeKbds->fCHS = TRUE; 00109 break; 00110 case MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT): 00111 pFeKbds->fJPN = TRUE; 00112 break; 00113 case MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT): 00114 pFeKbds->fKOR = TRUE; 00115 break; 00116 } 00117 } 00118 00119 /***************************************************************************\ 00120 * ImmInitializeHotkeys() 00121 * 00122 * Called from user\client\UpdatePerUserSystemParameters() 00123 * 00124 * Read the User registry and set the IME hotkey. 00125 * 00126 * History: 00127 * 25-Mar-1996 TakaoK Created 00128 \***************************************************************************/ 00129 VOID CliImmInitializeHotKeys(DWORD dwAction, HKL hkl) 00130 { 00131 FE_KEYBOARDS feKbds = { 0, 0, 0, 0, }; 00132 BOOL fFoundAny; 00133 00134 UNREFERENCED_PARAMETER(hkl); 00135 00136 // First, initialize the hotkey list 00137 CliImmSetHotKeyWorker(0, 0, 0, NULL, ISHK_INITIALIZE); 00138 00139 // Check if the user has customized IME hotkeys 00140 // (they're stored in the registry) 00141 fFoundAny = CliGetImeHotKeysFromRegistry(); 00142 00143 if (dwAction == ISHK_INITIALIZE) { 00144 TAGMSG0(DBGTAG_IMM, "Setting IME HotKeys for Init.\n"); 00145 00146 // Get the user's default locale and set its flag 00147 SetFeKeyboardFlags(LANGIDFROMLCID(GetUserDefaultLCID()), &feKbds); 00148 00149 // Get preloaded keyboards' locales and set their flags 00150 CliGetPreloadKeyboardLayouts(&feKbds); 00151 00152 } 00153 else { 00154 UINT i; 00155 UINT nLayouts; 00156 LPHKL lphkl; 00157 00158 TAGMSG0(DBGTAG_IMM, "Setting IME HotKeys for Add.\n"); 00159 00160 nLayouts = NtUserGetKeyboardLayoutList(0, NULL); 00161 if (nLayouts == 0) { 00162 return; 00163 } 00164 lphkl = UserLocalAlloc(0, nLayouts * sizeof(HKL)); 00165 if (lphkl == NULL) { 00166 return; 00167 } 00168 NtUserGetKeyboardLayoutList(nLayouts, lphkl); 00169 for (i = 0; i < nLayouts; ++i) { 00170 // 00171 // Set language flags. By its definition, LOWORD(hkl) is LANGID 00172 // 00173 SetFeKeyboardFlags(LOWORD(HandleToUlong(lphkl[i])), &feKbds); 00174 } 00175 UserLocalFree(lphkl); 00176 } 00177 00178 if (feKbds.fJPN) { 00179 TAGMSG0(DBGTAG_IMM, "JPN KL Preloaded.\n"); 00180 CliSetDefaultImeHotKeys(DefaultHotKeyTableJ, DefaultHotKeyNumJ, fFoundAny); 00181 } 00182 00183 if (feKbds.fKOR) { 00184 TAGMSG0(DBGTAG_IMM, "KOR KL Preloaded, but KOR hotkeys will not be registered.\n"); 00185 } 00186 00187 if (feKbds.fCHT) { 00188 TAGMSG0(DBGTAG_IMM, "CHT KL Preloaded.\n"); 00189 CliSetDefaultImeHotKeys(DefaultHotKeyTableT, DefaultHotKeyNumT, fFoundAny); 00190 } 00191 if (feKbds.fCHS) { 00192 TAGMSG0(DBGTAG_IMM, "CHS KL Preloaded.\n"); 00193 CliSetDefaultImeHotKeys(DefaultHotKeyTableC, DefaultHotKeyNumC, fFoundAny); 00194 } 00195 } 00196 00197 VOID CliSetDefaultImeHotKeys(PCIMEHOTKEY ph, INT num, BOOL fNeedToCheckExistingHotKey) 00198 { 00199 IMEHOTKEY hkt; 00200 00201 while( num-- > 0 ) { 00202 // 00203 // Set IME hotkey only if there is no such 00204 // hotkey in the registry 00205 // 00206 if (!fNeedToCheckExistingHotKey || 00207 !NtUserGetImeHotKey(ph->dwHotKeyID, &hkt.uModifiers, &hkt.uVKey, &hkt.hKL)) { 00208 00209 CliImmSetHotKeyWorker(ph->dwHotKeyID, 00210 ph->uModifiers, 00211 ph->uVKey, 00212 ph->hKL, 00213 ISHK_ADD); 00214 } 00215 ph++; 00216 } 00217 } 00218 00219 /***************************************************************************\ 00220 * CliGetPreloadKeyboardLayouts() 00221 * 00222 * Read the User registry and enumerate values in Keyboard Layouts\Preload 00223 * to see which FE languages are to be preloaded. 00224 * 00225 * History: 00226 * 03-Dec-1997 Hiroyama Created 00227 \***************************************************************************/ 00228 00229 VOID CliGetPreloadKeyboardLayouts(FE_KEYBOARDS* pFeKbds) 00230 { 00231 UINT i; 00232 WCHAR szPreLoadee[4]; // up to 999 preloads 00233 WCHAR lpszName[KL_NAMELENGTH]; 00234 UNICODE_STRING UnicodeString; 00235 HKL hkl; 00236 00237 for (i = 1; i < 1000; i++) { 00238 wsprintf(szPreLoadee, L"%d", i); 00239 if ((GetPrivateProfileStringW( 00240 L"Preload", 00241 szPreLoadee, 00242 L"", // default = NULL 00243 lpszName, // output buffer 00244 KL_NAMELENGTH, 00245 L"keyboardlayout.ini") == -1 ) || (*lpszName == L'\0')) { 00246 break; 00247 } 00248 RtlInitUnicodeString(&UnicodeString, lpszName); 00249 RtlUnicodeStringToInteger(&UnicodeString, 16L, (PULONG)&hkl); 00250 00251 RIPMSG2(RIP_VERBOSE, "PreLoaded HKL(%d): %08X\n", i, hkl); 00252 00253 // 00254 // Set language flags. By its definition, LOWORD(hkl) is LANGID 00255 // 00256 SetFeKeyboardFlags(LOWORD(HandleToUlong(hkl)), pFeKbds); 00257 } 00258 } 00259 00260 BOOL CliGetImeHotKeysFromRegistry() 00261 { 00262 BOOL fFoundAny = FALSE; 00263 00264 HANDLE hCurrentUserKey; 00265 HANDLE hKeyHotKeys; 00266 00267 OBJECT_ATTRIBUTES Obja; 00268 UNICODE_STRING SubKeyName; 00269 00270 NTSTATUS Status; 00271 ULONG uIndex; 00272 00273 // 00274 // Open the current user registry key 00275 // 00276 Status = RtlOpenCurrentUser(MAXIMUM_ALLOWED, &hCurrentUserKey); 00277 if (!NT_SUCCESS(Status)) { 00278 return fFoundAny; 00279 } 00280 00281 RtlInitUnicodeString( &SubKeyName, szRegImeHotKey ); 00282 InitializeObjectAttributes( &Obja, 00283 &SubKeyName, 00284 OBJ_CASE_INSENSITIVE, 00285 hCurrentUserKey, 00286 NULL); 00287 Status = NtOpenKey( &hKeyHotKeys, KEY_READ, &Obja ); 00288 if (!NT_SUCCESS(Status)) { 00289 NtClose( hCurrentUserKey ); 00290 return fFoundAny; 00291 } 00292 00293 for (uIndex = 0; TRUE; uIndex++) { 00294 BYTE KeyBuffer[sizeof(KEY_BASIC_INFORMATION) + 16 * sizeof(WCHAR)]; 00295 PKEY_BASIC_INFORMATION pKeyInfo; 00296 ULONG ResultLength; 00297 00298 pKeyInfo = (PKEY_BASIC_INFORMATION)KeyBuffer; 00299 Status = NtEnumerateKey(hKeyHotKeys, 00300 uIndex, 00301 KeyBasicInformation, 00302 pKeyInfo, 00303 sizeof( KeyBuffer ), 00304 &ResultLength ); 00305 00306 if (NT_SUCCESS(Status)) { 00307 00308 if (CliSetSingleHotKey(pKeyInfo, hKeyHotKeys)) { 00309 00310 fFoundAny = TRUE; 00311 } 00312 00313 } else if (Status == STATUS_NO_MORE_ENTRIES) { 00314 break; 00315 } 00316 } 00317 00318 NtClose(hKeyHotKeys); 00319 NtClose(hCurrentUserKey); 00320 00321 return fFoundAny; 00322 } 00323 00324 DWORD CliReadRegistryValue(HANDLE hKey, PCWSTR pName) 00325 { 00326 BYTE ValueBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 16 * sizeof(UCHAR)]; 00327 PKEY_VALUE_PARTIAL_INFORMATION pKeyValue; 00328 UNICODE_STRING ValueName; 00329 ULONG ResultLength; 00330 NTSTATUS Status; 00331 00332 pKeyValue = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer; 00333 00334 RtlInitUnicodeString(&ValueName, pName); 00335 Status = NtQueryValueKey(hKey, 00336 &ValueName, 00337 KeyValuePartialInformation, 00338 pKeyValue, 00339 sizeof(ValueBuffer), 00340 &ResultLength ); 00341 00342 if (NT_SUCCESS(Status) && pKeyValue->DataLength > 3) { 00343 // 00344 // In Win95 registry, these items are written as BYTE data... 00345 // 00346 return (DWORD)(MAKEWORD( pKeyValue->Data[0], pKeyValue->Data[1])) | 00347 (((DWORD)(MAKEWORD( pKeyValue->Data[2], pKeyValue->Data[3]))) << 16); 00348 } 00349 00350 return 0; 00351 } 00352 00353 BOOL CliSetSingleHotKey(PKEY_BASIC_INFORMATION pKeyInfo, HANDLE hKey) 00354 { 00355 UNICODE_STRING SubKeyName; 00356 HANDLE hKeySingleHotKey; 00357 OBJECT_ATTRIBUTES Obja; 00358 00359 DWORD dwID = 0; 00360 UINT uVKey = 0; 00361 UINT uModifiers = 0; 00362 HKL hKL = NULL; 00363 00364 NTSTATUS Status; 00365 00366 SubKeyName.Buffer = (PWSTR)&(pKeyInfo->Name[0]); 00367 SubKeyName.Length = (USHORT)pKeyInfo->NameLength; 00368 SubKeyName.MaximumLength = (USHORT)pKeyInfo->NameLength; 00369 InitializeObjectAttributes(&Obja, 00370 &SubKeyName, 00371 OBJ_CASE_INSENSITIVE, 00372 hKey, 00373 NULL); 00374 00375 Status = NtOpenKey(&hKeySingleHotKey, KEY_READ, &Obja); 00376 if (!NT_SUCCESS(Status)) { 00377 return FALSE; 00378 } 00379 00380 RtlUnicodeStringToInteger(&SubKeyName, 16L, &dwID); 00381 uVKey = CliReadRegistryValue(hKeySingleHotKey, szRegVK); 00382 uModifiers = CliReadRegistryValue(hKeySingleHotKey, szRegMOD); 00383 hKL = (HKL)LongToHandle( CliReadRegistryValue(hKeySingleHotKey, szRegHKL) ); 00384 00385 NtClose(hKeySingleHotKey); 00386 00387 return CliImmSetHotKeyWorker(dwID, uModifiers, uVKey, hKL, ISHK_ADD); 00388 } 00389 00390 /***************************************************************************\ 00391 * ImmSetHotKey() 00392 * 00393 * Private API for IMEs and the control panel. 00394 * 00395 * History: 00396 * 25-Mar-1996 TakaoK Created 00397 \***************************************************************************/ 00398 BOOL WINAPI CliImmSetHotKey( 00399 DWORD dwID, 00400 UINT uModifiers, 00401 UINT uVKey, 00402 HKL hkl) 00403 { 00404 BOOL fResult; 00405 BOOL fTmp; 00406 BOOL fDelete = (uVKey == 0 ); 00407 00408 if (fDelete) { 00409 // 00410 // Removing an IME hotkey from the list in the kernel side 00411 // should not be failed, if we succeed to remove the IME 00412 // hotkey entry from the registry. Therefore CliSaveImeHotKey 00413 // is called first. 00414 // 00415 fResult = CliSaveImeHotKey( dwID, uModifiers, uVKey, hkl, fDelete ); 00416 if (fResult) { 00417 fTmp = CliImmSetHotKeyWorker( dwID, uModifiers, uVKey, hkl, ISHK_REMOVE ); 00418 UserAssert(fTmp); 00419 } 00420 } else { 00421 // 00422 // CliImmSetHotKeyWorker should be called first since 00423 // adding an IME hotkey into the list in the kernel side 00424 // will be failed in various reasons. 00425 // 00426 fResult = CliImmSetHotKeyWorker(dwID, uModifiers, uVKey, hkl, ISHK_ADD); 00427 if (fResult) { 00428 fResult = CliSaveImeHotKey(dwID, uModifiers, uVKey, hkl, fDelete); 00429 if (!fResult) { 00430 // 00431 // We failed to save the hotkey to the registry. 00432 // We need to remove the entry from the IME hotkey 00433 // list in the kernel side. 00434 // 00435 fTmp = CliImmSetHotKeyWorker(dwID, uModifiers, uVKey, hkl, ISHK_REMOVE); 00436 UserAssert(fTmp); 00437 } 00438 } 00439 } 00440 return fResult; 00441 } 00442 00443 /***************************************************************************\ 00444 * Open/CloseRegApi 00445 * 00446 * Open and Close Regstry APIs in ADVAPI32.DLL 00447 * 00448 * History: 00449 * 17-Aug-98 Hiroyama 00450 \***************************************************************************/ 00451 00452 #define GET(a) \ 00453 if ((pfn->a = (void*)GetProcAddress(pfn->hModule, #a)) == NULL) { \ 00454 RIPMSG0(RIP_WARNING, "OpenRegApi: " #a " cannot be imported."); \ 00455 FreeLibrary(pfn->hModule); \ 00456 return FALSE; \ 00457 } 00458 00459 ADVAPI_FN gAdvApiFn; 00460 00461 BOOL OpenRegApi(ADVAPI_FN* pfn) 00462 { 00463 pfn->hModule = LoadLibraryW(L"ADVAPI32.DLL"); 00464 00465 if (pfn->hModule != NULL) { 00466 GET(RegCreateKeyW); 00467 GET(RegOpenKeyW); 00468 GET(RegCloseKey); 00469 GET(RegDeleteKeyW); 00470 GET(RegCreateKeyExW); 00471 GET(RegSetValueExW); 00472 GET(RegQueryValueExW); 00473 00474 // 00475 // Succeeded. 00476 // 00477 return TRUE; 00478 } 00479 00480 // 00481 // Failed to open registry APIs. 00482 // 00483 return TRUE; 00484 } 00485 00486 void CloseRegApi(ADVAPI_FN* pfn) 00487 { 00488 UserAssert(pfn->hModule); 00489 if (pfn->hModule) { 00490 FreeLibrary(pfn->hModule); 00491 pfn->hModule; 00492 } 00493 } 00494 00495 #undef GET 00496 00497 /***************************************************************************\ 00498 * CliSaveImeHotKey() 00499 * 00500 * Put/Remove the specified IME hotkey entry from the registry 00501 * 00502 * History: 00503 * 25-Mar-1996 TakaoK Created 00504 \***************************************************************************/ 00505 00506 extern BOOL CliSaveImeHotKeyWorker(DWORD, UINT, UINT, HKL, BOOL, ADVAPI_FN*); 00507 00508 BOOL CliSaveImeHotKey(DWORD id, UINT mod, UINT vk, HKL hkl, BOOL fDelete) 00509 { 00510 BOOL fRet = FALSE; 00511 ADVAPI_FN fn; 00512 00513 if (OpenRegApi(&fn)) { 00514 fRet = CliSaveImeHotKeyWorker(id, mod, vk, hkl, fDelete, &fn); 00515 CloseRegApi(&fn); 00516 } 00517 00518 return fRet; 00519 } 00520 00521 BOOL CliSaveImeHotKeyWorker(DWORD id, UINT mod, UINT vk, HKL hkl, BOOL fDelete, ADVAPI_FN* fn) 00522 { 00523 HKEY hKey, hKeyParent; 00524 INT i; 00525 LONG lResult; 00526 TCHAR szHex[16]; 00527 00528 if (fDelete) { 00529 TCHAR szRegTmp[(sizeof(szRegImeHotKey) / sizeof(TCHAR) + 1 + 8 + 1)]; 00530 00531 lstrcpy(szRegTmp, szRegImeHotKey); 00532 lstrcat(szRegTmp, TEXT("\\")); 00533 NumToHexAscii(id, szHex); 00534 lstrcat(szRegTmp, szHex); 00535 00536 lResult = fn->RegDeleteKey(HKEY_CURRENT_USER, szRegTmp); 00537 if (lResult != ERROR_SUCCESS) { 00538 RIPERR1(lResult, RIP_WARNING, 00539 "CliSaveImeHotKeyWorker: deleting %s failed", szRegTmp); 00540 return FALSE; 00541 } 00542 return TRUE; 00543 } 00544 00545 hKeyParent = HKEY_CURRENT_USER; 00546 for (i = 0; szaRegImmHotKeys[i] != NULL; i++) { 00547 lResult = fn->RegCreateKeyEx(hKeyParent, 00548 szaRegImmHotKeys[i], 00549 0, 00550 NULL, 00551 REG_OPTION_NON_VOLATILE, 00552 KEY_WRITE|KEY_READ, 00553 NULL, 00554 &hKey, 00555 NULL ); 00556 fn->RegCloseKey(hKeyParent); 00557 if (lResult == ERROR_SUCCESS) { 00558 hKeyParent = hKey; 00559 } else { 00560 RIPERR1(lResult, RIP_WARNING, 00561 "CliSaveImeHotKeyWorker: creating %s failed", szaRegImmHotKeys[i]); 00562 00563 return FALSE; 00564 } 00565 } 00566 00567 NumToHexAscii(id, szHex); 00568 lResult = fn->RegCreateKeyEx(hKeyParent, 00569 szHex, 00570 0, 00571 NULL, 00572 REG_OPTION_NON_VOLATILE, 00573 KEY_WRITE|KEY_READ, 00574 NULL, 00575 &hKey, 00576 NULL ); 00577 fn->RegCloseKey(hKeyParent); 00578 if (lResult != ERROR_SUCCESS) { 00579 RIPERR1(lResult, RIP_WARNING, 00580 "CliSaveImeHotKeyWorker: creating %s failed", szHex ); 00581 return FALSE; 00582 } 00583 00584 lResult = fn->RegSetValueExW(hKey, 00585 szRegVK, 00586 0, 00587 REG_BINARY, 00588 (LPBYTE)&vk, 00589 sizeof(DWORD)); 00590 if (lResult != ERROR_SUCCESS) { 00591 fn->RegCloseKey(hKey); 00592 CliSaveImeHotKey(id, vk, mod, hkl, TRUE); 00593 RIPERR1( lResult, RIP_WARNING, 00594 "SaveImeHotKey:setting value on %s failed", szRegVK ); 00595 return ( FALSE ); 00596 } 00597 lResult = fn->RegSetValueExW(hKey, 00598 szRegMOD, 00599 0, 00600 REG_BINARY, 00601 (LPBYTE)&mod, 00602 sizeof(DWORD)); 00603 00604 if (lResult != ERROR_SUCCESS) { 00605 fn->RegCloseKey(hKey); 00606 CliSaveImeHotKey(id, vk, mod, hkl, TRUE); 00607 RIPERR1(lResult, RIP_WARNING, 00608 "CliSaveImeHotKeyWorker: setting value on %s failed", szRegMOD); 00609 return FALSE; 00610 } 00611 00612 lResult = fn->RegSetValueExW(hKey, 00613 szRegHKL, 00614 0, 00615 REG_BINARY, 00616 (LPBYTE)&hkl, 00617 sizeof(DWORD) ); 00618 00619 if (lResult != ERROR_SUCCESS) { 00620 fn->RegCloseKey(hKey); 00621 CliSaveImeHotKey(id, vk, mod, hkl, TRUE); 00622 RIPERR1(lResult, RIP_WARNING, 00623 "CliSaveImeHotKeyWorker: setting value on %s failed", szRegHKL); 00624 return FALSE; 00625 } 00626 00627 fn->RegCloseKey(hKey); 00628 return TRUE; 00629 } 00630 00631 BOOL CliImmSetHotKeyWorker( 00632 DWORD dwID, 00633 UINT uModifiers, 00634 UINT uVKey, 00635 HKL hkl, 00636 DWORD dwAction) 00637 { 00638 // 00639 // if we're adding an IME hotkey entry, let's check 00640 // the parameters before calling the kernel side code 00641 // 00642 if (dwAction == ISHK_ADD) { 00643 00644 if (dwID >= IME_HOTKEY_DSWITCH_FIRST && 00645 dwID <= IME_HOTKEY_DSWITCH_LAST) { 00646 // 00647 // IME direct switching hot key - switch to 00648 // the keyboard layout specified. 00649 // We need to specify keyboard layout. 00650 // 00651 if (hkl == NULL) { 00652 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "hkl should be specified"); 00653 return FALSE; 00654 } 00655 00656 } else { 00657 // 00658 // normal hot keys - change the mode of current iME 00659 // 00660 // Because it should be effective in all IME no matter 00661 // which IME is active we should not specify a target IME 00662 // 00663 if (hkl != NULL) { 00664 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "hkl shouldn't be specified"); 00665 return FALSE; 00666 } 00667 00668 if (dwID >= IME_KHOTKEY_FIRST && dwID <= IME_KHOTKEY_LAST) { 00669 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "Hotkey for Korean IMEs are invalid."); 00670 return FALSE; 00671 } 00672 } 00673 00674 if (uModifiers & MOD_MODIFY_KEYS) { 00675 // 00676 // Because normal keyboard has left and right key for 00677 // these keys, you should specify left or right ( or both ) 00678 // 00679 if ((uModifiers & MOD_BOTH_SIDES) == 0) { 00680 RIPERR3(ERROR_INVALID_PARAMETER, RIP_WARNING, "invalid modifiers %x for id %x vKey %x", uModifiers, dwID, uVKey); 00681 return FALSE; 00682 } 00683 } 00684 00685 #if 0 // Skip this check for now 00686 // 00687 // It doesn't make sense if vkey is same as modifiers 00688 // 00689 if ( ((uModifiers & MOD_ALT) && (uVKey == VK_MENU)) || 00690 ((uModifiers & MOD_CONTROL) && (uVKey == VK_CONTROL)) || 00691 ((uModifiers & MOD_SHIFT) && (uVKey == VK_SHIFT)) || 00692 ((uModifiers & MOD_WIN) && ((uVKey == VK_LWIN)||(uVKey == VK_RWIN))) 00693 ) { 00694 00695 RIPERR0( ERROR_INVALID_PARAMETER, RIP_WARNING, "vkey and modifiers are same"); 00696 return FALSE; 00697 } 00698 #endif 00699 } 00700 return NtUserSetImeHotKey(dwID, uModifiers, uVKey, hkl, dwAction); 00701 } 00702 00703 // 00704 // NumToHexAscii 00705 // 00706 // convert a DWORD into the hex string 00707 // (e.g. 0x31 -> "00000031") 00708 // 00709 // 29-Jan-1996 takaok ported from Win95. 00710 // 00711 static CONST TCHAR szHexString[] = TEXT("0123456789ABCDEF"); 00712 00713 VOID 00714 NumToHexAscii( 00715 DWORD dwNum, 00716 PWSTR szAscii) 00717 { 00718 int i; 00719 00720 for (i = 7; i >= 0; i--) { 00721 szAscii[i] = szHexString[dwNum & 0x0000000f]; 00722 dwNum >>= 4; 00723 } 00724 szAscii[8] = TEXT('\0'); 00725 00726 return; 00727 } 00728

Generated on Sat May 15 19:40:21 2004 for test by doxygen 1.3.7