395 lines
12 KiB
C
395 lines
12 KiB
C
/*++
|
|
|
|
Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
|
|
|
|
Module Name:
|
|
|
|
chcand.c
|
|
|
|
++*/
|
|
|
|
#include <windows.h>
|
|
#include <immdev.h>
|
|
#include <imedefs.h>
|
|
|
|
#if defined(CROSSREF)
|
|
//*******************************************************************
|
|
// The parameters are inherited from SelectOneCand
|
|
// CrossReverseConv()
|
|
//*******************************************************************
|
|
void CrossReverseConv(
|
|
LPINPUTCONTEXT lpIMC,
|
|
LPCOMPOSITIONSTRING lpCompStr,
|
|
LPPRIVCONTEXT lpImcP,
|
|
LPCANDIDATELIST lpCandList)
|
|
{
|
|
LPGUIDELINE lpGuideLine;
|
|
|
|
if (!sImeG.hRevKL) {
|
|
return;
|
|
}
|
|
|
|
|
|
lpGuideLine = ImmLockIMCC(lpIMC->hGuideLine);
|
|
|
|
if (!lpGuideLine) {
|
|
return;
|
|
}
|
|
|
|
if (lpCompStr->dwResultStrLen != sizeof(WORD)/sizeof(TCHAR)) {
|
|
// we only can reverse convert one DBCS character for now
|
|
lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE;
|
|
lpGuideLine->dwIndex = GL_ID_UNKNOWN;
|
|
} else {
|
|
TCHAR szStrBuf[4];
|
|
UINT uSize;
|
|
LPCANDIDATELIST lpRevCandList;
|
|
|
|
if(lpImcP->hRevCandList == (HIMCC)NULL){
|
|
// we alloc memory in lpImcP->hRevCandList,
|
|
// for reverse convert result codes; When finish reconvert,
|
|
// should read out this info.
|
|
REALLOC:
|
|
lpImcP->hRevCandList = (HIMCC)GlobalAlloc(GHND,sizeof(CANDIDATELIST)+1*sizeof(DWORD)+(MAXCODE+1)*sizeof(TCHAR));
|
|
if (lpImcP->hRevCandList == (HIMCC)NULL) {
|
|
return ;
|
|
}
|
|
lpRevCandList = (LPCANDIDATELIST)GlobalLock((HGLOBAL)lpImcP->hRevCandList);
|
|
if (lpRevCandList == NULL) {
|
|
return ;
|
|
}
|
|
}else{
|
|
lpRevCandList = (LPCANDIDATELIST)GlobalLock((HGLOBAL)lpImcP->hRevCandList);
|
|
if (lpRevCandList == NULL) {
|
|
goto REALLOC;
|
|
}
|
|
}
|
|
|
|
*(LPUNAWORD)szStrBuf = *(LPUNAWORD)((LPBYTE)lpCompStr +
|
|
lpCompStr->dwResultStrOffset);
|
|
szStrBuf[1] = TEXT('\0');
|
|
|
|
memset(lpRevCandList, 0, sizeof(CANDIDATELIST)+1*sizeof(DWORD)+(MAXCODE+1)*sizeof(TCHAR));
|
|
lpRevCandList->dwSize = sizeof(CANDIDATELIST)+1*sizeof(DWORD)+(MAXCODE+1)*sizeof(TCHAR);
|
|
|
|
uSize = ImmGetConversionList(sImeG.hRevKL, (HIMC)NULL, szStrBuf,
|
|
(LPCANDIDATELIST)lpRevCandList,
|
|
lpRevCandList->dwSize, GCL_REVERSECONVERSION);
|
|
|
|
GlobalUnlock((HGLOBAL)lpImcP->hRevCandList);
|
|
|
|
|
|
if (uSize) {
|
|
if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
|
|
lpImcP->fdwImeMsg &= ~(MSG_END_COMPOSITION|
|
|
MSG_START_COMPOSITION);
|
|
} else {
|
|
lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg|
|
|
MSG_START_COMPOSITION) & ~(MSG_END_COMPOSITION);
|
|
}
|
|
} else {
|
|
GlobalFree((HGLOBAL)lpImcP->hRevCandList);
|
|
}
|
|
}
|
|
|
|
ImmUnlockIMCC(lpIMC->hGuideLine);
|
|
}
|
|
#endif //CROSSREF
|
|
|
|
/**********************************************************************/
|
|
/* SelectOneCand() */
|
|
/**********************************************************************/
|
|
void PASCAL SelectOneCand(
|
|
LPINPUTCONTEXT lpIMC,
|
|
LPCOMPOSITIONSTRING lpCompStr,
|
|
LPPRIVCONTEXT lpImcP,
|
|
LPCANDIDATELIST lpCandList)
|
|
{
|
|
DWORD dwCompStrLen;
|
|
DWORD dwReadStrLen;
|
|
|
|
if (!lpCompStr) {
|
|
MessageBeep((UINT)-1);
|
|
return;
|
|
}
|
|
|
|
if (!lpImcP) {
|
|
MessageBeep((UINT)-1);
|
|
return;
|
|
}
|
|
|
|
// backup the dwCompStrLen, this value decide whether
|
|
// we go for phrase prediction
|
|
dwCompStrLen = lpCompStr->dwCompStrLen;
|
|
dwReadStrLen = lpCompStr->dwCompReadStrLen;
|
|
|
|
InitCompStr(lpCompStr);
|
|
|
|
// calculate result string length
|
|
lpCompStr->dwResultStrLen = lstrlen(
|
|
(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
|
|
lpCandList->dwSelection]));
|
|
|
|
// the result string = the selected candidate;
|
|
lstrcpy((LPTSTR)((LPBYTE)lpCompStr + lpCompStr->dwResultStrOffset),
|
|
(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
|
|
lpCandList->dwSelection]));
|
|
|
|
// 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);
|
|
}
|
|
|
|
// no candidate now, the right candidate string already be finalized
|
|
lpCandList->dwCount = 0;
|
|
|
|
lpImcP->iImeState = CST_INIT;
|
|
|
|
|
|
// init Engine private data
|
|
*(LPDWORD)lpImcP->bSeq = 0;
|
|
|
|
#ifdef CROSSREF
|
|
CrossReverseConv(lpIMC, lpCompStr, lpImcP, lpCandList);
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* CandEscapeKey() */
|
|
/**********************************************************************/
|
|
void PASCAL CandEscapeKey(
|
|
LPINPUTCONTEXT lpIMC,
|
|
LPPRIVCONTEXT lpImcP)
|
|
{
|
|
LPCOMPOSITIONSTRING lpCompStr;
|
|
LPGUIDELINE lpGuideLine;
|
|
|
|
// clean all candidate information
|
|
if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
|
|
ClearCand(lpIMC);
|
|
lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
|
|
~(MSG_OPEN_CANDIDATE);
|
|
}
|
|
|
|
|
|
// if it start composition, we need to clean composition
|
|
if (!(lpImcP->fdwImeMsg & MSG_ALREADY_START)) {
|
|
return;
|
|
}
|
|
|
|
lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
|
|
if (!lpCompStr) {
|
|
return;
|
|
}
|
|
|
|
lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
|
|
if (!lpGuideLine) {
|
|
return;
|
|
}
|
|
|
|
CompEscapeKey(lpIMC, lpCompStr, lpGuideLine, lpImcP);
|
|
|
|
ImmUnlockIMCC(lpIMC->hGuideLine);
|
|
ImmUnlockIMCC(lpIMC->hCompStr);
|
|
|
|
return;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* ChooseCand() */
|
|
/**********************************************************************/
|
|
void PASCAL ChooseCand( // choose one of candidate strings by
|
|
// input char
|
|
WORD wCharCode,
|
|
LPINPUTCONTEXT lpIMC,
|
|
LPCANDIDATEINFO lpCandInfo,
|
|
LPPRIVCONTEXT lpImcP)
|
|
{
|
|
LPCANDIDATELIST lpCandList;
|
|
LPCOMPOSITIONSTRING lpCompStr;
|
|
|
|
if (wCharCode == VK_ESCAPE) { // escape key
|
|
CandEscapeKey(lpIMC, lpImcP);
|
|
return;
|
|
}
|
|
|
|
if (!lpCandInfo) {
|
|
MessageBeep((UINT)-1);
|
|
return;
|
|
}
|
|
|
|
lpCandList = (LPCANDIDATELIST)
|
|
((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]);
|
|
|
|
if (wCharCode == TEXT(' ')) { // circle selection
|
|
if ((lpCandList->dwSelection += lpCandList->dwPageSize) >=
|
|
lpCandList->dwCount) {
|
|
// no more candidates, restart it!
|
|
lpCandList->dwSelection = 0;
|
|
MessageBeep((UINT)-1);
|
|
}
|
|
// inform UI, dwSelectedCand is changed
|
|
lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
|
|
return;
|
|
}
|
|
|
|
if (wCharCode == TEXT('=')) { // next selection
|
|
#if defined(COMBO_IME)
|
|
if(sImeL.dwRegImeIndex == INDEX_GB){
|
|
if (lpCandList->dwSelection >= ((IME_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
|
|
MessageBeep((UINT)-1);
|
|
return;
|
|
}
|
|
}else if(sImeL.dwRegImeIndex == INDEX_GBK){
|
|
if (lpCandList->dwSelection >= ((IME_XGB_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
|
|
MessageBeep((UINT)-1);
|
|
return;
|
|
}
|
|
}else if(sImeL.dwRegImeIndex == INDEX_UNICODE){
|
|
if (lpCandList->dwSelection >= ((IME_UNICODE_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
|
|
MessageBeep((UINT)-1);
|
|
return;
|
|
}
|
|
}
|
|
#else //COMBO_IME
|
|
#if defined(GB)
|
|
if (lpCandList->dwSelection >= ((IME_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
|
|
#else
|
|
if (lpCandList->dwSelection >= ((IME_XGB_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
|
|
#endif
|
|
MessageBeep((UINT)-1);
|
|
return;
|
|
}
|
|
#endif //COMBO_IME
|
|
lpCandList->dwSelection += lpCandList->dwPageSize;
|
|
// inform UI, dwSelectedCand is changed
|
|
lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
|
|
return;
|
|
}
|
|
|
|
if (wCharCode == TEXT('-')) { // previous selection
|
|
if (lpCandList->dwSelection < lpCandList->dwPageSize) {
|
|
MessageBeep((UINT)-1);
|
|
return;
|
|
}
|
|
lpCandList->dwSelection -= lpCandList->dwPageSize;
|
|
// inform UI, dwSelectedCand is changed
|
|
lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
|
|
return;
|
|
}
|
|
|
|
if (wCharCode == 0x23) { // previous selection
|
|
#if defined(COMBO_IME)
|
|
if(sImeL.dwRegImeIndex == INDEX_GB){
|
|
if (lpCandList->dwSelection >= ((IME_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
|
|
MessageBeep((UINT)-1);
|
|
return;
|
|
}else{
|
|
lpCandList->dwSelection = ((IME_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize;
|
|
}
|
|
}else if(sImeL.dwRegImeIndex == INDEX_GBK){
|
|
if (lpCandList->dwSelection >= ((IME_XGB_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
|
|
MessageBeep((UINT)-1);
|
|
return;
|
|
}else{
|
|
lpCandList->dwSelection = ((IME_XGB_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize;
|
|
}
|
|
}else if(sImeL.dwRegImeIndex == INDEX_UNICODE){
|
|
if (lpCandList->dwSelection >= ((IME_UNICODE_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
|
|
MessageBeep((UINT)-1);
|
|
return;
|
|
}else{
|
|
lpCandList->dwSelection = ((IME_UNICODE_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize;
|
|
}
|
|
}
|
|
#else //COMBO_IME
|
|
#if defined(GB)
|
|
if (lpCandList->dwSelection >= ((IME_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize) {
|
|
#else
|
|
if (lpCandList->dwSelection >= ((IME_XGB_MAXCAND-1)/CANDPERPAGE - 1)*lpCandList->dwPageSize) {
|
|
#endif
|
|
MessageBeep((UINT)-1);
|
|
return;
|
|
}
|
|
#if defined(GB)
|
|
lpCandList->dwSelection = ((IME_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize;
|
|
#else
|
|
lpCandList->dwSelection = ((IME_XGB_MAXCAND-1)/CANDPERPAGE)*lpCandList->dwPageSize;
|
|
#endif
|
|
#endif //COMBO_IME
|
|
// inform UI, dwSelectedCand is changed
|
|
lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
|
|
return;
|
|
}
|
|
|
|
if (wCharCode == 0x24) {
|
|
if (lpCandList->dwSelection < lpCandList->dwPageSize) {
|
|
MessageBeep((UINT)-1);
|
|
return;
|
|
}
|
|
lpCandList->dwSelection = 0;
|
|
// inform UI, dwSelectedCand is changed
|
|
lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
|
|
return;
|
|
}
|
|
|
|
if (wCharCode == TEXT('?')) { // home selection
|
|
if (lpCandList->dwSelection == 0) {
|
|
MessageBeep((UINT)-1); // already home!
|
|
return;
|
|
}
|
|
lpCandList->dwSelection = 0;
|
|
// inform UI, dwSelectedCand is changed
|
|
lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
|
|
return;
|
|
}
|
|
|
|
if ((wCharCode >= TEXT('0')) && wCharCode <= TEXT('9')) {
|
|
|
|
DWORD dwSelCand;
|
|
|
|
dwSelCand = wCharCode - TEXT('0') - CAND_START;
|
|
if(wCharCode == TEXT('0')) {
|
|
dwSelCand = 9;
|
|
}
|
|
|
|
if (dwSelCand >= CANDPERPAGE) {
|
|
// out of candidate page range
|
|
MessageBeep((UINT)-1);
|
|
return;
|
|
}
|
|
|
|
if ((lpCandList->dwSelection + dwSelCand) >=
|
|
lpCandList->dwCount) {
|
|
// out of range
|
|
MessageBeep((UINT)-1);
|
|
return;
|
|
}
|
|
|
|
lpCandList->dwSelection = lpCandList->dwSelection + dwSelCand;
|
|
|
|
lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
|
|
if (!lpCompStr) {
|
|
return;
|
|
}
|
|
|
|
// translate into translate buffer
|
|
SelectOneCand(lpIMC, lpCompStr, lpImcP, lpCandList);
|
|
|
|
ImmUnlockIMCC(lpIMC->hCompStr);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
return;
|
|
}
|