📄 compose.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 + -