00001
00002
00003
00004
00005
00006
00007
00008
00009
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
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
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
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
00067
00068
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
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
00121
00122
00123
00124
00125
00126
00127
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
00137
CliImmSetHotKeyWorker(0, 0, 0,
NULL,
ISHK_INITIALIZE);
00138
00139
00140
00141 fFoundAny =
CliGetImeHotKeysFromRegistry();
00142
00143
if (dwAction ==
ISHK_INITIALIZE) {
00144 TAGMSG0(DBGTAG_IMM,
"Setting IME HotKeys for Init.\n");
00145
00146
00147
SetFeKeyboardFlags(LANGIDFROMLCID(GetUserDefaultLCID()), &feKbds);
00148
00149
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
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
00204
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
00221
00222
00223
00224
00225
00226
00227
00228
00229 VOID CliGetPreloadKeyboardLayouts(
FE_KEYBOARDS* pFeKbds)
00230 {
00231
UINT i;
00232 WCHAR szPreLoadee[4];
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"",
00243 lpszName,
00244 KL_NAMELENGTH,
00245
L"keyboardlayout.ini") == -1 ) || (*lpszName ==
L'\0')) {
00246
break;
00247 }
00248
RtlInitUnicodeString(&UnicodeString, lpszName);
00249
RtlUnicodeStringToInteger(&UnicodeString, 16
L, (PULONG)&hkl);
00250
00251 RIPMSG2(RIP_VERBOSE,
"PreLoaded HKL(%d): %08X\n", i, hkl);
00252
00253
00254
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
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
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, 16
L, &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
00392
00393
00394
00395
00396
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
00411
00412
00413
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
00423
00424
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
00432
00433
00434
00435 fTmp =
CliImmSetHotKeyWorker(dwID, uModifiers, uVKey, hkl,
ISHK_REMOVE);
00436 UserAssert(fTmp);
00437 }
00438 }
00439 }
00440
return fResult;
00441 }
00442
00443
00444
00445
00446
00447
00448
00449
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
00476
00477
return TRUE;
00478 }
00479
00480
00481
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
00499
00500
00501
00502
00503
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
00640
00641
00642
if (dwAction ==
ISHK_ADD) {
00643
00644
if (dwID >= IME_HOTKEY_DSWITCH_FIRST &&
00645 dwID <= IME_HOTKEY_DSWITCH_LAST) {
00646
00647
00648
00649
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
00659
00660
00661
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
00677
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
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
00705
00706
00707
00708
00709
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