// 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