|
|
/*++
Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
Module Name:
compose.c
++*/
#include <windows.h>
#include <immdev.h>
#include <imedefs.h>
void PASCAL XGBAddCodeIntoCand(LPCANDIDATELIST, WORD); #if defined(COMBO_IME)
void PASCAL UnicodeAddCodeIntoCand(LPCANDIDATELIST, WORD); #endif
#if defined(COMBO_IME)
/**********************************************************************/ /* UnicodeEngine() */ /* Description: */ /* Conv GBcode */ /**********************************************************************/ WORD PASCAL UnicodeEngine(LPPRIVCONTEXT lpImcP) { if (lpImcP->bSeq[3] || lpImcP->bSeq[2] == TEXT('?') || lpImcP->bSeq[2] == TEXT(' ')) { if (lpImcP->bSeq[2] == TEXT('?') || lpImcP->bSeq[2] == TEXT(' ')){ lpImcP->bSeq[2] = TEXT('0'); lpImcP->bSeq[3] = TEXT('0'); } return (AsciiToGB(lpImcP)); } else { return (0); } } #endif //COMBO_IME
/**********************************************************************/ /* XGBEngine() */ /* Description: */ /* Conv GBcode */ /**********************************************************************/ WORD PASCAL XGBEngine(LPPRIVCONTEXT lpImcP) { WORD wCode;
if (lpImcP->bSeq[3] ||(lpImcP->bSeq[2] == TEXT('?'))) { if (lpImcP->bSeq[2] == TEXT('?')){ //add 626
lpImcP->bSeq[2] = TEXT('4'); lpImcP->bSeq[3] = TEXT('0'); } wCode = AsciiToGB(lpImcP); return wCode; } else { return ((WORD)NULL); } }
/**********************************************************************/ /* XGBSpcEng() */ /* Description: */ /* Conv GBcode for Space */ /**********************************************************************/ WORD PASCAL XGBSpcEng(LPPRIVCONTEXT lpImcP) { WORD wCode;
lpImcP->bSeq[2] = TEXT('4'); lpImcP->bSeq[3] = TEXT('0'); wCode = AsciiToGB(lpImcP);
return wCode; }
/**********************************************************************/ /* GBEngine() */ /* Description: */ /* Conv GBcode */ /**********************************************************************/ WORD PASCAL GBEngine(LPPRIVCONTEXT lpImcP) { WORD wCode;
if (lpImcP->bSeq[3] ||(lpImcP->bSeq[2] == TEXT('?'))) {
if (lpImcP->bSeq[0] >=TEXT('0') && lpImcP->bSeq[0] <=TEXT('9')) { //Area mode
if (lpImcP->bSeq[2] == TEXT('?')){
lpImcP->bSeq[2] = TEXT('0'); lpImcP->bSeq[3] = TEXT('1'); } return (AsciiToArea(lpImcP)); } else if (lpImcP->bSeq[0] >=TEXT('a') && lpImcP->bSeq[0] <=TEXT('f')) { //GB mode
if (lpImcP->bSeq[2] == TEXT('?')){ lpImcP->bSeq[2] = TEXT('a'); lpImcP->bSeq[3] = TEXT('1'); } wCode = AsciiToGB(lpImcP); return wCode; } else { return ((WORD)NULL); } } else return ((WORD)NULL);
}
/**********************************************************************/ /* GBSpcEng() */ /* Description: */ /* Conv GBcode for Space */ /**********************************************************************/ WORD PASCAL GBSpcEng(LPPRIVCONTEXT lpImcP) { if (lpImcP->bSeq[0] >=TEXT('0') && lpImcP->bSeq[0] <=TEXT('9')) { //Area mode
lpImcP->bSeq[2] = TEXT('0'); lpImcP->bSeq[3] = TEXT('1'); return (AsciiToArea(lpImcP)); } else if (lpImcP->bSeq[0] >=TEXT('a') && lpImcP->bSeq[0] <=TEXT('f')) { //GB mode
lpImcP->bSeq[2] = TEXT('a'); lpImcP->bSeq[3] = TEXT('1'); return (AsciiToGB(lpImcP)); } else { return ((WORD)NULL); } }
/**********************************************************************/ /* AsciiToGB */ /* Description: */ /**********************************************************************/ WORD PASCAL AsciiToGB(LPPRIVCONTEXT lpImcP) { WORD GBCode;
GBCode = (CharToHex(lpImcP->bSeq[2]) << 4) + CharToHex(lpImcP->bSeq[3]); GBCode = GBCode * 256; GBCode = (CharToHex(lpImcP->bSeq[0]) << 4) + CharToHex(lpImcP->bSeq[1]) + GBCode;
return (GBCode); }
/**********************************************************************/ /* AsciiToArea */ /* Description: */ /**********************************************************************/ WORD PASCAL AsciiToArea(LPPRIVCONTEXT lpImcP) { WORD AreaCode; AreaCode = (CharToHex(lpImcP->bSeq[2]) * 10) + CharToHex(lpImcP->bSeq[3]) + 0xa0; AreaCode = AreaCode * 256; AreaCode = (CharToHex(lpImcP->bSeq[0]) * 10) + CharToHex(lpImcP->bSeq[1]) + AreaCode + 0xa0; return (AreaCode); }
WORD PASCAL CharToHex( TCHAR cChar) { if (cChar >= TEXT('0') && cChar <= TEXT('9')) return((WORD)(cChar - TEXT('0'))); else if (cChar >= TEXT('a') && cChar <= TEXT('f')) return((WORD)(cChar-TEXT('a')+ 0x0a)); else return ((WORD)NULL); }
/**********************************************************************/ /* Engine() */ /* Description: */ /* search MB and fill lpCompStr and lpCandList */ /**********************************************************************/ int PASCAL Engine( LPCOMPOSITIONSTRING lpCompStr, LPCANDIDATELIST lpCandList, LPPRIVCONTEXT lpImcP, LPINPUTCONTEXT lpIMC, WORD wCharCode) { if(lpCompStr->dwCursorPos < 4 && (lpImcP->bSeq[2] != TEXT('?')) && (wCharCode != TEXT(' '))) { return (ENGINE_COMP); } else if((lpCompStr->dwCursorPos==4) ||(lpImcP->bSeq[2] == TEXT('?')) ||((wCharCode == TEXT(' ')) && (lpCompStr->dwCursorPos == 2))) {
if (!lpCompStr) { MessageBeep((UINT)-1); return -1; }
if (!lpImcP) { MessageBeep((UINT)-1); return -1; }
#if defined(COMBO_IME)
if(sImeL.dwRegImeIndex == INDEX_GB) {
// GB
DWORD i; WORD wCode; TCHAR ResaultStr[3];
if((lpImcP->bSeq[2] == TEXT('?'))) { wCode = GBEngine(lpImcP); wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8); for (i = 0; i < IME_MAXCAND; i++, wCode++) { AddCodeIntoCand(lpCandList, wCode); } return (ENGINE_COMP); } else if(wCharCode == TEXT(' ')) { wCode = GBSpcEng(lpImcP); lpImcP->bSeq[2] = 0; lpImcP->bSeq[3] = 0; wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8); for (i = 0; i < IME_MAXCAND; i++, wCode++) { AddCodeIntoCand(lpCandList, wCode); } return (ENGINE_COMP); } else { InitCompStr(lpCompStr);
// the result string = the selected candidate;
wCode = GBEngine(lpImcP); #ifdef UNICODE
MultiByteToWideChar(NATIVE_ANSI_CP, 0, (LPCSTR)&wCode, 2, ResaultStr, sizeof(ResaultStr)/sizeof(TCHAR)); ResaultStr[1] = TEXT('\0'); #else
ResaultStr[0] = LOBYTE(wCode); ResaultStr[1] = HIBYTE(wCode); ResaultStr[2] = 0x00; #endif
lstrcpy((LPTSTR)((LPBYTE)lpCompStr + lpCompStr->dwResultStrOffset),ResaultStr);
// calculate result string length
lpCompStr->dwResultStrLen = lstrlen(ResaultStr);
return (ENGINE_RESAULT); }
}else if(sImeL.dwRegImeIndex == INDEX_GBK) { // XGB
DWORD i; WORD wCode; TCHAR ResaultStr[3];
if((lpImcP->bSeq[2] == TEXT('?'))) { wCode = XGBEngine(lpImcP); wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
for (i = 0; i < (0x7e-0x40+1); i++, wCode++) { XGBAddCodeIntoCand(lpCandList, wCode); } wCode ++; for (i = 0; i < (0xfe-0x80+1); i++, wCode++) { XGBAddCodeIntoCand(lpCandList, wCode); } return (ENGINE_COMP); } else if(wCharCode == TEXT(' ')) { wCode = XGBSpcEng(lpImcP); lpImcP->bSeq[2] = 0; lpImcP->bSeq[3] = 0;
wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
for (i = 0; i < (0x7e-0x40+1); i++, wCode++) { XGBAddCodeIntoCand(lpCandList, wCode); } wCode ++; for (i = 0; i < (0xfe-0x80+1); i++, wCode++) { XGBAddCodeIntoCand(lpCandList, wCode); } return (ENGINE_COMP); } else { InitCompStr(lpCompStr);
// the result string = the selected candidate;
wCode = XGBEngine(lpImcP); #ifdef UNICODE
MultiByteToWideChar(NATIVE_ANSI_CP, 0, (LPCSTR)&wCode, 2, ResaultStr, sizeof(ResaultStr)/sizeof(TCHAR)); ResaultStr[1] = TEXT('\0'); #else
ResaultStr[0] = LOBYTE(wCode); ResaultStr[1] = HIBYTE(wCode); ResaultStr[2] = 0x00; #endif
lstrcpy((LPTSTR)((LPBYTE)lpCompStr + lpCompStr->dwResultStrOffset),ResaultStr);
// calculate result string length
lpCompStr->dwResultStrLen = lstrlen(ResaultStr);
return (ENGINE_RESAULT); } }else if(sImeL.dwRegImeIndex == INDEX_UNICODE) { // UNICODE
DWORD i; WORD wCode, xCode; TCHAR ResaultStr[3];
memset(ResaultStr, 0, sizeof(ResaultStr));
if((lpImcP->bSeq[2] == TEXT('?') || wCharCode == TEXT(' '))) { lpImcP->bSeq[2] = TEXT('0'); lpImcP->bSeq[3] = TEXT('0'); lpImcP->bSeq[4] = TEXT('\0');
wCode = UnicodeEngine(lpImcP);
wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
lpCandList->dwCount = 0; for (i = 0; i < IME_UNICODE_MAXCAND; i++, wCode++) { #ifdef UNICODE
// add this string into candidate list
*(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[ lpCandList->dwCount]) = wCode; #else
WideCharToMultiByte(NATIVE_ANSI_CP, NULL, &wCode, 1, &xCode, 2, NULL, NULL); // add this string into candidate list
*(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[ lpCandList->dwCount]) = xCode; #endif
// null terminator
*(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[ lpCandList->dwCount] + sizeof(WORD)) = TEXT('\0');
lpCandList->dwOffset[lpCandList->dwCount + 1] = lpCandList->dwOffset[lpCandList->dwCount] + sizeof(WORD) + sizeof(TCHAR); lpCandList->dwCount++;
} return (ENGINE_COMP); } else { InitCompStr(lpCompStr);
// the result string = the selected candidate;
wCode = UnicodeEngine(lpImcP); { WCHAR UniStr[2];
UniStr[0] = HIBYTE(wCode) | (LOBYTE(wCode) << 8); UniStr[1] = 0; lstrcpy((LPTSTR)((LPBYTE)lpCompStr + lpCompStr->dwResultStrOffset),UniStr);
// calculate result string length
lpCompStr->dwResultStrLen = lstrlen(UniStr); } return (ENGINE_RESAULT); } } #else //COMBO_IME
#ifdef GB
{
// GB
DWORD i; WORD wCode; TCHAR ResaultStr[3];
if((lpImcP->bSeq[2] == TEXT('?'))) { wCode = GBEngine(lpImcP); wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8); for (i = 0; i < IME_MAXCAND; i++, wCode++) { AddCodeIntoCand(lpCandList, wCode); } return (ENGINE_COMP); } else if(wCharCode == TEXT(' ')) { wCode = GBSpcEng(lpImcP); lpImcP->bSeq[2] = 0; lpImcP->bSeq[3] = 0; wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8); for (i = 0; i < IME_MAXCAND; i++, wCode++) { AddCodeIntoCand(lpCandList, wCode); } return (ENGINE_COMP); } else { InitCompStr(lpCompStr);
// the result string = the selected candidate;
wCode = GBEngine(lpImcP); #ifdef UNICODE
// change CP_ACP to 936, so that it can work under Multilingul Env.
MultiByteToWideChar(NATIVE_ANSI_CP, NULL, &wCode, 2, ResaultStr, sizeof(ResaultStr)/sizeof(TCHAR)); ResaultStr[1] = TEXT('\0'); #else
ResaultStr[0] = LOBYTE(wCode); ResaultStr[1] = HIBYTE(wCode); ResaultStr[2] = 0x00; #endif
lstrcpy((LPTSTR)lpCompStr + lpCompStr->dwResultStrOffset,ResaultStr);
// calculate result string length
lpCompStr->dwResultStrLen = lstrlen(ResaultStr);
return (ENGINE_RESAULT); }
} #else
{ // XGB
DWORD i; WORD wCode; TCHAR ResaultStr[3];
if((lpImcP->bSeq[2] == TEXT('?'))) { wCode = XGBEngine(lpImcP); wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
for (i = 0; i < (0x7e-0x40+1); i++, wCode++) { XGBAddCodeIntoCand(lpCandList, wCode); } wCode ++; for (i = 0; i < (0xfe-0x80+1); i++, wCode++) { XGBAddCodeIntoCand(lpCandList, wCode); } return (ENGINE_COMP); } else if(wCharCode == TEXT(' ')) { wCode = XGBSpcEng(lpImcP); lpImcP->bSeq[2] = 0; lpImcP->bSeq[3] = 0;
wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
for (i = 0; i < (0x7e-0x40+1); i++, wCode++) { XGBAddCodeIntoCand(lpCandList, wCode); } wCode ++; for (i = 0; i < (0xfe-0x80+1); i++, wCode++) { XGBAddCodeIntoCand(lpCandList, wCode); } return (ENGINE_COMP); } else { InitCompStr(lpCompStr);
// the result string = the selected candidate;
wCode = XGBEngine(lpImcP); #ifdef UNICODE
// change CP_ACP to 936, so that it can work under Multilingul Env.
MultiByteToWideChar(NATIVE_ANSI_CP, NULL, &wCode, 2, ResaultStr, sizeof(ResaultStr)/sizeof(TCHAR)); ResaultStr[1] = TEXT('\0'); #else
ResaultStr[0] = LOBYTE(wCode); ResaultStr[1] = HIBYTE(wCode); ResaultStr[2] = 0x00; #endif
lstrcpy((LPTSTR)lpCompStr + lpCompStr->dwResultStrOffset,ResaultStr);
// calculate result string length
lpCompStr->dwResultStrLen = lstrlen(ResaultStr);
return (ENGINE_RESAULT); } } #endif //GB
#endif //COMBO_IME
} MessageBeep((UINT)-1); return (ENGINE_COMP); }
/**********************************************************************/ /* AddCodeIntoCand() */ /**********************************************************************/ void PASCAL AddCodeIntoCand( LPCANDIDATELIST lpCandList, WORD wCode) { WORD wInCode;
if (lpCandList->dwCount >= IME_MAXCAND) { return; }
wInCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8); #ifdef UNICODE
{ TCHAR wUnicode; // change CP_ACP to 936, so that it can work under Multilingul Env.
MultiByteToWideChar(NATIVE_ANSI_CP, 0, (LPCSTR) &wInCode, 2, &wUnicode, 1); *(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[ lpCandList->dwCount]) = wUnicode; } #else
// add GB string into candidate list
*(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[ lpCandList->dwCount]) = wInCode; #endif
// null terminator
*(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[ lpCandList->dwCount] + sizeof(WORD)) = TEXT('\0');
lpCandList->dwOffset[lpCandList->dwCount + 1] = lpCandList->dwOffset[lpCandList->dwCount] + sizeof(WORD) + sizeof(TCHAR); lpCandList->dwCount++; return; }
#if defined(COMBO_IME)
/**********************************************************************/ /* UnicodeAddCodeIntoCand() */ /**********************************************************************/ void PASCAL UnicodeAddCodeIntoCand( LPCANDIDATELIST lpCandList, WORD wCode) { if (lpCandList->dwCount >= IME_UNICODE_MAXCAND) { return; } // add this string into candidate list
*(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[ lpCandList->dwCount]) = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
// null terminator
*(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[ lpCandList->dwCount] + sizeof(WORD)) = TEXT('\0');
lpCandList->dwOffset[lpCandList->dwCount + 1] = lpCandList->dwOffset[lpCandList->dwCount] + sizeof(WORD) + sizeof(TCHAR); lpCandList->dwCount++;
return; } #endif //COMBO_IME
/**********************************************************************/ /* XGBAddCodeIntoCand() */ /**********************************************************************/ void PASCAL XGBAddCodeIntoCand( LPCANDIDATELIST lpCandList, WORD wCode) { WORD wInCode;
if (lpCandList->dwCount >= IME_XGB_MAXCAND) { return; }
wInCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8); #ifdef UNICODE
{ TCHAR wUnicode;
// change CP_ACP to 936, so that it can work under Multilingul Env.
MultiByteToWideChar(NATIVE_ANSI_CP, 0, (LPCSTR) &wInCode, 2, &wUnicode, 1); *(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[ lpCandList->dwCount]) = wUnicode; } #else
// add GB string into candidate list
*(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[ lpCandList->dwCount]) = wInCode; #endif
*(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[ lpCandList->dwCount] + sizeof(WORD)) = TEXT('\0');
lpCandList->dwOffset[lpCandList->dwCount + 1] = lpCandList->dwOffset[lpCandList->dwCount] + sizeof(WORD) + sizeof(TCHAR); lpCandList->dwCount++;
return; }
/**********************************************************************/ /* CompEscapeKey() */ /**********************************************************************/ void PASCAL CompEscapeKey( LPINPUTCONTEXT lpIMC, LPCOMPOSITIONSTRING lpCompStr, LPGUIDELINE lpGuideLine, LPPRIVCONTEXT lpImcP) { if (!lpGuideLine) { MessageBeep((UINT)-1); } else if (lpGuideLine->dwLevel != GL_LEVEL_NOGUIDELINE) { lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE; lpGuideLine->dwIndex = GL_ID_UNKNOWN; lpGuideLine->dwStrLen = 0;
lpImcP->fdwImeMsg |= MSG_GUIDELINE; }
if (lpImcP->iImeState != CST_CHOOSE) { if (lpImcP->fdwImeMsg & MSG_ALREADY_START) { lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_END_COMPOSITION) & ~(MSG_START_COMPOSITION); } }
lpImcP->iImeState = CST_INIT; *(LPDWORD)lpImcP->bSeq = 0;
if (lpCompStr) { InitCompStr(lpCompStr); lpImcP->fdwImeMsg |= MSG_COMPOSITION; lpImcP->dwCompChar = VK_ESCAPE; lpImcP->fdwGcsFlag |= (GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS| GCS_DELTASTART); }
return; }
/**********************************************************************/ /* CompBackSpaceKey() */ /**********************************************************************/ void PASCAL CompBackSpaceKey( LPINPUTCONTEXT lpIMC, LPCOMPOSITIONSTRING lpCompStr, LPPRIVCONTEXT lpImcP) {
if (lpCompStr->dwCursorPos < sizeof(BYTE)) { lpCompStr->dwCursorPos = sizeof(BYTE); }
lpImcP->bSeq[3] = 0;
// go back a compsoition char
lpCompStr->dwCursorPos -= sizeof(BYTE);
// clean the sequence code
lpImcP->bSeq[lpCompStr->dwCursorPos] = 0;
lpImcP->fdwImeMsg |= MSG_COMPOSITION; lpImcP->dwCompChar = TEXT('\b'); lpImcP->fdwGcsFlag |= (GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS| GCS_DELTASTART);
if (!lpCompStr->dwCursorPos) { if (lpImcP->fdwImeMsg & (MSG_ALREADY_OPEN)) { ClearCand(lpIMC); lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) & ~(MSG_OPEN_CANDIDATE); }
if(lpImcP->iImeState != CST_INIT) { lpImcP->iImeState = CST_INIT; lpCompStr->dwCompReadStrLen = lpCompStr->dwCompStrLen = lpCompStr->dwDeltaStart = lpCompStr->dwCursorPos; Finalize(lpIMC, lpCompStr, lpImcP, TEXT('\b')); return; }
if (lpImcP->fdwImeMsg & MSG_ALREADY_START) { InitCompStr(lpCompStr); lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_END_COMPOSITION) & ~(MSG_START_COMPOSITION); return; } }
// reading string is composition string for some simple IMEs
// delta start is the same as cursor position for backspace
lpCompStr->dwCompReadStrLen = lpCompStr->dwCompStrLen = lpCompStr->dwDeltaStart = lpCompStr->dwCursorPos;
Finalize(lpIMC, lpCompStr, lpImcP, TEXT('\b'));
return; }
/**********************************************************************/ /* CompStrInfo() */ /**********************************************************************/ void PASCAL CompStrInfo( LPCOMPOSITIONSTRING lpCompStr, LPPRIVCONTEXT lpImcP, LPGUIDELINE lpGuideLine, WORD wCharCode) { register DWORD dwCursorPos;
//
dwCursorPos = lpCompStr->dwCursorPos;
// dwCrusorPos limit
if (dwCursorPos >= lpImeL->nMaxKey) { // exceed the max input key limitation
lpGuideLine->dwLevel = GL_LEVEL_ERROR; lpGuideLine->dwIndex = GL_ID_TOOMANYSTROKE;
lpImcP->fdwImeMsg |= MSG_GUIDELINE; return; }
// set MSG_START_COMPOSITION
if (!(lpImcP->fdwImeMsg & MSG_ALREADY_START)) { lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_START_COMPOSITION) & ~(MSG_END_COMPOSITION); }
if (lpImcP->iImeState == CST_INIT) { // clean the 4 bytes in one time
*(LPDWORD)lpImcP->bSeq = 0; }
lpImcP->bSeq[dwCursorPos] = (BYTE)wCharCode;
// composition/reading string - UsedCode(Full Shape)
lpImcP->dwCompChar = (DWORD)wCharCode;
// set reading string for lpCompStr
*((LPUNAWORD)((LPBYTE)lpCompStr + lpCompStr->dwCompReadStrOffset + dwCursorPos*sizeof(TCHAR))) = (BYTE)lpImcP->dwCompChar;
*((LPUNAWORD)((LPBYTE)lpCompStr + lpCompStr->dwCompReadAttrOffset + dwCursorPos*sizeof(TCHAR))) = ((ATTR_TARGET_CONVERTED << 8)|ATTR_TARGET_CONVERTED);
// set reading string lenght for lpCompStr
if (lpCompStr->dwCompReadStrLen <= dwCursorPos) { lpCompStr->dwCompReadStrLen += sizeof(BYTE); }
// composition string is reading string for some simple IMEs
lpCompStr->dwCompStrLen = lpCompStr->dwCompReadStrLen;
// composition/reading attribute length is equal to reading string length
lpCompStr->dwCompReadAttrLen = lpCompStr->dwCompReadStrLen; lpCompStr->dwCompAttrLen = lpCompStr->dwCompStrLen;
// delta start from previous cursor position
lpCompStr->dwDeltaStart = lpCompStr->dwCursorPos;
// set new cursor with next to the composition string
lpCompStr->dwCursorPos = lpCompStr->dwCompStrLen;
// set lpImcp->iImeState
lpImcP->iImeState = CST_INPUT;
// tell app, there is a composition char generated
lpImcP->fdwImeMsg |= MSG_COMPOSITION;
// set lpImeP->fdwGcsFlag
lpImcP->fdwGcsFlag |= GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS|GCS_DELTASTART;
return; }
/**********************************************************************/ /* Finalize() */ /* Return vlaue */ /* Engine Flag */ /* Description: */ /* Call Engine finalize Chinese word(s) by searching table */ /* (Set lpCompStr and lpCandList) */ /* Set lpImeP(iImeState, fdwImeMsg, fdwGcsFlag) */ /**********************************************************************/ UINT PASCAL Finalize( LPINPUTCONTEXT lpIMC, LPCOMPOSITIONSTRING lpCompStr, LPPRIVCONTEXT lpImcP, WORD wCharCode) { LPCANDIDATEINFO lpCandInfo; LPCANDIDATELIST lpCandList; UINT fEngine;
if (!lpIMC->hCandInfo) { return (0); }
// get lpCandInfo
lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
if (!lpCandInfo) { return (0); }
// get lpCandList and init dwCount & dwSelection
lpCandList = (LPCANDIDATELIST) ((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]); lpCandList->dwCount = 0; lpCandList->dwSelection = 0;
// search the IME tables
fEngine =Engine(lpCompStr, lpCandList, lpImcP, lpIMC, wCharCode);
if (fEngine == ENGINE_COMP) { lpCandInfo->dwCount = 1;
if (((lpCompStr->dwCursorPos < 3) && (wCharCode != TEXT(' '))) || ((lpCompStr->dwCursorPos == 3) && (wCharCode != TEXT(' ')) && (wCharCode != TEXT('?')))) { lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) & ~(MSG_OPEN_CANDIDATE); ImmUnlockIMCC(lpIMC->hCandInfo); return (fEngine); }
if(lpCandList->dwCount != 0x0000) { // open composition candidate UI window for the string(s)
if ((lpImcP->fdwImeMsg & (MSG_ALREADY_OPEN|MSG_CLOSE_CANDIDATE)) == (MSG_ALREADY_OPEN|MSG_CLOSE_CANDIDATE)) { lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CHANGE_CANDIDATE) & ~(MSG_CLOSE_CANDIDATE); } else if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) { lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE; } else { lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_OPEN_CANDIDATE) & ~(MSG_CLOSE_CANDIDATE); }
}
if (lpImcP->fdwImeMsg & MSG_ALREADY_START) { lpImcP->fdwImeMsg |= MSG_COMPOSITION; } } else if (fEngine == ENGINE_ASCII) { } else if (fEngine == ENGINE_RESAULT) {
// Set lpImep! and tell application, there is a reslut string
lpImcP->fdwImeMsg |= MSG_COMPOSITION; lpImcP->dwCompChar = (DWORD)0; lpImcP->fdwGcsFlag |= GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS| GCS_DELTASTART|GCS_RESULTREAD|GCS_RESULT;
if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) { lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) & ~(MSG_OPEN_CANDIDATE); } // clear candidate now
lpCandList->dwCount = 0; // set iImeState with CST_INIT
lpImcP->iImeState = CST_INIT; *(LPDWORD)lpImcP->bSeq = 0; #ifdef CROSSREF
CrossReverseConv(lpIMC, lpCompStr, lpImcP, lpCandList); #endif
}
ImmUnlockIMCC(lpIMC->hCandInfo);
return fEngine; }
/**********************************************************************/ /* CompWord() */ /**********************************************************************/ void PASCAL CompWord( // compose the Chinese word(s) according to
// input key
WORD wCharCode, LPINPUTCONTEXT lpIMC, LPCOMPOSITIONSTRING lpCompStr, LPPRIVCONTEXT lpImcP, LPGUIDELINE lpGuideLine) {
// lpComStr=NULL?
if (!lpCompStr) { MessageBeep((UINT)-1); return; }
// escape key
if (wCharCode == VK_ESCAPE) { // not good to use VK as char, but...
CompEscapeKey(lpIMC, lpCompStr, lpGuideLine, lpImcP); return; }
// GuideLine
if (!lpGuideLine) { } else if (lpGuideLine->dwLevel == GL_LEVEL_NOGUIDELINE) { lpGuideLine->dwStrLen = 0; } else { // previous input error cause us trancate some chars
if (lpGuideLine->dwLevel == GL_LEVEL_ERROR) { lpImcP->bSeq[lpCompStr->dwCursorPos / 2] = 0; lpCompStr->dwCompReadStrLen = lpCompStr->dwCompStrLen = lpCompStr->dwCursorPos; lpCompStr->dwCompReadAttrLen = lpCompStr->dwCompReadStrLen; lpCompStr->dwCompAttrLen = lpCompStr->dwCompStrLen; } lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE; lpGuideLine->dwIndex = GL_ID_UNKNOWN; lpGuideLine->dwStrLen = 0;
lpImcP->fdwImeMsg |= MSG_GUIDELINE; }
// backspace key
if (wCharCode == TEXT('\b')) { CompBackSpaceKey(lpIMC, lpCompStr, lpImcP); return; }
if(wCharCode == TEXT(' ')) { } else { // build up composition string info
CompStrInfo(lpCompStr, lpImcP, lpGuideLine, wCharCode); }
Finalize(lpIMC, lpCompStr, lpImcP, wCharCode); // compsition
return; }
|