?? ime.cpp
字號:
* IUndoBuilder &undobldr )
*
* @mfunc
* Handle Level 3 WM_IME_COMPOSITION messages.
*
* @comm
* Display all of the intermediary composition text as well as the final
* reading.
*
* @devnote
* This is a rudimentary solution for replacing text in the backing store.
* Work is left to do with the undo list, underlining, and hiliting with
* colors and the selection.
*
* @devnote
* A GCS_RESULTSTR message can arrive and the IME will *still* be in
* composition string mode. This occurs because the IME's internal
* buffers overflowed and it needs to convert the beginning of the buffer
* to clear out some room. When this happens we need to insert the
* converted text as normal, but remain in composition processing mode.
*
* Another reason, GCS_RESULTSTR can occur while in composition mode
* for Korean because there is only 1 correct choice and no additional
* user intervention is necessary, meaning that the converted string can
* be sent as the result before composition mode is finished.
*
* @rdesc
* HRESULT-S_FALSE for DefWindowProc processing, S_OK if not.
*/
HRESULT CIme_Lev3::CompositionString(
const LPARAM lparam, // @parm associated with message.
CTxtEdit &ed, // @parm the containing text edit.
IUndoBuilder &undobldr) // @parm required to modify the text.
{
TRACEBEGIN(TRCSUBSYSFE, TRCSCOPEINTERN, "CIme_Lev3::CompositionString");
#ifdef DEBUG
static BOOL fNoRecurse = FALSE;
Assert ( !fNoRecurse );
fNoRecurse = TRUE;
#endif
// fix, need to come up with error handler for no selection.
CTxtSelection * const psel = ed.GetSel();
CTxtRange rg(&ed, 0,0);
HIMC hIMC;
INT cchOld;
WCHAR uniCompStr[256];
BYTE startAttrib, attrib[256];
BOOL fShowCursor;
LONG cursorCP, cchAttrib;
CCharFormat baseCF, CF;
LONG i,j, selStart; // For applying attrib
// effects.
LONG formatMin, formatMost;
BOOL fKBSwitchSave;
if ( !psel ) // Needed for Level 3.
return S_FALSE;
Assert (psel);
psel->SetIsChar(TRUE);
fKBSwitchSave = ed._fAutoKeyboard; // Don't allow switch!
ed._fAutoKeyboard = FALSE; // causes re-entrance.
if ( CLEANUP_COMPOSITION_STRING || HAVE_RESULT_STRING ) // Any final readings?
{
psel->ShowCaret(FALSE);
psel->ShowSelection(FALSE);
psel->SetSelection(_ichStart+_cchCompStr, _ichStart+_cchCompStr);
rg.Set( _ichStart + _cchCompStr, _cchCompStr);// Select old text.
rg.Set_iCF(_iFormatSave); // For degenerate case.
rg.ReplaceRange( 0, NULL, NULL, SELRR_IGNORE);// Delete previous text.
psel->Set_iCF(_iFormatSave); // Insert final reading.
CheckInsertResultString(lparam, ed, undobldr);
// GuyBark JupiterJ 49758:
// We may have just changed the font to be a J font to suit the text
// just entered through the IME. Don't change the font back to what it
// was before, otherwise the user doesn't know the font used to insert
// the text.
// psel->Set_iCF(_iFormatSave);
psel->ShowSelection(TRUE);
psel->ShowCaret(TRUE);
_ichStart = psel->GetCpMin(); // Reset as we may still
_cchCompStr = 0; // be in composition mode.
_fHoldNotify = FALSE; // OK notify client for change
}
if ( HAVE_COMPOSITION_STRING ) // In composition mode?
{
hIMC = ed.TxImmGetContext(); // Get host's IME context.
cchOld = _cchCompStr;
_cchCompStr = 0;
cchAttrib = 0;
if ( hIMC ) // Get new intermediate
{ // composition string,
// attribs, and caret.
_cchCompStr = GetCompositionStringInfo( hIMC, GCS_COMPSTR,
uniCompStr, sizeof(uniCompStr)/sizeof(uniCompStr[0]),
attrib, sizeof(attrib)/sizeof(attrib[0]),
&cursorCP, &cchAttrib );
ed.TxImmReleaseContext( hIMC ); // Done with IME context.
}
// When there is no old text or new text, just show the caret
// This is the case when client used TerminateIMEComposition with
// CPS_CANCEL option.
if ( !cchOld && !_cchCompStr )
psel->ShowCaret(TRUE);
else
{
#ifndef MACPORT
// this is to support Korean overstrike mode
if ( _fKorean && !cchOld && ed._fOverstrike )
psel->PrepareIMEOverstrike ( &undobldr ); // get ride of the next char if necessary
#endif
// Select the old composition text and replace them with
// the new composition text.
ed.GetCharFormat(_iFormatSave)->Get(&baseCF); // Remove underline attrib.
if (!_fKorean)
{
baseCF.dwEffects &= ~CFE_UNDERLINE;
baseCF.bUnderlineType = 0;
}
rg.Set( _ichStart+cchOld, cchOld); // Select old comp string.
#ifdef PWD_JUPITER
// GuyBark:
// If this is a J character, make sure a J font is selected
// Only change the charset if we may be handling a CJK character.
if(uniCompStr[0] >= 0x3000)
{
baseCF.dwMask |= CFM_CHARSET;
baseCF.bCharSet = GetCharSet(GetKeyboardCodePage());
}
#endif // PWD_JUPITER
rg.SetCharFormat(&baseCF, FALSE, NULL); // Set format for new text.
LONG ccAdded = rg.CleanseAndReplaceRange( _cchCompStr, uniCompStr, TRUE, NULL );// Replace with new text...
if (!_cchCompStr && _fKorean)
{
// make sure the current format is restored.
psel->Set_iCF(_iFormatSave);
}
// ensure that the cursor position and _cchCompStr matched what we have added
// to avoid the max. text length case.
_cchCompStr = min(ccAdded, _cchCompStr);
if ( cursorCP > 0 )
cursorCP = min(ccAdded, cursorCP) ;
selStart = -1;
_invertMin = 0;
_invertMost = 0;
if ( ccAdded && ccAdded <= cchAttrib && !_fKorean ) // no Korean style needed
{
for ( i = 0; i < ccAdded; ) // Parse the attributes...
{ // to apply selection,
// and styles.
startAttrib = attrib[i]; // Get attrib's run length.
for ( j = i+1; j < ccAdded; j++ )
{
if ( startAttrib != attrib[j] ) // Same run until diff.
break;
}
// remember sel start.
if ( startAttrib == ATTR_TARGET_CONVERTED )
{
// Windows CE Platforms Bug #10084 May 25,01 v-holee
if( LANG_CHINESE != PRIMARYLANGID( LOWORD( GetKeyboardLayout(0) ) )) //
{
Assert ( -1 == selStart ); // only 1 selection??
selStart = _ichStart + i;
cursorCP = i; // RAID #4043,8982 fix. If there is ATTR_TARGET_CONVERTED, don"t display caret.
}
}
#ifndef PWD_JUPITER
// Guybark Jupiter 47621:
// Allow the caret to sit inside an uncomposed string for JupiterJ.
else if ( startAttrib == ATTR_TARGET_NOTCONVERTED )
cursorCP = -1; // turn off caret
#endif // PWD_JUPITER
CF = baseCF; // Ask IMEShare for style.
if ( SetCompositionStyle ( ed, CF, startAttrib ) )
{
formatMin = _ichStart + i; // Book keeping to help
formatMost = formatMin + (j-i); // renderer draw IME
// selection.
if ( formatMin < _invertMin )
_invertMin = formatMin;
if ( formatMost > _invertMost )
_invertMost = formatMost;
}
rg.Set( _ichStart + i, -(j-i)); // Apply FE clause's style.
rg.SetCharFormat(&CF, FALSE, NULL);
i = j;
}
}
fShowCursor = FALSE;
if ( cursorCP >= 0 ) // If a cursor pos exist...
{
cursorCP += _ichStart; // Set cursor and scroll.
SetIMECaretWidth ( dxCaret ); // setup initial caret width
#ifndef MACPORT
if ( _fKorean && ccAdded ) // Set-up Korean Block
{ // cursor.
LONG xWidth = dxCaret;
LONG iFormat;
const CCharFormat *pCF;
HDC hdc;
CCcs *pccs; // Font cache.
if ( psel )
{
POINT ptCurrentPos; // caret position of previous character
INT CurrentCaretHt; // caret height of current character
INT NewCaretHt=0; // caret height of previous character
INT CurrentDescent; // descent of current character
INT NewDescent=0; // descent of previous character
// Force a scroll for Korean block caret.
// Otherwise, the current Korean character will not display
// when it is at the end of line for single-lined control.
psel->SetSelection( cursorCP+1, cursorCP+1 );
hdc = ed.TxGetDC(); // Get the font cache
if ( hdc )
{
iFormat = psel->Get_iCF();
pCF = ed.GetCharFormat(iFormat);
ReleaseFormats(iFormat, -1);
if ( pCF )
{
pccs = fc().GetCcs(hdc, pCF, ed._pdp->GetZoomNumerator(),
ed._pdp->GetZoomDenominator(), GetDeviceCaps(hdc, LOGPIXELSY));
if( pccs ) // If font cache exist...
{
pccs->Include( *uniCompStr, xWidth);
// setup new character height info for caret height calc.
NewDescent = pccs->_yDescent;
NewCaretHt = pccs->_yHeight;
pccs->Release();
}
}
ed.TxReleaseDC( hdc );
}
psel->SetSelection( cursorCP, cursorCP );
CurrentDescent = psel->GetCurrentDescent();
CurrentCaretHt = (INT)psel->GetCaretHt();
if ( NewCaretHt == 0 )
// This is 0 if we fail to get pccs
NewCaretHt = CurrentCaretHt;
else if ( CurrentCaretHt != NewCaretHt && ::GetCaretPos( &ptCurrentPos ) )
{
// current character font size is diff, adjust the caret position
// before using the new caret height
ptCurrentPos.y += (( CurrentCaretHt - NewCaretHt ) -
( CurrentDescent - NewDescent ));
ed.TxSetCaretPos ( ptCurrentPos.x, ptCurrentPos.y );
}
GetCaretPos( &ptCurrentPos ); // v-holee: Korean block caret
psel->ShowCaret(FALSE); // Because create turns off
SetIMECaretWidth ( xWidth ); // setup Korean block caret width
ed.TxCreateCaret(0, (INT) xWidth, NewCaretHt );
ed.TxSetCaretPos ( ptCurrentPos.x, ptCurrentPos.y ); // v-holee: Korean block caret
}
}
else
#endif
psel->SetSelection( cursorCP, cursorCP );
if ( selStart < 0 || cursorCP != selStart )
{ // Don't display caret if
// it is part of target
fShowCursor = TRUE; // that is selected.
}
}
psel->ShowCaret(fShowCursor);
// we don't want caret, need to reset _fUpdateSelection so
// CCallMgr::~CCallMgr() will not display the caret via Update()
if ( !fShowCursor )
ed._fUpdateSelection = FALSE;
// make sure we have set the call manager text changed flag. This flag
// may be cleared when calling SetCharFormat
ed.GetCallMgr()->SetChangeEvent(CN_TEXTCHANGED);
// setup composition window for Chinese in-caret IME
if ( !_fKorean )
IMENotify ( IMN_OPENCANDIDATE, 0x01, ed );
}
// don't notify client for changes only when there is composition string available
if ( _cchCompStr && !ed._fIMEAlwaysNotify )
_fHoldNotify = TRUE;
}
psel->SetIsChar(FALSE);
psel->CheckUpdateWindow();
#ifdef DEBUG
fNoRecurse = FALSE;
#endif
ed._fAutoKeyboard = fKBSwitchSave; // Allow KB switching.
return S_OK; // No DefWindowProc
} // processing.
/*
* BOOL CIme_Lev3::SetCompositionStyle ( CTxtEdit &ed, CCharFormat &CF, UINT attribute )
*
* @mfunc
* Set up a composition clause's character formmatting.
*
* @comm
* If we loaded Office's IMEShare.dll, then we ask it what the formatting
* should be, otherwise we use our own, hardwired default formatting.
*
* @devnote
* Note the use of pointers to functions when dealing with IMEShare funcs.
* This is because we dynamically load the IMEShare.dll.
*
* @rdesc
* BOOL - This is because CFU_INVERT is treated like a selection by
* the renderer, and we need to know the the min invertMin and
* the max invertMost to know if the rendered line should be treated
* as if there are selections to be drawn.
*/
BOOL CIme_Lev3::SetCompositionStyle (
CTxtEdit &ed,
CCharFormat &CF,
UINT attribute )
{
#pragma message ("This needs to be reviewed")
// GuyBark: We want this on Windows CE's PWord.
// #if 0
#ifdef PWD_JUPITER
BOOL fInvertStyleUsed = FALSE;
CF.dwEffects &= ~CFE_UNDERLINE; // default.
CF.bUnderlineType = 0;
// GuyBark: there's no shared ime in the shared Office dll on the device.
//#ifndef MACPORT
#ifdef NEVER
const IMESTYLE *pIMEStyle;
UINT ulID;
COLORREF color;
// load ImeShare if it has not been done
if ( !fLoadIMEShareProcs )
{
InitNLSProcTable( LOAD_IMESHARE );
fLoadIMEShareProcs = TRUE;
}
if ( fHaveIMEShareProcs )
{
pIMEStyle = pPIMEStyleFromAttr( attribute );
if ( NULL == pIMEStyle )
goto defaultStyle;
CF.dwEffects &= ~CFE_BOLD & ~CFE_ITALIC;
if ( pFBoldIMEStyle ( pIMEStyle ) )
CF.dwEffects |= CFE_BOLD;
if ( pFItalicIMEStyle ( pIMEStyle ) )
CF.dwEffects |= CFE_ITALIC;
if ( pFUlIMEStyle ( pIMEStyle ) )
{
CF.dwEffects |= CFE_UNDERLINE;
CF.bUnderlineType = CFU_UNDERLINE;
ulID = pIdUlIMEStyle ( pIMEStyle );
if ( UINTIMEBOGUS != ulID )
{
if ( IMESTY_UL_DOTTED == ulID )
CF.bUnderlineType = CFU_UNDERLINEDOTTED;
}
}
color = pRGBFromIMEColorStyle( pPColorStyleTextFromIMEStyle ( pIMEStyle ));
if ( UINTIMEBOGUS != color )
{
CF.dwEffects &= ~CFE_AUTOCOLOR;
CF.crTextColor = color;
}
color = pRGBFromIMEColorStyle( pPColorStyleBackFromIMEStyle ( pIMEStyle ));
if ( UINTIMEBOGUS != color )
{
CF.dwEffects &= ~CFE_AUTOBACKCOLOR;
CF.crBackColor = color;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -