📄 textserv.cpp
字号:
// if we are not streaming into the selection, then we are
// "loading" the entire file; this is not an undo-able operation,
// so set the undo builder to NULL and get rid of the current
// undo stacks
publdr = NULL;
ClearUndo(&undobldr);
if(msg == EM_STREAMIN)
{
wparam |= SFF_ADJUSTENDEOP;
// clear away the file information if necessary
if( !(wparam & SFF_KEEPDOCINFO) )
{
CloseFile(FALSE);
}
}
}
if(msg == EM_STREAMIN)
{
// if we are going to be loading an entire file, we only
// want to check "normal' protection; we can ignore the
// fIsDBCS protection. This does mean that somebody
// can do an "insert file" and break apart a DBCS combo,
// but we'll have to live with that. Outlook uses
// RTF streaming in many different places, so the strong
// fIsDBCS protection breaks them.
if( (_dwEventMask & ENM_PROTECTED) &&
prg->IsProtected(0) == CTxtRange::PROTECTED_ASK &&
QueryUseProtection(prg, msg, wparam, lparam))
{
Sound();
Assert(lres == 0);
break;
}
// Freeze the display before loading
CFreezeDisplay fd(_pdp);
lres = _ldte.LoadFromEs(prg, wparam, (EDITSTREAM *)lparam,
FALSE, publdr);
if (_fFocus)
{
// Update caret but delay till display is thawed and do so only
// if we have the focus. If we do this all the time we get wierd
// scrolling effects such as scrolling to the beginning of a
// document when the focus is set. See bug #1649 for repro of
// wierd effects.
_pdp->SaveUpdateCaret(TRUE);
}
}
else
lres = _ldte.SaveToEs (prg, wparam, (EDITSTREAM *)lparam);
break;
}
#ifndef PEGASUS
case WM_SYSCOLORCHANGE:
TxInvalidateRect(NULL, FALSE);
break;
#endif
// debug stuff
#ifdef DEBUG
case EM_DBGPED:
OnDumpPed();
break;
#endif // DEBUG
case EM_SETEVENTMASK:
lres = _dwEventMask; // Set up to return value before
_dwEventMask = (DWORD)lparam; // the change
if (lparam & ENM_REQUESTRESIZE)
{
// We need to update the display just in case it changes.
_pdp->UpdateView();
}
break;
case EM_GETEVENTMASK:
lres = _dwEventMask;
break;
case EM_GETTHUMB:
LONG Pos;
BOOL IsEnabled;
if (TxGetVScroll(NULL, NULL, &Pos, NULL, &IsEnabled) == S_OK
&& IsEnabled )
{
lres = Pos;
}
break;
case EM_SETLANGOPTIONS:
_fAutoFont = (lparam & IMF_AUTOFONT) != 0;
_fAutoKeyboard = (lparam & IMF_AUTOKEYBOARD) != 0;
_fIMEAlwaysNotify = (lparam & IMF_IMEALWAYSSENDNOTIFY) != 0;
lres = 1;
if ( fHaveIMMProcs )
{
_fIMECancelComplete = (lparam & IMF_IMECANCELCOMPLETE) != 0;
lres = 1;
}
break;
case EM_GETLANGOPTIONS:
if ( _fAutoFont )
lres |= IMF_AUTOFONT;
if ( _fAutoKeyboard )
lres |= IMF_AUTOKEYBOARD;
if ( _fIMEAlwaysNotify )
lres |= IMF_IMEALWAYSSENDNOTIFY;
if ( fHaveIMMProcs )
{
if ( _fIMECancelComplete )
lres |= IMF_IMECANCELCOMPLETE;
}
break;
case EM_GETIMECOMPMODE:
lres = OnGetIMECompositionMode(*this);
break;
case EM_SETTEXTMODE:
lres = HandleSetTextMode(wparam);
break;
case EM_GETTEXTMODE:
lres = IsRich() ? TM_RICHTEXT : TM_PLAINTEXT;
if( _pundo && ((CUndoStack *)_pundo)->GetSingleLevelMode() )
{
lres |= TM_SINGLELEVELUNDO;
}
else
{
lres |= TM_MULTILEVELUNDO;
}
if( _fSingleCodePage )
{
lres |= TM_SINGLECODEPAGE;
}
else
{
lres |= TM_MULTICODEPAGE;
}
break;
case EM_LIMITTEXT:
lparam = wparam;
// Intentionally fall through. These messages are duplicates.
case EM_EXLIMITTEXT:
if (lparam == 0)
{
// 0 means set the control to the maximum size. However, because
// 1.0 set this to 64K will keep this the same value so as not to
// surprise anyone. Apps are free to set the value to be above 64K.
lparam = (LPARAM) cResetTextMax;
}
_cchTextMost = (LONG) lparam;
break;
case EM_AUTOURLDETECT:
if( !_fRich )
{
hr = lres = E_FAIL;
}
if( lparam != 0 || ((wparam | 1) != 1))
{
hr = lres = E_INVALIDARG;
break;
}
if( wparam == TRUE && !_pdetecturl )
{
_pdetecturl = new CDetectURL(this);
if( !_pdetecturl )
{
hr = lres = E_OUTOFMEMORY;
}
}
else if( !wparam && _pdetecturl )
{
delete _pdetecturl;
_pdetecturl = NULL;
}
break;
case EM_GETAUTOURLDETECT:
Assert(lres == 0);
Assert(hr == NOERROR);
if( _pdetecturl )
{
lres = TRUE;
}
break;
case WM_SIZE:
// we reset the "number of tries to put an active object
// in place" count here
_cActiveObjPosTries = MAX_ACTIVE_OBJ_POS_TRIES;
hr = S_FALSE;
break;
default:
def: hr = S_FALSE;
break;
}
if( plresult )
*plresult = lres;
return hr;
}
/*
* CTxtEdit::TxDraw (dwDrawAspect, lindex, pvAspect, ptd, hdcDraw,
* hicTargetDev, lprcBounds, lprcWBounds, lprcUpdate,
* pfnContinue, dwContinue)
*
* @mfunc Draws the text services object
*
* @rdesc HRESULT (typically S_OK).
*
* @comm
*
* This method renders the Text Services. It accepts the same parameters
* as the corresponding IViewObject::Draw method in OLE, with the extra
* <p lprcUpdate > parameter. It can be used while the host is inactive
* or active (in-place).
*
* If dwDrawAspect is DVASPECT_CONTENT, this method should render a screen
* image of the text content to the hdcDraw device context. The hicTargetDev
* and ptd parameters give information on the target device context if any
* (usually a printer).
*
* The lprcClient parameter gives the rectangle to render to, also called
* "client rectangle". This rectangle represents the position and extents
* of the entire image of the Text Services to be drawn. It is expressed in
* the logical coordinate system of hdcDraw. This parameter can only be NULL
* if the control is active. In that case, Text Services should render the
* in-place active view (which client rectangle can be obtained by calling
* TxGetClientRect on the host).
*
* The lprcUpdate parameter, if not NULL, gives the rectangle to update
* inside that client rectangle. It is given in the logical coordinate system
* of hdcDraw. If NULL, the entire client rectangle should be painted.
*
* Text Services should render with the appropriate zooming factor, which
* can be obtained from the client rect and the native size given by
* ITextHost::GetExtent. See ITextHost::GetExtent.
*
* If the drawing aspect is DVASPECT_DOCPRINT, the TxDraw method can assume
* that it is rendering to the printer. In that case, hdcDraw is the printer
* device context. TxDraw should still render the lprcBounds rectangle,
* starting at the current scrolling position. TS can make optimization for
* rendering to the printer (like not painting the background color if white)
* and certain screen specific elements (such as the selection) should not be
* rendered.
*
* General comments on OLE hosts and TxDraw (and TxSetCursor, TxQueryHitPoint):
*
* OLE hosts can call the TxDraw method at any time with any rendering DC or
* client rectangle. All an inactive OLE object has on a permanent basis is
* a himetric extent. It gets the rectangle in which to render only via the
* IViewObject::Draw call and this rectangle is valid only for the scope of
* that method. In fact, the same control can be rendered consecutively in
* different rectangles and different DCs for example because it is displayed
* simultaneously in different views on the screen.
*
* The client rectangle and DC passed to TxDraw should normally not be cached.
* However, this would force Text Services to recalc lines for every single
* draw, which would lead to terrible performance. So it is likely that Text
* Services will actually cache some information computed for a specific
* client rectangle and DC (such as the line breaks for example). On the
* next call to TxDraw, however, the validity of the cached information
* should be checked before it gets used, and updated information should be
* regenerated if necessary.
*
* When the control is in-place active, the problem is even more complex
* since TxDraw can still be called to render other views than the in-place
* active one. In other words, the client rectangle passed to TxDraw may
* not be the same as the active view one (passed to OnTxInPlaceActivate
* and obtained via TxGetClientRect on the host).The the host specifies
* what view they wish to display based on the lViewId parameter. If the
* value for lViewId is TXTVIEW_ACTIVE, the view referred to is the inplace
* active view. TXTVIEW_INACTIVE means some other view such as a print
* preview or even printing itself. It is important to note that
* TXTVIEW_INACTIVE views may not have scroll bars.
*
* The same comments apply to TxSetCursor and TxQueryHitPoint, discussed
* in the following sections.
*/
HRESULT CTxtEdit::TxDraw (
DWORD dwDrawAspect, //@parm Draw aspect
LONG lindex, //@parm Currently unused
void * pvAspect, //@parm Info for drawing optimizations (OCX 96)
DVTARGETDEVICE *ptd, //@parm Info on target device
HDC hdcDraw, //@parm Rendering device context
HDC hicTargetDev, //@parm Target information context
LPCRECTL lprcBounds, //@parm Bounding (client) rectangle
LPCRECTL lprcWBounds, //@parm Clipping rect for metafiles
LPRECT lprcUpdate, //@parm Dirty rectangle inside lprcBounds
BOOL (CALLBACK * pfnContinue) (DWORD), //@parm Callback for interupting
// long display (currently unused)
DWORD dwContinue, //@parm Parameter to pass to pfnContinue function
LONG lViewId ) //@parm View identifier
{
TRACEBEGIN(TRCSUBSYSTS, TRCSCOPEEXTERN, "CTxtEdit::TxDraw");
HRESULT hr;
#if !defined(NOMAGELLAN)
CMagellanBMPStateWrap bmpOff(*this, hdcDraw);
#endif
// These are rect's are used if we convert the the input parameters if we
// convert the HDC's mapping mode. The idea here is we avoid changing our
// clients memory.
RECTL rcLocalBounds;
RECTL rcLocalWBounds;
RECT rcLocalUpdate;
CCallMgr callmgr(this);
START_PROFILING
// if the display is frozen, don't let ourselves draw. This is a pretty
// hoaky re-entrancy check.
// FUTURE (alexgo/ricksa): be better about this.
if( TXTVIEW_ACTIVE == lViewId && _pdp->IsFrozen() )
{
return E_UNEXPECTED;
}
if(dwDrawAspect != DVASPECT_CONTENT && dwDrawAspect != DVASPECT_DOCPRINT)
{
// We don't support the aspect requested
return DV_E_DVASPECT;
}
if ((!lprcBounds && !_fInPlaceActive) || (hicTargetDev && !ptd))
{
// If we are not inplace active we must have a client rectangle
return E_INVALIDARG;
}
HDC hicLocal = NULL;
// Did they give us a ptd without a hic?
if (!hicTargetDev && ptd)
{
// Create and information context for the device information
// since it wasn't supplied.
hicLocal = CreateIC(
(TCHAR *)((BYTE *) ptd + ptd->tdDriverNameOffset),
(TCHAR *)((BYTE *) ptd + ptd->tdDeviceNameOffset),
(TCHAR *)((BYTE *) ptd + ptd->tdPortNameOffset),
(DEVMODE *)((BYTE *) ptd + ptd->tdExtDevmodeOffset));
if (NULL == hicLocal)
{
// Couldn't create it
return E_FAIL;
}
hicTargetDev = hicLocal;
}
BOOL fRestore = FALSE;
// Force DC in MM_TEXT
if(GetMapMode(hdcDraw) != MM_TEXT &&
GetDeviceCaps(hdcDraw, TECHNOLOGY) != DT_METAFILE)
{
fRestore = TRUE;
// Convert input parameters to new mapping.
if (lprcBounds)
{
rcLocalBounds = *lprcBounds;
lprcBounds = &rcLocalBounds;
WinLPtoDP(hdcDraw, (POINT *)lprcBounds, 2);
}
if(lprcWBounds)
{
rcLocalWBounds = *lprcWBounds;
lprcWBounds = &rcLocalWBounds;
WinLPtoDP(hdcDraw, (POINT *)lprcWBounds, 2);
}
if(lprcUpdate)
{
rcLocalUpdate = *lprcUpdate;
lprcUpdate = &rcLocalUpdate;
WinLPtoDP(hdcDraw, (POINT *)lprcUpdate, 2);
}
// Convert HDC to new mapping
ConvertDrawDCMapping(hdcDraw);
}
// Preallocate the memory so the set cannnot fail and we don't
// have
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -