⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compose.cpp

📁 输入法源代码自由拼音输入法源代码(T9)
💻 CPP
字号:
/*++

Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved

Module Name:

   compose.c 

++*/


#include <windows.h>
#include <imm.h>
#include "imedefs.h"

extern char	CurrentHz[PY_EDITER_HZ_ITEMS][4]; 
extern char	CurrentPy[PY_EDITER_PY_ITEMS][8];
/**********************************************************************/
/* Engine()                                                           */
/* Description:                                                       */
/*      search MB and fill lpCompStr and lpCandList                   */
/**********************************************************************/
int PASCAL Engine(  
    LPCANDIDATELIST     lpCandList
    )
{
	int count = 0 , i,RetWch;
	char pingyin[COMP_MAX_PYLEN+1];
	TCHAR HANZI[COMP_MAX_PYLEN+1];
		  
	if(!lpCandList)
	    return -1;
	   
	if( !WideCharToMultiByte( GetACP(), 
            0,
            lpImeL->tComCurItem,
            -1,
            pingyin,
            COMP_MAX_PYLEN, NULL, NULL ))
        return  -1;
	  
	count = GetHanZiByPinyin(pingyin,CurrentHz);  	   

	if(count == 0 )   	return  (-1);

	for(i=0; i<count; i++){
	   RetWch = MultiByteToWideChar( GetACP(),
		           0,
		 	       &(CurrentHz[i][0]),
		 	       -1, 
		 	       HANZI, 
		 	       4);

	   if(RetWch != 0 && RetWch<(COMP_MAX_PYLEN+1)){
          HANZI[2] = 0;
	      AddCodeIntoCand(lpCandList, HANZI );
       }
	}
	return (ENGINE_COMP);
}

/**********************************************************************/
/* AddCodeIntoCand()                                                  */
/**********************************************************************/
void PASCAL AddCodeIntoCand(
    LPCANDIDATELIST lpCandList,
    WORD          * wCode )
{
	UINT i, j;

	for( i = 0, j = 0 ; i < lpCandList->dwCount ; i++ ){
		j += lstrlen((WORD *)((LPBYTE)lpCandList + lpCandList->dwOffset[lpCandList->dwCount]));
		if((j + lstrlen( wCode )) >= IME_MAXCAND ) 
		    return;
	}

	lstrcpy((LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[lpCandList->dwCount]), wCode );  
	
	// null terminator
	*(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[lpCandList->dwCount] + lstrlen(wCode)*sizeof(WORD) ) = TEXT('\0');
	
	lpCandList->dwOffset[lpCandList->dwCount + 1]  = 
    	   lpCandList->dwOffset[lpCandList->dwCount] + lstrlen( wCode )*sizeof(WORD) + sizeof(TCHAR);
 
	lpCandList->dwCount++;

	return;
}

/**********************************************************************/
/* CompEscapeKey()                                                    */
/**********************************************************************/
void PASCAL CompEscapeKey(
    LPINPUTCONTEXT      lpIMC,
    LPCOMPOSITIONSTRING lpCompStr,
    LPPRIVCONTEXT      lpImcP)
{
	
	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);
		}
	}
}

/**********************************************************************/
/* CompBackSpaceKey()                                                 */
/**********************************************************************/
void PASCAL CompBackSpaceKey(
    LPINPUTCONTEXT      lpIMC,
    LPCOMPOSITIONSTRING lpCompStr,
    LPPRIVCONTEXT       lpImcP)
{
	char digtal[COMP_MAX_PYLEN+1];
	int  iLastinput = 0; 
	int  j ,MaxCount ,iTotalLen =0;

	while(iLastinput<COMP_MAX_PYLEN &&  lpImcP->bSeq[iLastinput] != 0) {
		digtal[iLastinput] = (char)lpImcP->bSeq[iLastinput];
		iLastinput++;
	}

	if(iLastinput>0) {
		lpImcP->bSeq[iLastinput -1] = 0;	
		digtal[iLastinput-1] = 0;
	}

	lpImcP->fdwImeMsg |= MSG_COMPOSITION;
	lpImcP->dwCompChar = TEXT('\b');
	lpImcP->fdwGcsFlag |= (GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS|GCS_DELTASTART);
   
	if ( lpImcP->bSeq[0] == 0 ) {
		lpImeL->iTotalItem      = 0; 
		lpImeL->tComSelItem[0]   = 0;
		lpImeL->tComCurItem[0]  = 0;
		InitCompStr(lpCompStr);
		*((LPUNAWORD)((LPBYTE)lpCompStr + lpCompStr->dwCompReadStrOffset)) = 0;
		sImeG.bGetFocus    = FALSE;
		sImeG. iCandSelID  = 0;
		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);
//			return;
		}

		if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
			lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_END_COMPOSITION) & ~(MSG_START_COMPOSITION);
