461 lines
12 KiB
C
461 lines
12 KiB
C
// 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
|