⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dispml.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			if(pli->_fCollapsed)
				continue;

			// Get a local copy of the height
			yHeightForLine = pli->_yHeight;

			if ((pli->_bFlags & fliUseOffScreenDC) != 0)
			{
				// We only want to set the height for the bitmap if this
				// line needs off screen rendering. Otherwise, we can do
				// just as well by rendering the line directly.

				if (yHeightForLine > yHeightForBitmap)
				{
					// We want to figure out what is the height of the tallest 
					// line to be displayed off screen. The purpose of this is 
					// to allow the rendering to create  a bit map big enough 
					// that it does not have to be reallocated during 
					// the rendering of the screen.
					yHeightForBitmap = yHeightForLine;
				}
			}
	        yLi += yHeightForLine;
		}

		if ((0 != yHeightForBitmap) && (rcView.top > rcRender.top))
		{
			// Bit map for first line needs to be big enough to take into account
			// the area above the first line so, add the difference between view
			// and render start into the bitmap size.
			yHeightForBitmap += (rcView.top - rcRender.top);
		}
	}

	// Create renderer
	CRenderer re(this);

	// Prepare renderer
	if(!re.StartRender(rcView, rcRender, yHeightForBitmap))
		return;
	
	// Init renderer at the start of the first line to render
	re.SetCurPoint(pt);
   	re.SetCp(cp);

#ifdef DEBUG
    LONG cpLi = re.GetCp();
    yLi = pt.y;
#endif

	if (fLinesToRender)
	{
		// Render each line in the update rectangle
		for (; ili < lCount; ili++)
		{
			if(!re.RenderLine(GetAt(ili), ili == lCount - 1))
				break;

#ifdef DEBUG
			cpLi += Elem(ili)->_cch;
			yLi  += Elem(ili)->GetHeight();

			// Rich controls with password characters do not process EOPs. 
			// Therefore, the following assert is only valid when the above
			// is not the case.
			if (!_ped->IsRich() || !_ped->fUsePassword())
			{
				AssertSz(re.GetCp() == cpLi, 
					"CDisplayML::RenderView() - cp out of sync. with line table");
			}

			AssertSz(re.GetCurPoint().y == yLi,
				"CDisplayML::RenderView() - y out of sync. with line table");
#endif // DEBUG
		}
	}
	
	re.EndRender();						  // Finish rendering
}


//===================================  View Updating  ===================================

/*
 *	CDisplayML::RecalcView(fUpdateScrollBars)
 *
 *	@mfunc
 *		Recalc all lines breaks and update first visible line
 *
 *	@rdesc
 *		TRUE if success
 */
BOOL CDisplayML::RecalcView(
	BOOL fUpdateScrollBars)
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CDisplayML::RecalcView");

	BOOL fRet = TRUE;
	const LONG cp = _cpFirstVisible;
	LONG yHeightOld = _yHeight;
	LONG yScrollHeightOld = GetMaxYScroll();
	LONG xWidthOld = _xWidth;

	// full recalc lines
	if(!RecalcLines())
	{
		// the recalc failed
		// let's try to get out of this with our head still mostly attached
		InitVars();
		fRet = FALSE;
        goto Done;
	}

	if (_ped->GetTextLength() == 0)
	{
		// This is an empty control so create one empty line
		CreateEmptyLine();
	}


    // force _xScroll = 0 if x scroll range is smaller than the view width
    if(_xWidth <= _xWidthView)
	{
        _xScroll = 0;
	}

	// change first visible entries because CLinePtr::RpSetCp() and
	// YPosFromLine() use them, but they're not valid
	_dyFirstVisible = 0;
	_cpFirstVisible = 0;
	_iliFirstVisible = 0;
	_yScroll = 0;


	// recompute scrolling position and first visible values after edit
    // force _yScroll = 0 if y scroll range is smaller than the view height
    if(_yHeight > _yHeightView)
    {   	
    	CLinePtr rp(this);
   		rp.RpSetCp(cp, FALSE);
   		_yScroll = YposFromLine(rp);
		// we use rp.GetCp() instead of cp, because cp could now be
		// woefully out of date.  RpSetCp will set us to the closest
		// available cp.
   		_cpFirstVisible = rp.GetCp() - rp.RpGetIch();
   		_iliFirstVisible = rp;
	}

	CheckView();

	// We only need to resize if the size needed to display the object has 
	// changed.
	if ((yHeightOld != _yHeight) || (yScrollHeightOld != GetMaxYScroll())
		|| (xWidthOld != _xWidth))
	{
		if(FAILED(RequestResize()))
		{
			_ped->GetCallMgr()->SetOutOfMemory();
		}
	}

Done:

    // Now update the scrollbars
	if (fUpdateScrollBars)
	{
		RecalcScrollBars();
	}
    return fRet;
}

/*
 *	CDisplayML::UpdateView(&tpFirst, cchOld, cchNew)
 *
 *	@mfunc
 *		Recalc lines and update the visible part of the display 
 *		(the "view") on the screen.
 *
 *	@devnote
 *      --- Use when in-place active only ---
 *
 *	@rdesc
 *		TRUE if success
 */
BOOL CDisplayML::UpdateView(
	const CRchTxtPtr &tpFirst,	//@parm Text ptr where change happened
	LONG cchOld,				//@parm Count of chars deleted
	LONG cchNew)				//@parm Count of chars inserted
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CDisplayML::UpdateView");

	BOOL fReturn = TRUE;
	BOOL fRecalcVisible = TRUE;
	RECT rcClient;
    RECT rcView;
	CLed led;
	CTxtSelection *psel = _ped->GetSelNC();
	LONG cpStartOfUpdate = tpFirst.GetCp();
	BOOL fNeedViewChange = FALSE;
	LONG yHeightOld = _yHeight;
	LONG yScrollHeightOld = GetMaxYScroll();
	LONG xWidthOld = _xWidth;
	LONG yScrollOld = _yScroll;
	LONG cpNewFirstVisible;

	if (_fNoUpdateView)
		return fReturn;

	AssertSz(_ped->_fInPlaceActive, "CDisplayML::UpdateView(...) called when inactive");

	if( tpFirst.GetCp() > _cpCalcMax || _fNeedRecalc)
	{
		// we haven't even calc'ed this far, so don't bother with updating
		// here.  Background recalc will eventually catch up to us.
		return TRUE;
	}

	AssertSz(tpFirst.GetCp() <= _cpCalcMax, "CDisplayML::UpdateView(...) - tpFirst > _cpCaclMax");

	_ped->TxGetClientRect(&rcClient);
	GetViewRect(rcView, &rcClient);

	if(psel && !psel->PuttingChar())
		psel->ClearCchPending();

	DeferUpdateScrollBar();

	// In general, background recalc should not start until both the scroll 
	// position is beyond the visible view and the cp is beyond the first visible 
	// character. However, for the recalc we will only wait on the height. 
	// Later calls to WaitForRecalc will wait on cpFirstVisible if that is 
	// necessary.
	_yWait = _yScroll + _yHeightView;
	_cpWait = -1;

	if(!RecalcLines(tpFirst, cchOld, cchNew, FALSE, TRUE, &led))
	{
		// we're in deep crap now, the recalc failed
		// let's try to get out of this with our head still mostly attached
		InitVars();
		fRecalcVisible = TRUE;
		fReturn = FALSE;
		_ped->TxInvalidateRect (NULL, FALSE);
		fNeedViewChange = TRUE;
		goto Exit;
	}

	if(_ped->GetTextLength() == 0)
	{
		if(LineCount() != 0)
		{
			// There are currently elements in the line array, so zap them.
			Clear(AF_DELETEMEM);
		}
		// This is an empty control so create one empty line
		CreateEmptyLine();
	}


	if(_xWidth <= _xWidthView)
    {
		// x scroll range is smaller than the view width
        // force x scrolling position = 0
		_xScroll = 0;
    }

	if(led._yFirst >= _yScroll + _yHeightView)
	{
		// update is after the view, don't do anything
		fRecalcVisible = FALSE;

		Assert(VerifyFirstVisible());

		goto finish;
	}
	else if(led._yMatchNew <= _yScroll + _dyFirstVisible &&
			led._yMatchOld <= _yScroll + _dyFirstVisible)
	{
		// update is entirely before the view
		// just update scroll position but don't touch the screen
		_yScroll += led._yMatchNew - led._yMatchOld;
		_iliFirstVisible += led._iliMatchNew - led._iliMatchOld;
		_iliFirstVisible = max((LONG)_iliFirstVisible, 0);

		_cpFirstVisible += led._cpMatchNew - led._cpMatchOld;
		_cpFirstVisible = min((LONG)_ped->GetTextLength(), _cpFirstVisible);
		_cpFirstVisible = max(0, _cpFirstVisible);
		fRecalcVisible = FALSE;

		Assert(VerifyFirstVisible());
	}
	else
	{
		// update overlaps the visible view
		RECT rc = rcClient;
        RECT rcUpdate;
		RECT *prc = &rc;

		// Do we need to resync the first visible?  Note that this if check
		// is mostly an optmization; we could decide to _always_ recompute
		// this _iliFirstVisible if we wanted to.
		if ( cpStartOfUpdate <= _cpFirstVisible || 
			led._iliMatchOld <= _iliFirstVisible ||
			led._iliMatchNew <= _iliFirstVisible ||
			led._iliFirst <= _iliFirstVisible )
		{
			// Edit overlaps the first visible. We try to maintain
			// approximately the same place in the file visible.
			cpNewFirstVisible = _cpFirstVisible;

			if (_iliFirstVisible - 1 == led._iliFirst)
			{
				// The edit occurred on the line before the visible view. Most
				// likely this means that the the first character got pulled
				// back to the previous line so we want that line to be 
				// visible.
				cpNewFirstVisible = led._cpFirst;
			}

			// change first visible entries because CLinePtr::RpSetCp() and
			// YPosFromLine() use them, but they're not valid
			_dyFirstVisible = 0;
			_cpFirstVisible = 0;
			_iliFirstVisible = 0;
			_yScroll = 0;

			// with certain formatting changes, it's possible for 
			// cpNewFirstVisible to be less that what's been calculated so far 
			// in RecalcLines above. Wait for things to catch up.

			WaitForRecalc(cpNewFirstVisible, -1);

			// recompute scrolling position and first visible values after edit
		    CLinePtr rp(this);
   			rp.RpSetCp(cpNewFirstVisible, FALSE);
   			_yScroll = YposFromLine(rp);
   			_cpFirstVisible = rp.GetCp() - rp.RpGetIch();
   			_iliFirstVisible = rp;

			Assert(VerifyFirstVisible());
		}

		Assert(VerifyFirstVisible());

		// Is there a match in the display area? - this can only happen if the
		// old match is on the screen and the new match will be on the screen
		if ((led._yMatchOld < yScrollOld + _yHeightView)
			&& (led._yMatchNew < _yScroll + _yHeightView))
		{
			// we have a match inside the visible view

			// scroll the part that is below the old y pos of the match
			// or invalidate if the new y of the match is now below the view
			rc.top = rcView.top + (INT) (led._yMatchOld - yScrollOld);
			if(rc.top < rc.bottom)
			{
				// Calculate difference between the new and old screen
				// position.
				const INT dy = (INT) ((led._yMatchNew - _yScroll)) 
					- (led._yMatchOld - yScrollOld);

				if(dy)
				{
				    if(!_ped->_fTransparent)
                   {
    					_ped->TxScrollWindowEx(0, dy, &rc, &rcView,
    						NULL, &rcUpdate, 0);
		    			_ped->TxInvalidateRect(&rcUpdate, FALSE);
						fNeedViewChange = TRUE;

    					if(dy < 0)
	    				{
		    				rc.top = rc.bottom + dy;
			    			_ped->TxInvalidateRect(&rc, FALSE);
							fNeedViewChange = TRUE;
				    	}
    				}
                    else
                    {
						// adjust the rect since we are not doing 
						// scrolling for transparent mode
						RECT	rcInvalidate = rc;
   						rcInvalidate.top += dy;

                        _ped->TxInvalidateRect(&rcInvalidate, FALSE);
						fNeedViewChange = TRUE;
                    }
				}
			}
			else
			{
				rc.top = rcView.top + led._yMatchNew - _yScroll;
				_ped->TxInvalidateRect(&rc, FALSE);
				fNeedViewChange = TRUE;
			}

			// Because above it was determined that the new match fell
			// within the screen, we can safely set the bottom to the
			// new match since this is the most that can have changed.
			rc.bottom = rcView.top 
				+ (INT) (max(led._yMatchNew, led._yMatchOld) - _yScroll);
		}

		rc.top = rcView.top + (INT) (led._yFirst - _yScroll);

		// Set the first line edited to be rendered using off screen
		// rendering. 

		if (led._iliFirst < (LONG) Count() && !_ped->_fTransparent
			&& (Elem(led._iliFirst)->_bFlags & fliUseOffScreenDC) == 0)
		{	
			Elem(led._iliFirst)->_bFlags |= 
				(fliOffScreenOnce |	fliUseOffScreenDC);
			_fUpdateOffScreen = TRUE;
		}
		
		// Invalidate part of update that is above match (if any)
		_ped->TxInvalidateRect (&rc, FALSE);
		fNeedViewChange = TRUE;
	}

finish:

	if(fRecalcVisible)
	{
		fReturn = WaitForRecalcView();
		if( !fReturn )
		{
			goto Exit;
		}
	}

	if (fNeedViewChange)
	{
		_ped->GetHost()->TxViewChange(FALSE);
	}

	CheckView();

	// We only need to resize if the size needed to display the object has 
	// changed.
	if ((yHeightOld != _yHeight) || (yScrollHeightOld != GetMaxYScroll())
		|| (xWidthOld != _xWidth))
	{
		if(FAILED(RequestResize()))
		{
			_ped->GetCallMgr()->SetOutOfMemory();
		}
	}

	if(DoDeferredUpdateScrollBar())
	{
		if(FAILED(RequestResize()))
			_ped->GetCallMgr()->SetOutOfMemory();
		DoDeferredUpdateScrollBar();
	}

Exit:
	return fReturn;
}

void CDisplayML::InitVars()
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CDisplayML::InitVars");

	_yScroll = _xScroll = 0;
	_iliFirstVisible = 0;
	_cpFirstVisible = _cpMin = 0;
	_dyFirstVisible = 0;
}

/*
 *	CDisplayML::GetCliVisible(pcpMostVisible)
 *
 *	@mfunc	
 *		Get count of visible lines and update _cpMostVisible for PageDown()
 *
 *	@rdesc
 *		count of visible lines
 */
LONG CDisplayML::GetCliVisible(
	LONG* pcpMostVisible, 				//@parm Returns cpMostVisible
	BOOL fLastCharOfLastVisible) const 	//@parm Want cp of last visible char
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CDisplayML::GetCliVisible");

	LONG cli	 = 0;							// Initialize count
	LONG ili	 = _iliFirstVisible;			// Start with 1st visible line
	LONG yHeight = _dyFirstVisible;
    LONG cp;
	LONG cchWhite = 0;

	for(cp = _cpFirstVisible;
		yHeight < _yHeightView && ili < (LONG)Count();
		cli++, ili++)
	{
		const CLine* pli = Elem

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -