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

layout.c

Go to the documentation of this file.
00001 /**************************************************************************\ 00002 * Module Name: layout.c (corresponds to Win95 ime.c) 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * IME Keyboard Layout related functionality 00007 * 00008 * History: 00009 * 03-Jan-1996 wkwok Created 00010 \**************************************************************************/ 00011 00012 #include "precomp.h" 00013 #pragma hdrstop 00014 00015 /* 00016 * Local Defines. 00017 */ 00018 #define szLZOpenFileW "LZOpenFileW" 00019 #define szLZCopy "LZCopy" 00020 #define szLZClose "LZClose" 00021 00022 typedef HFILE (WINAPI *LPFNLZOPENFILEW)(LPTSTR, LPOFSTRUCT, WORD); 00023 typedef LONG (WINAPI *LPFNLZCOPY)(INT, INT); 00024 typedef VOID (WINAPI *LPFNLZCLOSE)(INT); 00025 00026 /* 00027 * Local Routines. 00028 */ 00029 UINT StrToUInt(LPWSTR); 00030 VOID UIntToStr(UINT, ULONG, LPWSTR, USHORT); 00031 BOOL CopyImeFile(LPWSTR, LPCWSTR); 00032 INT GetImeLayout(PIMELAYOUT, INT); 00033 BOOL WriteImeLayout(HKL, LPCWSTR, LPCWSTR); 00034 HKL AssignNewLayout(INT, PIMELAYOUT, HKL); 00035 00036 00037 /***************************************************************************\ 00038 * ImmGetIMEFileNameW 00039 * 00040 * Gets the description of the IME with the specified HKL. 00041 * 00042 * History: 00043 * 28-Feb-1995 wkwok Created 00044 \***************************************************************************/ 00045 00046 UINT WINAPI ImmGetDescriptionW( 00047 HKL hKL, 00048 LPWSTR lpwszDescription, 00049 UINT uBufLen) 00050 { 00051 IMEINFOEX iiex; 00052 UINT uRet; 00053 00054 if (!ImmGetImeInfoEx(&iiex, ImeInfoExKeyboardLayout, &hKL)) 00055 return 0; 00056 00057 uRet = wcslen(iiex.wszImeDescription); 00058 00059 /* 00060 * ask buffer length 00061 */ 00062 if (uBufLen == 0) 00063 return uRet; 00064 00065 if (uBufLen > uRet) { 00066 wcscpy(lpwszDescription, iiex.wszImeDescription); 00067 } 00068 else { 00069 uRet = uBufLen - 1; 00070 wcsncpy(lpwszDescription, iiex.wszImeDescription, uRet); 00071 lpwszDescription[uRet] = L'\0'; 00072 } 00073 00074 return uRet; 00075 } 00076 00077 00078 /***************************************************************************\ 00079 * ImmGetIMEFileNameA 00080 * 00081 * Gets the description of the IME with the specified HKL. 00082 * 00083 * History: 00084 * 28-Feb-1995 wkwok Created 00085 \***************************************************************************/ 00086 00087 UINT WINAPI ImmGetDescriptionA( 00088 HKL hKL, 00089 LPSTR lpszDescription, 00090 UINT uBufLen) 00091 { 00092 IMEINFOEX iiex; 00093 INT i; 00094 BOOL bUDC; 00095 00096 if (!ImmGetImeInfoEx(&iiex, ImeInfoExKeyboardLayout, &hKL)) 00097 return 0; 00098 00099 i = WideCharToMultiByte(CP_ACP, 00100 (DWORD)0, 00101 (LPWSTR)iiex.wszImeDescription, // src 00102 wcslen(iiex.wszImeDescription), 00103 lpszDescription, // dest 00104 uBufLen, 00105 (LPSTR)NULL, 00106 (LPBOOL)&bUDC); 00107 00108 if (uBufLen != 0) 00109 lpszDescription[i] = '\0'; 00110 00111 return (UINT)i; 00112 } 00113 00114 00115 /***************************************************************************\ 00116 * ImmGetIMEFileNameW 00117 * 00118 * Gets the file name of the IME with the specified HKL. 00119 * 00120 * History: 00121 * 28-Feb-1995 wkwok Created 00122 \***************************************************************************/ 00123 00124 UINT WINAPI ImmGetIMEFileNameW( 00125 HKL hKL, 00126 LPWSTR lpwszFile, 00127 UINT uBufLen) 00128 { 00129 IMEINFOEX iiex; 00130 UINT uRet; 00131 00132 if (!ImmGetImeInfoEx(&iiex, ImeInfoExKeyboardLayout, &hKL)) 00133 return 0; 00134 00135 uRet = wcslen(iiex.wszImeFile); 00136 00137 /* 00138 * ask buffer length 00139 */ 00140 if (uBufLen == 0) 00141 return uRet; 00142 00143 if (uBufLen > uRet) { 00144 wcscpy(lpwszFile, iiex.wszImeFile); 00145 } 00146 else { 00147 uRet = uBufLen - 1; 00148 wcsncpy(lpwszFile, iiex.wszImeFile, uRet); 00149 lpwszFile[uRet] = L'\0'; 00150 } 00151 00152 return uRet; 00153 } 00154 00155 00156 /***************************************************************************\ 00157 * ImmGetIMEFileNameA 00158 * 00159 * Gets the file name of the IME with the specified HKL. 00160 * 00161 * History: 00162 * 28-Feb-1995 wkwok Created 00163 \***************************************************************************/ 00164 00165 UINT WINAPI ImmGetIMEFileNameA( 00166 HKL hKL, 00167 LPSTR lpszFile, 00168 UINT uBufLen) 00169 { 00170 IMEINFOEX iiex; 00171 INT i; 00172 BOOL bUDC; 00173 00174 if (!ImmGetImeInfoEx(&iiex, ImeInfoExKeyboardLayout, &hKL)) 00175 return 0; 00176 00177 i = WideCharToMultiByte(CP_ACP, 00178 (DWORD)0, 00179 (LPWSTR)iiex.wszImeFile, // src 00180 wcslen(iiex.wszImeFile), 00181 lpszFile, // dest 00182 uBufLen, 00183 (LPSTR)NULL, 00184 (LPBOOL)&bUDC); 00185 00186 if (uBufLen != 0) 00187 lpszFile[i] = '\0'; 00188 00189 return i; 00190 } 00191 00192 00193 /***************************************************************************\ 00194 * ImmGetProperty 00195 * 00196 * Gets the property and capability of the IME with the specified HKL. 00197 * 00198 * History: 00199 * 28-Feb-1995 wkwok Created 00200 \***************************************************************************/ 00201 00202 DWORD WINAPI ImmGetProperty( 00203 HKL hKL, 00204 DWORD dwIndex) 00205 { 00206 IMEINFOEX iiex; 00207 PIMEDPI pImeDpi = NULL; 00208 PIMEINFO pImeInfo; 00209 DWORD dwRet; 00210 00211 if (!ImmGetImeInfoEx(&iiex, ImeInfoExKeyboardLayout, &hKL)) 00212 return 0; 00213 00214 if (dwIndex == IGP_GETIMEVERSION) 00215 return iiex.dwImeWinVersion; 00216 00217 if (iiex.fLoadFlag != IMEF_LOADED) { 00218 pImeDpi = FindOrLoadImeDpi(hKL); 00219 if (pImeDpi == NULL) { 00220 RIPMSG0(RIP_WARNING, "ImmGetProperty: load IME failure."); 00221 return 0; 00222 } 00223 pImeInfo = &pImeDpi->ImeInfo; 00224 } 00225 else { 00226 pImeInfo = &iiex.ImeInfo; 00227 } 00228 00229 switch (dwIndex) { 00230 case IGP_PROPERTY: 00231 dwRet = pImeInfo->fdwProperty; 00232 break; 00233 00234 case IGP_CONVERSION: 00235 dwRet = pImeInfo->fdwConversionCaps; 00236 break; 00237 00238 case IGP_SENTENCE: 00239 dwRet = pImeInfo->fdwSentenceCaps; 00240 break; 00241 00242 case IGP_UI: 00243 dwRet = pImeInfo->fdwUICaps; 00244 break; 00245 00246 case IGP_SETCOMPSTR: 00247 dwRet = pImeInfo->fdwSCSCaps; 00248 break; 00249 00250 case IGP_SELECT: 00251 dwRet = pImeInfo->fdwSelectCaps; 00252 break; 00253 00254 default: 00255 RIPMSG1(RIP_WARNING, "ImmGetProperty: wrong index %lx.", dwIndex); 00256 dwRet = 0; 00257 break; 00258 } 00259 00260 ImmUnlockImeDpi(pImeDpi); 00261 00262 return dwRet; 00263 } 00264 00265 00266 HKL WINAPI ImmInstallIMEW( 00267 LPCWSTR lpszIMEFileName, 00268 LPCWSTR lpszLayoutText) 00269 { 00270 LPWSTR lpwszImeFileName; 00271 LPWSTR lpwszImeFilePart; 00272 LPWSTR lpwszImeCopiedPath; 00273 int i, nIMEs; 00274 PIMELAYOUT pImeLayout = NULL; 00275 HKL hImeKL, hLangKL; 00276 WCHAR szKeyName[HEX_ASCII_SIZE]; 00277 IMEINFOEX iiex; 00278 00279 lpwszImeFileName = ImmLocalAlloc(0, (MAX_PATH+1) * sizeof(WCHAR)); 00280 if (lpwszImeFileName == NULL) 00281 return (HKL)0; 00282 00283 lpwszImeCopiedPath = ImmLocalAlloc(0, (MAX_PATH+1) * sizeof(WCHAR)); 00284 if (lpwszImeCopiedPath == NULL) { 00285 ImmLocalFree(lpwszImeFileName); 00286 return (HKL)0; 00287 } 00288 00289 /* 00290 * Get the file name only into lpwszImeFilePart 00291 */ 00292 GetFullPathNameW(lpszIMEFileName, MAX_PATH, 00293 lpwszImeFileName, &lpwszImeFilePart); 00294 00295 CharUpper(lpwszImeFileName); 00296 00297 if (lpwszImeFilePart == NULL) { 00298 ImmLocalFree(lpwszImeFileName); 00299 ImmLocalFree(lpwszImeCopiedPath); 00300 return (HKL)0; 00301 } 00302 00303 hImeKL = hLangKL = iiex.hkl = (HKL)0; 00304 00305 wcsncpy(iiex.wszImeFile, lpwszImeFilePart, IM_FILE_SIZE-1); 00306 iiex.wszImeFile[IM_FILE_SIZE - 1] = L'\0'; 00307 00308 if (LoadVersionInfo(&iiex) && iiex.hkl != (HKL)0) { 00309 hLangKL = iiex.hkl; 00310 } 00311 else { 00312 ImmLocalFree(lpwszImeFileName); 00313 ImmLocalFree(lpwszImeCopiedPath); 00314 return (HKL)0; 00315 } 00316 00317 nIMEs = GetImeLayout(NULL, 0); 00318 if (nIMEs != 0) { 00319 pImeLayout = (PIMELAYOUT)ImmLocalAlloc(0, nIMEs * sizeof(IMELAYOUT)); 00320 if (pImeLayout == NULL) { 00321 ImmLocalFree(lpwszImeFileName); 00322 ImmLocalFree(lpwszImeCopiedPath); 00323 return (HKL)0; 00324 } 00325 00326 GetImeLayout(pImeLayout, nIMEs); 00327 00328 for (i=0; i < nIMEs; i++) { 00329 if (_wcsicmp(pImeLayout[i].szImeName, lpwszImeFilePart) == 0) { 00330 /* 00331 * We got the same IME name, ISV wants to upgrade. 00332 */ 00333 if (LOWORD(HandleToUlong(hLangKL)) != LOWORD(HandleToUlong(pImeLayout[i].hImeKL))) { 00334 /* 00335 * IME name conflict, blow out! 00336 */ 00337 RIPMSG0(RIP_WARNING, "ImmInstallIME: different language!"); 00338 goto ImmInstallIMEWFailed; 00339 } 00340 00341 hImeKL = pImeLayout[i].hImeKL; 00342 break; 00343 } 00344 } 00345 } 00346 00347 if (ImmGetImeInfoEx(&iiex, ImeInfoExImeFileName, lpwszImeFilePart)) { 00348 /* 00349 * The specified IME has been activated. Unload it first. 00350 */ 00351 if (!UnloadKeyboardLayout(iiex.hkl)) { 00352 hImeKL = (HKL)0; 00353 goto ImmInstallIMEWFailed; 00354 } 00355 } 00356 00357 /* 00358 * We will copy to system directory 00359 */ 00360 #if 0 00361 i = (INT)GetSystemDirectory(lpwszImeCopiedPath, MAX_PATH); 00362 lpwszImeCopiedPath[i] = L'\0'; 00363 AddBackslash(lpwszImeCopiedPath); 00364 wcscat(lpwszImeCopiedPath, lpwszImeFilePart); 00365 #else 00366 GetSystemPathName(lpwszImeCopiedPath, lpwszImeFilePart, MAX_PATH); 00367 #endif 00368 CharUpper(lpwszImeCopiedPath); 00369 00370 if (_wcsicmp(lpwszImeFileName, lpwszImeCopiedPath) != 0) { 00371 /* 00372 * path is different, need to copy into system directory 00373 */ 00374 if (!CopyImeFile(lpwszImeFileName, lpwszImeCopiedPath)) { 00375 hImeKL = (HKL)0; 00376 goto ImmInstallIMEWFailed; 00377 } 00378 } 00379 00380 if (hImeKL == 0) { 00381 hImeKL = AssignNewLayout(nIMEs, pImeLayout, hLangKL); 00382 } 00383 00384 if (hImeKL != 0) { 00385 /* 00386 * Write HKL under "keyboard layouts" 00387 */ 00388 if (WriteImeLayout(hImeKL, lpwszImeFilePart, lpszLayoutText)) { 00389 UIntToStr(HandleToUlong(hImeKL), 16, szKeyName, sizeof(szKeyName)); 00390 hImeKL = LoadKeyboardLayout(szKeyName, KLF_REPLACELANG); 00391 } 00392 else { 00393 hImeKL = (HKL)0; 00394 } 00395 } 00396 00397 ImmInstallIMEWFailed: 00398 if (pImeLayout != NULL) 00399 ImmLocalFree(pImeLayout); 00400 ImmLocalFree(lpwszImeFileName); 00401 ImmLocalFree(lpwszImeCopiedPath); 00402 00403 return (HKL)hImeKL; 00404 } 00405 00406 00407 HKL WINAPI ImmInstallIMEA( 00408 LPCSTR lpszIMEFileName, 00409 LPCSTR lpszLayoutText) 00410 { 00411 HKL hKL; 00412 LPWSTR lpwszIMEFileName; 00413 LPWSTR lpwszLayoutText; 00414 DWORD cbIMEFileName; 00415 DWORD cbLayoutText; 00416 INT i; 00417 00418 cbIMEFileName = strlen(lpszIMEFileName) + sizeof(CHAR); 00419 cbLayoutText = strlen(lpszLayoutText) + sizeof(CHAR); 00420 00421 lpwszIMEFileName = ImmLocalAlloc(0, cbIMEFileName * sizeof(WCHAR)); 00422 if (lpwszIMEFileName == NULL) { 00423 RIPMSG0(RIP_WARNING, "ImmInstallIMEA: memory failure!"); 00424 return (HKL)0; 00425 } 00426 00427 lpwszLayoutText = ImmLocalAlloc(0, cbLayoutText * sizeof(WCHAR)); 00428 if (lpwszLayoutText == NULL) { 00429 RIPMSG0(RIP_WARNING, "ImmInstallIMEA: memory failure!"); 00430 ImmLocalFree(lpwszIMEFileName); 00431 return (HKL)0; 00432 } 00433 00434 i = MultiByteToWideChar(CP_ACP, 00435 (DWORD)MB_PRECOMPOSED, 00436 (LPSTR)lpszIMEFileName, // src 00437 (INT)strlen(lpszIMEFileName), 00438 (LPWSTR)lpwszIMEFileName, // dest 00439 (INT)cbIMEFileName); 00440 lpwszIMEFileName[i] = L'\0'; 00441 00442 i = MultiByteToWideChar(CP_ACP, 00443 (DWORD)MB_PRECOMPOSED, 00444 (LPSTR)lpszLayoutText, // src 00445 (INT)strlen(lpszLayoutText), 00446 (LPWSTR)lpwszLayoutText, // dest 00447 (INT)cbLayoutText); 00448 lpwszLayoutText[i] = L'\0'; 00449 00450 hKL = ImmInstallIMEW(lpwszIMEFileName, lpwszLayoutText); 00451 00452 ImmLocalFree(lpwszLayoutText); 00453 ImmLocalFree(lpwszIMEFileName); 00454 00455 return hKL; 00456 } 00457 00458 00459 /***************************************************************************\ 00460 * ImmIsIME 00461 * 00462 * Checks whether the specified hKL is a HKL of an IME or not. 00463 * 00464 * History: 00465 * 28-Feb-1995 wkwok Created 00466 \***************************************************************************/ 00467 00468 BOOL WINAPI ImmIsIME( 00469 HKL hKL) 00470 { 00471 IMEINFOEX iiex; 00472 00473 if (!ImmGetImeInfoEx(&iiex, ImeInfoExKeyboardLayout, &hKL)) 00474 return FALSE; 00475 00476 return TRUE; 00477 } 00478 00479 00480 UINT StrToUInt( 00481 LPWSTR lpsz) 00482 { 00483 UNICODE_STRING Value; 00484 UINT ReturnValue; 00485 00486 Value.Length = wcslen(lpsz) * sizeof(WCHAR); 00487 Value.Buffer = lpsz; 00488 00489 /* 00490 * Convert string to int. 00491 */ 00492 RtlUnicodeStringToInteger(&Value, 16, &ReturnValue); 00493 return(ReturnValue); 00494 } 00495 00496 00497 VOID UIntToStr( 00498 UINT Value, 00499 ULONG Base, 00500 LPWSTR lpsz, 00501 USHORT dwBufLen) 00502 { 00503 UNICODE_STRING String; 00504 00505 String.Length = dwBufLen; 00506 String.MaximumLength = dwBufLen; 00507 String.Buffer = lpsz; 00508 00509 /* 00510 * Convert int to string. 00511 */ 00512 RtlIntegerToUnicodeString(Value, Base, &String); 00513 } 00514 00515 00516 BOOL CopyImeFile( 00517 LPWSTR lpwszImeFileName, 00518 LPCWSTR lpwszImeCopiedPath) 00519 { 00520 HMODULE hLzExpandDll; 00521 BOOL fUnloadExpandDll; 00522 LPFNLZOPENFILEW lpfnLZOpenFileW; 00523 LPFNLZCOPY lpfnLZCopy; 00524 LPFNLZCLOSE lpfnLZClose; 00525 OFSTRUCT ofStruc; 00526 HFILE hfSource, hfDest; 00527 LPSTR lpszImeCopiedPath; 00528 INT i, cbBuffer; 00529 BOOL fRet = FALSE; 00530 00531 hLzExpandDll = GetModuleHandle(L"LZ32"); 00532 if (hLzExpandDll) { 00533 fUnloadExpandDll = FALSE; 00534 } else { 00535 WCHAR szLzExpand[MAX_PATH]; 00536 00537 GetSystemPathName(szLzExpand, L"LZ32", MAX_PATH); 00538 hLzExpandDll = LoadLibrary(szLzExpand); 00539 if (!hLzExpandDll) { 00540 return FALSE; 00541 } 00542 00543 fUnloadExpandDll = TRUE; 00544 } 00545 00546 #define GET_PROC(x) \ 00547 if (!(lpfn##x = (PVOID) GetProcAddress(hLzExpandDll, sz##x))) { \ 00548 goto CopyImeFileFailed; } 00549 00550 GET_PROC(LZOpenFileW); 00551 GET_PROC(LZCopy); 00552 GET_PROC(LZClose); 00553 00554 #undef GET_PROC 00555 00556 cbBuffer = (wcslen(lpwszImeCopiedPath) + 1) * sizeof(WCHAR); 00557 00558 if ((lpszImeCopiedPath = ImmLocalAlloc(0, cbBuffer)) == NULL) 00559 goto CopyImeFileFailed; 00560 00561 i = WideCharToMultiByte(CP_ACP, 00562 (DWORD)0, 00563 lpwszImeCopiedPath, // src 00564 wcslen(lpwszImeCopiedPath), 00565 lpszImeCopiedPath, // dest 00566 cbBuffer, 00567 (LPSTR)NULL, 00568 (LPBOOL)NULL); 00569 if (i == 0) { 00570 ImmLocalFree(lpszImeCopiedPath); 00571 goto CopyImeFileFailed; 00572 } 00573 00574 lpszImeCopiedPath[i] = '\0'; 00575 00576 hfSource = (*lpfnLZOpenFileW)(lpwszImeFileName, &ofStruc, OF_READ); 00577 if (hfSource < 0) { 00578 ImmLocalFree(lpszImeCopiedPath); 00579 goto CopyImeFileFailed; 00580 } 00581 00582 hfDest = OpenFile(lpszImeCopiedPath, &ofStruc, OF_CREATE); 00583 if (hfDest != HFILE_ERROR) { 00584 if ((*lpfnLZCopy)(hfSource, hfDest) >= 0) { 00585 fRet = TRUE; 00586 } 00587 _lclose(hfDest); 00588 } 00589 00590 (*lpfnLZClose)(hfSource); 00591 00592 ImmLocalFree(lpszImeCopiedPath); 00593 00594 CopyImeFileFailed: 00595 if (fUnloadExpandDll) 00596 FreeLibrary(hLzExpandDll); 00597 00598 return fRet; 00599 } 00600 00601 00602 INT GetImeLayout( 00603 PIMELAYOUT pImeLayout, 00604 INT cEntery) 00605 { 00606 int i, nIMEs; 00607 HKEY hKeyKbdLayout; 00608 HKEY hKeyOneIME; 00609 WCHAR szKeyName[HEX_ASCII_SIZE]; 00610 WCHAR szImeFileName[IM_FILE_SIZE]; 00611 DWORD dwKeyNameSize; 00612 DWORD dwTmp; 00613 00614 RegOpenKey(HKEY_LOCAL_MACHINE, gszRegKbdLayout, &hKeyKbdLayout); 00615 00616 dwKeyNameSize = sizeof(szKeyName); 00617 00618 for (i = 0, nIMEs = 0; 00619 RegEnumKey(hKeyKbdLayout, i, szKeyName, dwKeyNameSize) == ERROR_SUCCESS; 00620 i++) 00621 { 00622 if (szKeyName[0] != L'E' && szKeyName[0] != L'e') 00623 continue; // this is not an IME based keyboard layout. 00624 00625 if (pImeLayout != NULL) { 00626 00627 if (nIMEs >= cEntery) 00628 break; 00629 00630 RegOpenKey(hKeyKbdLayout, szKeyName, &hKeyOneIME); 00631 00632 dwTmp = IM_FILE_SIZE; 00633 00634 RegQueryValueEx(hKeyOneIME, 00635 gszValImeFile, 00636 NULL, 00637 NULL, 00638 (LPBYTE)szImeFileName, 00639 &dwTmp); 00640 00641 // avoid length problem 00642 szImeFileName[IM_FILE_SIZE - 1] = L'\0'; 00643 00644 RegCloseKey(hKeyOneIME); 00645 00646 CharUpper(szImeFileName); 00647 00648 pImeLayout[nIMEs].hImeKL = (HKL)IntToPtr( StrToUInt(szKeyName) ); 00649 wcscpy(pImeLayout[nIMEs].szKeyName, szKeyName); 00650 wcscpy(pImeLayout[nIMEs].szImeName, szImeFileName); 00651 } 00652 00653 nIMEs++; 00654 } 00655 00656 RegCloseKey(hKeyKbdLayout); 00657 00658 return nIMEs; 00659 } 00660 00661 00662 BOOL WriteImeLayout( 00663 HKL hImeKL, 00664 LPCWSTR lpwszImeFilePart, 00665 LPCWSTR lpszLayoutText) 00666 { 00667 int i; 00668 HKEY hKeyKbdLayout; 00669 HKEY hKeyOneIME; 00670 HKEY hKeyKbdOrder; 00671 WCHAR szKeyName[HEX_ASCII_SIZE]; 00672 WCHAR szImeFileName[IM_FILE_SIZE]; 00673 WCHAR szOrderNum[HEX_ASCII_SIZE]; 00674 WCHAR szOrderKeyName[HEX_ASCII_SIZE]; 00675 DWORD dwTmp; 00676 00677 if (RegOpenKey(HKEY_LOCAL_MACHINE, 00678 gszRegKbdLayout, 00679 &hKeyKbdLayout) != ERROR_SUCCESS) { 00680 RIPMSG0(RIP_WARNING, "WriteImeLayout: RegOpenKey() failed!"); 00681 return FALSE; 00682 } 00683 00684 UIntToStr(HandleToUlong(hImeKL), 16, szKeyName, sizeof(szKeyName)); 00685 00686 if (RegCreateKey(hKeyKbdLayout, 00687 szKeyName, 00688 &hKeyOneIME) != ERROR_SUCCESS) { 00689 RIPMSG0(RIP_WARNING, "WriteImeLayout: RegCreateKey() failed!"); 00690 RegCloseKey(hKeyKbdLayout); 00691 return FALSE; 00692 } 00693 00694 if (RegSetValueExW(hKeyOneIME, 00695 gszValImeFile, 00696 0, 00697 REG_SZ, 00698 (CONST BYTE*)lpwszImeFilePart, 00699 (wcslen(lpwszImeFilePart) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS) { 00700 goto WriteImeLayoutFail; 00701 } 00702 00703 if (RegSetValueExW(hKeyOneIME, 00704 gszValLayoutText, 00705 0, 00706 REG_SZ, 00707 (CONST BYTE*)lpszLayoutText, 00708 (wcslen(lpszLayoutText) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS) { 00709 goto WriteImeLayoutFail; 00710 } 00711 00712 switch (LANGIDFROMHKL(hImeKL)) { 00713 case LANG_JAPANESE: 00714 wcscpy(szImeFileName, L"kbdjpn.dll"); 00715 break; 00716 case LANG_KOREAN: 00717 wcscpy(szImeFileName, L"kbdkor.dll"); 00718 break; 00719 case LANG_CHINESE: 00720 default: 00721 wcscpy(szImeFileName, L"kbdus.dll"); 00722 break; 00723 } 00724 00725 if (RegSetValueExW(hKeyOneIME, 00726 gszValLayoutFile, 00727 0, 00728 REG_SZ, 00729 (CONST BYTE*)szImeFileName, 00730 (wcslen(szImeFileName) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS) { 00731 goto WriteImeLayoutFail; 00732 } 00733 00734 RegCloseKey(hKeyOneIME); 00735 RegCloseKey(hKeyKbdLayout); 00736 00737 /* 00738 * Update CurrentUser's preload keyboard layout setting 00739 */ 00740 RegCreateKey(HKEY_CURRENT_USER, gszRegKbdOrder, &hKeyKbdOrder); 00741 00742 for (i = 1; i < 1024; i++) { 00743 UIntToStr(i, 10, szOrderNum, sizeof(szOrderNum)); 00744 00745 dwTmp = sizeof(szOrderKeyName); 00746 if (RegQueryValueEx(hKeyKbdOrder, 00747 szOrderNum, 00748 NULL, 00749 NULL, 00750 (LPBYTE)szOrderKeyName, 00751 &dwTmp) != ERROR_SUCCESS) { 00752 break; 00753 } 00754 00755 if (_wcsicmp(szKeyName, szOrderKeyName) == 0) { 00756 /* 00757 * We have the same value in the preload! 00758 * OK, ISV is developing their IMEs 00759 * so even it is in preload, but it can not be loaded 00760 */ 00761 break; 00762 } 00763 } 00764 00765 if (i < 1024) { 00766 /* 00767 * Write a subkey under "preload" 00768 */ 00769 RegSetValueExW(hKeyKbdOrder, 00770 szOrderNum, 00771 0, 00772 REG_SZ, 00773 (CONST BYTE*)szKeyName, 00774 (lstrlen(szKeyName) + 1) * sizeof(WCHAR)); 00775 RegCloseKey(hKeyKbdOrder); 00776 } 00777 else { 00778 RegCloseKey(hKeyKbdOrder); 00779 return FALSE; 00780 } 00781 00782 return TRUE; 00783 00784 WriteImeLayoutFail: 00785 RegCloseKey(hKeyOneIME); 00786 RegDeleteKey(hKeyKbdLayout, szKeyName); 00787 RegCloseKey(hKeyKbdLayout); 00788 00789 return FALSE; 00790 } 00791 00792 00793 HKL AssignNewLayout( 00794 INT nIMEs, 00795 PIMELAYOUT pImeLayout, 00796 HKL hLangKL) 00797 { 00798 int i; 00799 HKL hHighKL, hLowKL; 00800 HKL hImeNewKL; 00801 00802 /* 00803 * We prefer the value higher than E01F for ISVs, we will use 00804 * E001 ~ E01F in Microsoft .INF file 00805 */ 00806 hHighKL = (HKL)((DWORD)0xE01F0000 + (ULONG_PTR)hLangKL); 00807 hLowKL = (HKL)((DWORD)0xE0FF0000 + (ULONG_PTR)hLangKL); 00808 00809 /* 00810 * Find out the high and low one 00811 */ 00812 for (i = 0; i < nIMEs; i++) { 00813 if (pImeLayout[i].hImeKL > hHighKL) { 00814 hHighKL = pImeLayout[i].hImeKL; 00815 } 00816 00817 if (pImeLayout[i].hImeKL < hLowKL) { 00818 hLowKL = pImeLayout[i].hImeKL; 00819 } 00820 } 00821 00822 /* 00823 * This way is more preferable for app consideration 00824 * we don't want app think this is a old keyboard layout 00825 * some apps will put hKL into their documents. 00826 */ 00827 if (hHighKL < (HKL)UIntToPtr( 0xE0FF0000 )) { 00828 hImeNewKL = (HKL)((ULONG_PTR)hHighKL + (DWORD)0x10000); 00829 } else if (hLowKL > (HKL)UIntToPtr( 0xE0010000 )) { 00830 hImeNewKL = (HKL)((ULONG_PTR)hLowKL - (DWORD)0x10000); 00831 } else { 00832 /* 00833 * find out a hKL using search, find it one by one 00834 */ 00835 for (hLowKL = (HKL)((DWORD)0xE0200000 + (ULONG_PTR)hLangKL); 00836 hLowKL < (HKL)UIntToPtr( 0xE1000000 ); 00837 hLowKL = (HKL)((ULONG_PTR)hLowKL + (DWORD)0x10000)) { 00838 00839 for (i = 0; i < nIMEs; i++) { 00840 if (HIWORD(HandleToUlong(pImeLayout[i].hImeKL)) == HIWORD(HandleToUlong(hLowKL))) { 00841 // conflict with existing IME, try next hLowKL 00842 break; 00843 } 00844 } 00845 00846 if (i >= nIMEs) { 00847 break; 00848 } 00849 } 00850 00851 if (hLowKL >= (HKL)UIntToPtr( 0xE1000000 )) { 00852 hImeNewKL = (HKL)0; 00853 } 00854 else { 00855 hImeNewKL = hLowKL; 00856 } 00857 } 00858 00859 return hImeNewKL; 00860 }

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