|
|
// Copyright (c) 1985 - 1999, Microsoft Corporation
//
// MODULE: imefull.c
//
// PURPOSE: Console IME control.
//
// PLATFORMS: Windows NT-J 3.51
//
// FUNCTIONS:
// ImeOpenClose() - calls initialization functions, processes message loop
//
// History:
//
// 27.Jul.1995 v-HirShi (Hirotoshi Shimizu) created
//
// COMMENTS:
//
#include "precomp.h"
#pragma hdrstop
//**********************************************************************
//
// IMEOpenClose()
//
// This routines calls IMM API to open or close IME.
//
//**********************************************************************
VOID ImeOpenClose( HWND hWnd, BOOL fFlag ) { HIMC hIMC;
//
// If fFlag is true then open IME; otherwise close it.
//
if ( !( hIMC = ImmGetContext( hWnd ) ) ) return;
ImmSetOpenStatus( hIMC, fFlag );
ImmReleaseContext( hWnd, hIMC );
}
#ifdef DEBUG_MODE
/************************************************************************
* * VirtualKeyHandler - WM_KEYDOWN handler * * * INPUT: HWND - handle to the window for repainting output. * UINT - virtual key code. * ************************************************************************/
VOID VirtualKeyHandler( HWND hWnd, UINT wParam, UINT lParam ) { PCONSOLE_TABLE ConTbl; int i; static int delta ;
ConTbl = SearchConsole(LastConsole); if (ConTbl == NULL) { DBGPRINT(("CONIME: Error! Cannot found registed Console\n")); return; }
if ( ConTbl->fInCandidate || ( ConTbl->fInComposition && !MoveCaret( hWnd ) ) ) return;
switch( wParam ) { case VK_HOME: // beginning of line
xPos = FIRSTCOL; break;
case VK_END: // end of line
xPos = xPosLast ; break;
case VK_RIGHT: if ( IsUnicodeFullWidth( ConvertLine[xPos] ) ){ if (xPos > xPosLast - 2 ) break; //last character don't move
xPos += 2; //skip 2 for DB Character
} else xPos = min( xPos+1, xPosLast ); break;
case VK_LEFT:
xPos = max( xPos-1, FIRSTCOL );
if ( IsUnicodeFullWidth( ConvertLine[xPos] ) ) xPos--; break;
case VK_BACK: // backspace
if ( xPos > FIRSTCOL ) { delta = 1 ;
//
// DB Character so backup one more to allign on boundary
//
if ( IsUnicodeFullWidth( ConvertLine[xPos] ) ) delta = 2 ; //
// Fall Through to VK_DELETE to adjust row
//
xPos -= delta ; for ( i = xPos ; i < xPosLast+2 ; i++) { ConvertLine[i] = ConvertLine[i+delta] ; ConvertLineAtr[i] = ConvertLineAtr[i+delta] ; } xPosLast -= delta ; } else //FIRST COLUMN don't backup -- this would change for wrapping
break; goto Repaint ; break; case VK_DELETE: if ( !IsUnicodeFullWidth( ConvertLine[xPos] ) ) {
//
// Move rest of line left by one, then blank out last character
//
for ( i = xPos; i < xPosLast; i++ ) { ConvertLine[i] = ConvertLine[i+1]; ConvertLineAtr[i] = ConvertLineAtr[i+1]; } xPosLast-- ;
} else {
//
// Move line left by two bytes, blank out last two bytes
//
for ( i = xPos; i < xPosLast; i++ ) { ConvertLine[i] = ConvertLine[i+2]; ConvertLineAtr[i] = ConvertLineAtr[i+2]; } xPosLast -= 2 ; }
goto Repaint ; break;
case VK_TAB: // tab -- tabs are column allignment not character
{ int xTabMax = xPos + TABSTOP; int xPosPrev;
do { xPosPrev = xPos; if ( IsUnicodeFullWidth( ConvertLine[xPos] ) ){ if (xPos > xPosLast - 2 ) break; //last character don't move
xPos += 2; //skip 2 for DB Character
} else xPos = min( xPos+1, xPosLast );
} while ( (xPos % TABSTOP) && (xPos < xTabMax) && (xPos != xPosPrev));
} goto Repaint ; break;
case VK_RETURN: // linefeed
for (i = FIRSTCOL ; i < MAXCOL ; i++) { ConvertLine[i] = ' ' ; ConvertLineAtr[i] = 0 ; } xPos = FIRSTCOL; xPosLast = FIRSTCOL; Repaint: { //
// Repaint the entire line
//
HDC hdc;
hdc = GetDC( hWnd ); HideCaret( hWnd ); DisplayConvInformation( hWnd ) ; ReleaseDC( hWnd, hdc ); } break; } ResetCaret( hWnd ); } #endif
/************************************************************************
* * CharHandler - WM_CHAR handler * ************************************************************************/
VOID CharHandlerFromConsole( HWND hWnd, UINT Message, ULONG wParam, ULONG lParam) { UINT TmpMessage ; DWORD dwImmRet ; UINT uVKey ; UINT wParamSave ;
if (HIWORD(wParam) == 0){ wParamSave = wParam ; } else { if (Message == WM_KEYDOWN +CONIME_KEYDATA || Message == WM_KEYUP +CONIME_KEYDATA || Message == WM_SYSKEYDOWN+CONIME_KEYDATA || Message == WM_SYSKEYUP+CONIME_KEYDATA){ wParamSave = 0 ; } else if(HIWORD(wParam) > 0x00ff){ WCHAR WideChar ; UCHAR MultiChar ; WideChar = HIWORD(wParam) ; WideCharToMultiByte(CP_OEMCP, 0, &WideChar, 1, &MultiChar, 1, NULL, NULL) ; wParamSave = MultiChar ; } else { wParamSave = HIWORD(wParam) ; } }
if (HIWORD(lParam) & KF_UP) // KEY_TRANSITION_UP
TmpMessage = WM_KEYUP ; else TmpMessage = WM_KEYDOWN ;
// Return Value of ClientImmProcessKeyConsoleIME
// IPHK_HOTKEY 1 - the vkey is IME hotkey
// IPHK_PROCESSBYIME 2 - the vkey is the one that the IME is waiting for
// IPHK_CHECKCTRL 4 - not used by NT IME
dwImmRet = ImmCallImeConsoleIME(hWnd, TmpMessage, wParam, lParam, &uVKey) ;
if ( dwImmRet & IPHK_HOTKEY ) { //
// if this vkey is the IME hotkey, we won't pass
// it to application or hook procedure.
// This is what Win95 does. [takaok]
//
return ; } else if (dwImmRet & IPHK_PROCESSBYIME) { BOOL Status ;
//3.51
// uVKey = (wParamSave<<8) | uVKey ;
// Status = ClientImmTranslateMessageMain( hWnd,uVKey,lParam);
Status = ImmTranslateMessage(hWnd, TmpMessage, wParam, lParam);
} else if (dwImmRet & IPHK_CHECKCTRL) { CharHandlerToConsole( hWnd, Message-CONIME_KEYDATA, wParamSave, lParam); } else { if ((Message == WM_CHAR +CONIME_KEYDATA)|| (Message == WM_SYSCHAR+CONIME_KEYDATA)) { CharHandlerToConsole( hWnd, Message-CONIME_KEYDATA, wParamSave, lParam); } else CharHandlerToConsole( hWnd, Message-CONIME_KEYDATA, wParam, lParam); }
}
VOID CharHandlerToConsole( HWND hWnd, UINT Message, ULONG wParam, ULONG lParam) { PCONSOLE_TABLE ConTbl; WORD ch ; int NumByte = 0 ;
ConTbl = SearchConsole(LastConsole); if (ConTbl == NULL) { DBGPRINT(("CONIME: Error! Cannot found registed Console\n")); return; }
if (HIWORD(lParam) & KF_UP ) { PostMessage( ConTbl->hWndCon, Message+CONIME_KEYDATA, wParam, lParam) ; return ; }
ch = LOWORD(wParam) ; if ((ch < UNICODE_SPACE) || ((ch >= UNICODE_SPACE) && ((Message == WM_KEYDOWN) || (Message == WM_SYSKEYDOWN) ))) { #ifdef DEBUG_MODE
VirtualKeyHandler( hWnd, wParam ,lParam) ; #endif
PostMessage( ConTbl->hWndCon, Message+CONIME_KEYDATA, wParam, lParam) ; return ; }
#ifdef DEBUG_MODE
StoreChar( hWnd, ch, 0); #endif
PostMessage( ConTbl->hWndCon, Message+CONIME_KEYDATA, wParam, //*Dest,
lParam) ; }
#ifdef DEBUG_MODE
//**********************************************************************
//
// void ImeUIMove()
//
// Handler routine of WM_MOVE message.
//
//*********************************************************************
VOID ImeUIMoveCandWin( HWND hwnd ) { PCONSOLE_TABLE ConTbl;
ConTbl = SearchConsole(LastConsole); if (ConTbl == NULL) { DBGPRINT(("CONIME: Error! Cannot found registed Console\n")); return; }
if ( ConTbl->fInCandidate ) { POINT point; // Storage for caret position.
int i; // loop counter.
int NumCandWin; // Storage for num of cand win.
RECT rect; // Storage for client rect.
//
// If current IME state is in chosing candidate, here we
// move all candidate windows, if any, to the appropriate
// position based on the parent window's position.
//
NumCandWin = 0;
GetCaretPos( (LPPOINT)&point ); ClientToScreen( hwnd, (LPPOINT)&point );
for ( i = 0; i < MAX_LISTCAND ; i++ ) { if ( ConTbl->hListCand[ i ] ) { GetClientRect( ConTbl->hListCand[ i ], &rect );
MoveWindow( ConTbl->hListCand[ i ], point.x + X_INDENT * NumCandWin, point.y + Y_INDENT * NumCandWin + cyMetrics, ( rect.right - rect.left + 1 ), ( rect.bottom - rect.top + 1 ), TRUE );
NumCandWin++; } } } } #endif
#ifdef DEBUG_MODE
/************************************************************************
* * ResetCaret - Reset caret shape to match input mode (overtype/insert) * ************************************************************************/
VOID ResetCaret( HWND hWnd ) {
HideCaret( hWnd ); DestroyCaret(); CreateCaret( hWnd, NULL, IsUnicodeFullWidth( ConvertLine[xPos] ) ? CaretWidth*2 : CaretWidth, cyMetrics ); SetCaretPos( xPos * cxMetrics, 0 ); ShowCaret( hWnd );
}
//**********************************************************************
//
// BOOL MoveCaret()
//
//**********************************************************************
BOOL MoveCaret( HWND hwnd ) { HIMC hIMC; BOOL retVal = TRUE;
if ( !( hIMC = ImmGetContext( hwnd ) ) ) return retVal;
if ( ImmGetCompositionString( hIMC, GCS_CURSORPOS, (void FAR *)NULL, 0 ) ) retVal = FALSE;
ImmReleaseContext( hwnd, hIMC );
return retVal; } #endif
#ifdef DEBUG_MODE
/************************************************************************
* * StoreChar - Stores one character into text buffer and advances * cursor * ************************************************************************/
VOID StoreChar( HWND hWnd, WORD ch, UCHAR atr ) { HDC hdc;
if ( xPos >= CVMAX-3 ) return;
//
// Store input character at current caret position
//
ConvertLine[xPos] = ch; ConvertLineAtr[xPos] = atr; xPos++ ; xPosLast = max(xPosLast,xPos) ;
//
// Repaint the entire line
//
hdc = GetDC( hWnd ); HideCaret( hWnd ); DisplayConvInformation( hWnd ) ; ResetCaret( hWnd ); ReleaseDC( hWnd, hdc );
} #endif
|