//			return;
		}
	}

	if(digtal[0] != 0) {
		iLastinput    =  	EnumPinyinByDigit(digtal,CurrentPy);
		lpImeL->iTotalItem = iLastinput;
		if(iLastinput>0){
            TCHAR *pDes ;
		    iLastinput = 0; 
	        j = MultiByteToWideChar( GetACP(),
                    0,
                    &(CurrentPy[0][0]),
                    -1, 
                    lpImeL->tComCurItem, 
                    COMP_MAX_PYLEN);
	        pDes = lpImeL->tComSelItem;
	        while(iLastinput<COMP_MAX_PYLEN && iLastinput<j){
                    *pDes++  = lpImeL->tComCurItem[iLastinput];
		            iLastinput++;
	        }
	        MaxCount =  (lpImeL->iTotalItem>COMP_MAX_ITEM?COMP_MAX_ITEM:(lpImeL->iTotalItem));   
	        iLastinput = 0;	

	        pDes = ((LPUNAWORD)((LPBYTE)lpCompStr + lpCompStr->dwCompReadStrOffset));
	        while(iLastinput<MaxCount){
	        j = MultiByteToWideChar( GetACP(),
                    0,
                    &(CurrentPy[iLastinput][0]),
                    -1, 
                    pDes, 
                    COMP_MAX_PYLEN);
	        if(j>0){
	             pDes += (j-1);
				 iTotalLen +=(j-1);
				 *pDes =  0x20; 	
				 pDes++;
				 iTotalLen++;
			}
			iLastinput++;	
			}
			lpImeL->iStartItem = MaxCount;
			*((LPUNAWORD)((LPBYTE)lpCompStr + lpCompStr->dwCompReadAttrOffset )) =((ATTR_TARGET_CONVERTED << 8)|ATTR_TARGET_CONVERTED); 	
			lpCompStr->dwCompReadStrLen = iTotalLen;
		}
		lpCompStr->dwCursorPos = 0 ;  
	}
	
	// reading string is composition string for some simple IMEs
	// delta start is the same as cursor position for backspace
	lpCompStr->dwCompStrLen =lpCompStr->dwCompReadStrLen; 
	lpCompStr->dwDeltaStart = lpCompStr->dwCursorPos;
	Finalize(lpIMC, lpCompStr, lpImcP);
	return;
}

/**********************************************************************/
/* CompStrInfo()                                                      */
/**********************************************************************/
void PASCAL CompStrInfo(
    LPCOMPOSITIONSTRING lpCompStr,
    LPPRIVCONTEXT       lpImcP,
    WORD                wCharCode)
{
	register DWORD dwCursorPos;
	lpCompStr->dwCursorPos = 0;//it is very important
	dwCursorPos = lpCompStr->dwCursorPos;
	// dwCrusorPos limit
	if (dwCursorPos >= lpImeL->nMaxKey ||lpImeL->iTotalItem<1) {
		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;
	}

	{
		int iLastinput = 0; 
		// clean the sequence code
		while(iLastinput<COMP_MAX_PYLEN &&  lpImcP->bSeq[iLastinput] != 0) {
			iLastinput++;
		} 
		lpImcP->bSeq[iLastinput] = (BYTE)wCharCode;	
		iLastinput++;
		lpImcP->bSeq[iLastinput] = 0;	
	}

	// composition/reading string - UsedCode(Full Shape)
	lpImcP->dwCompChar = (DWORD)wCharCode;
	//input  param 	 wCharCode
	//output param   pingying list
	//output param   candlist
	{
		TCHAR *pDes ;
		int i = 0,j ,MaxCount ,iTotalLen =0;
		j = MultiByteToWideChar( GetACP(),
		     0,
		     &(CurrentPy[0][0]),
		     -1, 
		     lpImeL->tComCurItem, 
		     COMP_MAX_PYLEN);
		pDes = lpImeL->tComSelItem;
		while(i<COMP_MAX_PYLEN && i<j){
          *pDes++  = lpImeL->tComCurItem[i];
		  i++;
		}

		MaxCount =  (lpImeL->iTotalItem>COMP_MAX_ITEM?COMP_MAX_ITEM:(lpImeL->iTotalItem));   
		i = 0 ;
		pDes = ((LPUNAWORD)((LPBYTE)lpCompStr + lpCompStr->dwCompReadStrOffset));
		while(i<MaxCount){
           j = MultiByteToWideChar( GetACP(),
		        0,
		        &(CurrentPy[i][0]),
		        -1, 
		        pDes, 
		        COMP_MAX_PYLEN);
		        if(j>0){
	               pDes += (j-1);
	               iTotalLen +=(j-1);
	               *pDes =  0x20; 	
	               pDes++;
	               iTotalLen++;
				}
	               i++;	
		}
		lpImeL->iStartItem = MaxCount;
		*((LPUNAWORD)((LPBYTE)lpCompStr + lpCompStr->dwCompReadAttrOffset )) =((ATTR_TARGET_CONVERTED << 8)|ATTR_TARGET_CONVERTED); 	
		lpCompStr->dwCompReadStrLen = iTotalLen;
	}

	// 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
                                   )
{
	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( lpCandList);

	if (fEngine == ENGINE_COMP) {
		lpCandInfo->dwCount  = 1;
		if(lpCandList->dwCount != 0x0000) {  
			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_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;
	}

	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
                                          )
{
    
    if (!lpCompStr){
        return;
    }
   
    // backspace key 
    if (wCharCode == TEXT('\b')) {
        CompBackSpaceKey(lpIMC, lpCompStr, lpImcP);
        return;
    }
    // build up composition string info
    CompStrInfo(lpCompStr, lpImcP, wCharCode);
    Finalize(lpIMC, lpCompStr, lpImcP);    // compsition
    return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -