?? ime.cpp
字號:
DWORD cpMin = psel->GetCpMin();
DWORD cpMax = psel->GetCpMost();
const CCharFormat *pCF;
LONG iFormat;
if (cpMin != cpMax)
{
// for selection, we need to get the character format at cpMin+1
CTxtRange rg( &ed, cpMin+1, 0 );
iFormat = rg.Get_iCF ();
psel->Set_iCF( iFormat );
}
else
iFormat = psel->Get_iCF ();
// get current Char format
pCF = ed.GetCharFormat(iFormat);
ReleaseFormats(iFormat, -1);
// if current font is not set correctly,
// change to a font preferred by current keyboard.
if ( pCF && ((UINT)GetCodePage(pCF->bCharSet) != cp))
{
psel->CheckChangeFont ( &ed, TRUE, (WORD)GetKeyboardLCID(), cp );
}
}
if (piFormat)
*piFormat = psel ? psel->Get_iCF () : -1;
}
/*
* INT CIme::GetCompositionStringInfo( HIMC hIMC, DWORD dwIndex,
* WCHAR *uniCompStr, INT cchMax, BYTE *attrib, INT cbAttrib
* LONG cchAttrib )
*
* @mfunc
* For WM_IME_COMPOSITION string processing to get the requested
* composition string, by type, and convert it to Unicode.
*
* @devnote
* We must use ImmGetCompositionStringA because W is not supported
* on Win95.
*
* @rdesc
* INT-cch of the Unicode composition string.
* Out param in UniCompStr.
*/
INT CIme::GetCompositionStringInfo(
HIMC hIMC, // @parm IME context provided by host.
DWORD dwIndex, // @parm The type of composition string.
WCHAR *uniCompStr, // @parm Out param, unicode result string.
INT cchUniCompStr,// @parm The cch for the Out param.
BYTE *pattrib, // @parm Out param, If attribute info is needed.
INT cchAttrib, // @parm The cch of the attribute info.
LONG *pcursorCP, // @parm Out param, returns the CP of cusor.
LONG *pcchAttrib ) // @parm how many attributes returned.
{
TRACEBEGIN(TRCSUBSYSFE, TRCSCOPEINTERN, "CIme::GetCompositionStringInfo");
// Pay close attention to cbXXX v. cchXXX in this routine. One
// wrinkle: The attributes returned are an array of BYTEs, one per
// character in the string - so for pattrib cb==cch.
BYTE compStr[sizeof(WCHAR)*256], attribInfo[256]; // Fix for WinCEOS RAID #15245
INT j, cbUniCompStr, cbAttrib, cbCompStr, cchCompStr, cbAttribRet, cursor;
#ifndef PWD_JUPITER
INT i, iMax;
#endif // PWD_JUPITER
Assert ( hIMC );
Assert ( uniCompStr );
Assert ( cchUniCompStr >= 0 );
Assert ( !pattrib || cchAttrib >= 0 );
if ( pcursorCP ) // Init cursor out param.
*pcursorCP = -1;
if ( pcchAttrib )
*pcchAttrib = 0;
cbUniCompStr = cchUniCompStr * sizeof(WCHAR);
cbAttrib = cchAttrib * sizeof(WCHAR);
cbAttribRet = -1;
// Get composition string.
cbCompStr = pImmGetCompositionString( hIMC, dwIndex, compStr, sizeof(compStr)-1 ); // Fix for WinCEOS RAID #15245
// (ImmGetCompositionString takes size of compStr
// in bytes even for Unicode, returns size in bytes)
if ( cbCompStr > 0 ) // If valid data.
{
// GuyBark Jupiter:
// ImmGetCompositionStringA() doesn't exist on the device. So use the
// wide version of it, and don't do any of the mbcs->wide stuff here.
#ifndef PWD_JUPITER
// Convert to unicode
cchCompStr = UnicodeFromMbcs( uniCompStr, cchUniCompStr,
(CHAR *) compStr, cbCompStr );
#else
// We already have the unicode string.
memcpy((LPBYTE)uniCompStr, (LPBYTE)compStr, min(cbUniCompStr,min(cbCompStr, (INT)(sizeof(WCHAR)*256))));
// Return number of characters.
cchCompStr = cbCompStr / sizeof(WCHAR);
#endif // PWD_JUPITER
if ( pattrib || pcursorCP ) // Need cursor or attribs?
{
// Get DBCS Cursor cp.
cursor = pImmGetCompositionString( hIMC, GCS_CURSORPOS, NULL, 0 );
if ( pattrib )
{
// Get DBCS attributes.
cbAttribRet = pImmGetCompositionString( hIMC, GCS_COMPATTR,
attribInfo, 255 );
}
// GuyBark Jupiter:
// ImmGetCompositionStringA() doesn't exist on the device. So use the
// wide version of it, and don't do any of the mbcs->wide stuff here.
#ifndef PWD_JUPITER
// MultiToWide conversion.
iMax = max ( cursor, cbAttribRet );
if ( NULL == pattrib )
cbAttrib = cbAttribRet;
for (i = 0, j = 0; i <= iMax && j < cbAttrib; i++, j++ )
{
if ( cursor == i ) // Cursor from DBCS.
cursor = j;
if ( IsDBCSLeadByte( compStr[i] ) )
i++;
// shouldn't this be j instead of i??
if ( pattrib && i < cbAttribRet ) // Attrib from DBCS.
*pattrib++ = attribInfo[i];
}
j--; // back off from last byte
// attrib cch==unicode cch
Assert ( 0 >= cbAttribRet || j == cchCompStr ); // ??
#else
// Return attribute array.
if ( pattrib )
{
if ( cbAttribRet >= 0)
{
j = min(cbAttribRet, min(cbAttrib,256));
memcpy(pattrib, attribInfo, j);
}
}
#endif // PWD_JUPITER
if ( cursor >= 0 && pcursorCP ) // If client needs cursor
*pcursorCP = cursor; // or pcchAttrib.
if ( cbAttribRet >= 0 && pcchAttrib )
*pcchAttrib = j;
}
}
else
{
if ( pcursorCP )
*pcursorCP = 0;
cchCompStr = 0;
}
return cchCompStr;
}
/*
* void CIme::SetCompositionFont ( CTxtEdit &ed, BOOL *pbUnderLineMode )
*
* @mfunc
* Important for level 2 IME so that the composition window
* has the correct font. The lfw to lfa copy is due to the fact that
* Win95 does not support the W)ide call.
* It is also important for both level 2 and level 3 IME so that
* the candidate list window has the proper. font.
*/
void CIme::SetCompositionFont (
CTxtEdit &ed, // @parm the containing text edit.
BOOL *pbUnderLineMode) // @parm the original char Underline mode
{
TRACEBEGIN(TRCSUBSYSFE, TRCSCOPEINTERN, "CIme::SetCompositionFont" );
#ifndef MACPORT
HIMC hIMC = ed.TxImmGetContext();// Get host's IME context.
CTxtSelection *psel; // Selection.
HDC hdc;
CCcs *pccs; // Font cache.
LOGFONTW lfw;
#ifndef PWD_JUPITER
LOGFONTA lfa;
#endif // PWD_JUPITER
if ( hIMC )
{
hdc = ed.TxGetDC();
if ( hdc ) // the selection.
{
psel = ed.GetSel(); // Get the font cache for
if ( psel )
{
const CCharFormat *pCF;
pCF = ed.GetCharFormat(_iFormatSave);
if ( pCF )
{
BOOL bFontOK = TRUE;
if ( !ed.IsRich())
{
// We haven't done any font matching for plain text control,
// check if this font maches current keyboard codepage.
// If they don't match, we don't want to call ImmSetCompositionFont
// or else the Candidate list will show garbage.
if ( (UINT)GetCodePage(pCF->bCharSet) != GetKeyboardCodePage() )
bFontOK = FALSE;
}
if ( bFontOK )
{
#ifdef PWD_JUPITER
// GuyBark: Make sure the candidate window is displaying a J font.
CCharFormat CFj;
memcpy(&CFj, pCF, sizeof(CCharFormat));
CFj.bCharSet = GetCharSet(GetKeyboardCodePage());
pccs = fc().GetCcs(hdc, &CFj, ed._pdp->GetZoomNumerator(),
ed._pdp->GetZoomDenominator(), GetDeviceCaps(hdc, LOGPIXELSY));
#else
pccs = fc().GetCcs(hdc, pCF, ed._pdp->GetZoomNumerator(),
ed._pdp->GetZoomDenominator(), GetDeviceCaps(hdc, LOGPIXELSY));
#endif // PWD_JUPITER
if( pccs ) // If font cache exist...
{
lfw = pccs->_lf; // Note: W to A copy.
// GuyBark: On the device, there is no ansi version of ImmSetCompositionFont().
#ifndef PWD_JUPITER
memcpy(&lfa, &lfw, sizeof(lfa) - sizeof(lfa.lfFaceName));
MbcsFromUnicode(
lfa.lfFaceName, sizeof(lfa.lfFaceName), lfw.lfFaceName,
-1, CP_ACP, UN_NOOBJECTS);
// WinCE RAID #7183 fix.
if(_imeLevel != IME_LEVEL_3){
pImmSetCompositionFont( hIMC, &lfa );
}
#else
// WinCE RAID #7183 fix.
if(_imeLevel != IME_LEVEL_3){
pImmSetCompositionFont( hIMC, &lfw );
}
#endif
pccs->Release();
}
}
if (pbUnderLineMode)
{
*pbUnderLineMode = (pCF->dwEffects & CFE_UNDERLINE);
}
}
}
ed.TxReleaseDC( hdc );
}
ed.TxImmReleaseContext( hIMC ); // Done with IME context.
}
#endif
}
/*
* void CIme::SetCompositionForm ( CTxtEdit &ed )
*
* @mfunc
* Important for level 2 IME so that the composition window
* is positioned correctly.
*
* @comm
* We go through a lot of work to get the correct height. This requires
* getting information from the font cache and the selection.
*/
void CIme::SetCompositionForm (
CTxtEdit &ed ) // @parm the containing text edit.
{
TRACEBEGIN(TRCSUBSYSFE, TRCSCOPEINTERN, "CIme::SetCompositionForm" );
#ifndef MACPORT
HIMC hIMC;
CTxtSelection *psel; // Selection.
HDC hdc;
LONG iFormat;
const CCharFormat *pCF;
CCcs *pccs = NULL; // Font cache.
COMPOSITIONFORM cf;
RECT rcInset;
if ( IME_LEVEL_2 == GetIMELevel() )
{
hIMC = ed.TxImmGetContext(); // Get host's IME context.
if ( hIMC )
{
psel = ed.GetSel(); // Get the font cache for
if (NULL == psel)
{
AssertSz(psel, "Memory allocation eror in CIme::SetCompositionForm");
return;
}
hdc = ed.TxGetDC();
if ( hdc ) // the selection.
{
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));
}
ed.TxReleaseDC( hdc );
}
// 1st line starts at caret
if ( GetCaretPos( &cf.ptCurrentPos ) == FALSE
|| cf.ptCurrentPos.x < 0 || cf.ptCurrentPos.y < 0 )
{
// Update the caret since the current caret is not visible
if ( ed.fInplaceActive() )
{
psel->UpdateCaret(TRUE); // To force a scroll
GetCaretPos( &cf.ptCurrentPos );
}
}
if( pccs ) // If font cache exist...
{ // Finer caret adjustment.
if ( psel->GetCurrentDescent() >= 0 && psel->GetCaretHt() > 1 )
{
// Adjusted for the different in descents between current
// selected font and the current character.
cf.ptCurrentPos.y += psel->GetCaretHt()
+ ( pccs->_yDescent - psel->GetCurrentDescent()
- pccs->_yHeight );
}
pccs->Release();
}
// Bounding rect for the IME (lev 2) composition window, causing
// composition text to be wrapped within it.
cf.dwStyle = CFS_RECT;
ed.TxGetClientRect( &cf.rcArea ); // Set-up bounding rect.
ed.TxGetViewInset( &rcInset, NULL );
cf.rcArea.right -= rcInset.right;
cf.rcArea.bottom -= rcInset.bottom;
cf.rcArea.left += rcInset.left;
cf.rcArea.top += rcInset.top;
// Make sure the starting point is not
// outside the rcArea. This happens when
// there is no text on the current line and the user
// has selected a large font size.
if (cf.ptCurrentPos.y < cf.rcArea.top)
cf.ptCurrentPos.y = cf.rcArea.top;
else if (cf.ptCurrentPos.y > cf.rcArea.bottom)
cf.ptCurrentPos.y = cf.rcArea.bottom;
if (cf.ptCurrentPos.x < cf.rcArea.left)
cf.ptCurrentPos.x = cf.rcArea.left;
else if (cf.ptCurrentPos.x > cf.rcArea.right)
cf.ptCurrentPos.x = cf.rcArea.right;
pImmSetCompositionWindow( hIMC, &cf ); // Set composition window.
ed.TxImmReleaseContext( hIMC ); // Done with IME context.
}
}
#endif
}
/*
*
* CIme::TerminateIMEComposition ( CTxtEdit &ed )
*
* @mfunc Terminate the IME Composition mode using CPS_COMPLETE
* @comm The IME will generate WM_IME_COMPOSITION with the result string
*
*/
void CIme::TerminateIMEComposition(
CTxtEdit &ed, // @parm the containing text edit.
TerminateMode mode)
{
TRACEBEGIN(TRCSUBSYSFE, TRCSCOPEINTERN, "CIme::TerminateIMEComposition");
DWORD dwTerminateMethod;
HIMC hIMC = ed.TxImmGetContext();
dwTerminateMethod = CPS_COMPLETE;
if ( IME_LEVEL_2 == GetIMELevel() // force cancel for near-caret IME
|| mode == TERMINATE_FORCECANCEL // caller wants force cancel
|| ed._fIMECancelComplete ) // Client wants force cancel
{
dwTerminateMethod = CPS_CANCEL;
}
// force the IME to terminate the current session
if (hIMC)
{
BOOL retCode;
retCode = pImmNotifyIME( hIMC, NI_COMPOSITIONSTR,
dwTerminateMethod, 0);
if ( !retCode && !ed._fIMECancelComplete )
{
// CPS_COMPLETE fail, try CPS_CANCEL. This happen with some ime which do not support
// CPS_COMPLETE option (e.g. ABC IME version 4 with Win95 simplified Chinese)
retCode = pImmNotifyIME( hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -