windows-nt/Source/XPSP1/NT/shell/osshell/accesory/eudcedit/imeblink.c
2020-09-26 16:20:57 +08:00

230 lines
6.2 KiB
C

//
// Copyright (c) 1997-1999 Microsoft Corporation.
//
#include <windows.h>
#include <imm.h>
#include "resource.h"
#include "imeblink.h"
#define UNICODE_CP 1200
/************************************************************/
/* MatchImeName() */
/************************************************************/
HKL MatchImeName(
LPCTSTR szStr)
{
TCHAR szImeName[16];
int nLayout;
HKL hKL;
HGLOBAL hMem;
HKL FAR * lpMem;
int i;
nLayout = GetKeyboardLayoutList(0, NULL);
// alloc temp buffer
hMem = GlobalAlloc(GHND, sizeof(HKL) * nLayout);
if (!hMem) {
return (NULL);
}
lpMem = (HKL FAR *)GlobalLock(hMem);
if (!lpMem) {
GlobalFree(hMem);
return (NULL);
}
// get all keyboard layouts, it includes all IMEs
GetKeyboardLayoutList(nLayout, lpMem);
for (i = 0; i < nLayout; i++) {
LRESULT lRet;
hKL = *(lpMem + i);
lRet = ImmEscape(hKL, (HIMC)NULL, IME_ESC_IME_NAME, szImeName);
if (!lRet) { // this hKL can not ask name
continue;
}
if (lstrcmp(szStr, szImeName) == 0) {
goto MatchOvr;
}
}
hKL = NULL;
MatchOvr:
GlobalUnlock(hMem);
GlobalFree(hMem);
return (hKL);
}
/************************************************************/
/* RegisterTable() */
/************************************************************/
HKL RegisterTable(
HWND hWnd,
LPUSRDICIMHDR lpIsvUsrDic,
DWORD dwFileSize,
UINT uCodePage)
{
HKL hKL;
// HDC hDC;
// SIZE lTextSize;
// RECT rcProcess;
DWORD i;
LPBYTE lpCurr, lpEnd;
BOOL fRet;
TCHAR szStr[16];
// TCHAR szProcessFmt[32];
// TCHAR szResult[2][32];
// TCHAR szProcessInfo[48];
WORD wInternalCode[256];
WORD wAltInternalCode[256];
#ifdef UNICODE
if (uCodePage == UNICODE_CP) {
LPUNATSTR lpszMethodName;
lpszMethodName = (LPUNATSTR)lpIsvUsrDic->achMethodName;
for (i = 0; i < sizeof(lpIsvUsrDic->achMethodName) / sizeof(TCHAR); i++) {
szStr[i] = *lpszMethodName++;
}
szStr[i] = '\0';
} else {
UINT uLen;
uLen = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED,
(LPCSTR)lpIsvUsrDic->achMethodName,
sizeof(lpIsvUsrDic->achMethodName),
szStr,
sizeof(szStr) / sizeof(TCHAR));
if (uLen == 0)
{
uCodePage = CP_ACP;
uLen = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED,
(LPCSTR)lpIsvUsrDic->achMethodName,
sizeof(lpIsvUsrDic->achMethodName),
szStr,
sizeof(szStr) / sizeof(TCHAR));
}
szStr[uLen] = '\0';
}
#else
for (i = 0; i < sizeof(lpIsvUsrDic->achMethodName); i++) {
szStr[i] = lpIsvUsrDic->achMethodName[i];
}
szStr[i] = '\0';
#endif
hKL = MatchImeName(szStr);
if (!hKL) {
return (hKL);
}
// convert sequence code to internal code
for (i = 0; i < sizeof(wInternalCode) / sizeof(WORD); i++) {
LRESULT lRet;
lRet = ImmEscape(hKL, (HIMC)NULL,
IME_ESC_SEQUENCE_TO_INTERNAL, &i);
if (HIWORD(lRet) == 0xFFFF) {
// This is caused by sign extent in Win9x in the return value of
// ImmEscape, it causes an invalid internal code.
wAltInternalCode[i] = 0;
} else {
wAltInternalCode[i] = HIWORD(lRet);
}
wInternalCode[i] = LOWORD(lRet);
#ifndef UNICODE
if (wAltInternalCode[i] > 0xFF) {
// convert to multi byte string
wAltInternalCode[i] = LOBYTE(wAltInternalCode[i]) << 8 |
HIBYTE(wAltInternalCode[i]);
}
if (wInternalCode[i] > 0xFF) {
// convert to multi byte string
wInternalCode[i] = LOBYTE(wInternalCode[i]) << 8 |
HIBYTE(wInternalCode[i]);
}
#endif
}
// check for each record and register it
// get to the first record and skip the Bank ID
lpCurr = (LPBYTE)(lpIsvUsrDic + 1) + sizeof(WORD);
lpEnd = (LPBYTE)lpIsvUsrDic + dwFileSize;
for (; lpCurr < lpEnd;
// internal code + sequence code + Bank ID of next record
lpCurr += sizeof(WORD) + lpIsvUsrDic->cMethodKeySize + sizeof(WORD)) {
int j;
// quick way to init \0 for the register string
*(LPDWORD)szStr = 0;
#ifdef UNICODE
if (uCodePage == UNICODE_CP) {
szStr[0] = *(LPUNATSTR)lpCurr;
} else {
CHAR szMultiByte[4];
szMultiByte[0] = HIBYTE(*(LPTSTR)lpCurr);
szMultiByte[1] = LOBYTE(*(LPTSTR)lpCurr);
MultiByteToWideChar(uCodePage, MB_PRECOMPOSED,
szMultiByte, 2, szStr, 2);
}
#else
szStr[1] = *lpCurr;
szStr[0] = *(lpCurr + 1);
#endif
for (i = 0, j = 0; i < lpIsvUsrDic->cMethodKeySize; i++) {
if (!wAltInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)]) {
} else if (wAltInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)] < 0xFF) {
*(LPTSTR)&szStr[4 + j] = (TCHAR)
wAltInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)];
j += sizeof(TCHAR) / sizeof(TCHAR);
} else {
*(LPWSTR)&szStr[4 + j] = (WCHAR)
wAltInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)];
j += sizeof(WCHAR) / sizeof(TCHAR);
}
if (wInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)] < 0xFF) {
*(LPTSTR)&szStr[4 + j] = (TCHAR)
wInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)];
j += sizeof(TCHAR) / sizeof(TCHAR);
} else {
*(LPWSTR)&szStr[4 + j] = (WCHAR)
wInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)];
j += sizeof(WCHAR) / sizeof(TCHAR);
}
}
szStr[4 + j] = szStr[4 + j + 1] = szStr[4 + j + 2] = '\0';
fRet = ImmRegisterWord(hKL, &szStr[4], IME_REGWORD_STYLE_EUDC,
szStr);
}
return (hKL);
}