/*++ Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved Module Name: compose.c ++*/ #include #include #include 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; }