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

📄 disp.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

    RECT rcView, rcClient, rcRender;
	CTxtSelection *psel = _ped->GetSelNC();

    // Get client rect
    if(!prcClient)
    {
        AssertSz(_ped->_fInPlaceActive, 
        	"CDisplay::GetViewRect() - Not in-place and !prcClient");
        _ped->TxGetClientRect(&rcClient);
        prcClient = &rcClient;
    }

	if (NULL == prcWBounds)
	{
		// No metafile, so just set the rendering DC
		if (!SetDC(hdcDraw))
		{
			hr = E_FAIL;
			goto Cleanup;
		}
	}
	else
	{
		// We are rendering to a metafile
		hdcMeasure = _ped->CreateMeasureDC(hdcDraw, prcClient, FALSE, prcWBounds->left, 
			prcWBounds->top, prcWBounds->right, prcWBounds->bottom,
				&xMeasurePerInch, &yMeasurePerInch);
		SetMetafileDC(hdcDraw, hdcMeasure, xMeasurePerInch, yMeasurePerInch);
	}		

	// Compute view rectangle from client rectangle
    Assert(prcClient);
  	GetViewRect(rcView, prcClient);

	// If this view is not active and it is not to be recalc'd then
	// we only decide to use it if the size matches and return S_FALSE
	// if it doesn't so the caller can create a new display to use for
	// drawing.
	if (!IsActive() && !_fNeedRecalc)
	{
		if ((rcView.right - rcView.left != GetViewWidth())
			|| (rcView.bottom - rcView.top != GetViewHeight()))
		{
			hr = S_FALSE;
			goto Cleanup;
		}
	}

	// Make sure our client rectangle is set correctly.
	_yHeightClient = prcClient->bottom - prcClient->top;

    // Recalc view 
    if( !RecalcView(rcView) )
	{
		goto Cleanup;
	}

	if (dwDepthThisDraw != _pdi->GetDrawDepth())
	{
		// A draw happend recursively to this draw. Therefore,
		// the screen has already been rendered so we don't need
		// to do anything more here.
		goto Cleanup;
	}

    // Compute rect to render
    if(!prcUpdate)
    {
        // update full view
        rcRender = *prcClient;
    }
	else 
	{
    	// Clip rendering to the client rect
        if(!IntersectRect(&rcRender, prcClient, prcUpdate))
            goto Cleanup;
    }
    
    if (psel)
	{
        psel->ClearCchPending();
	}

    if (IsMain())
	{
        _ped->TxNotify( EN_UPDATE, NULL );
	}

    // Now render
    Render(rcView, rcRender);

	// Update the cursor if we need to
	if (_fUpdateCaret)
	{
		// The caret only belongs in an active view with
		// a selection on a control that has the focus
		if (IsActive() && (psel != NULL) && _ped->_fFocus)
		{
			// Update the caret if there is a selection object.
			// Note: we only scroll the caret into view, if
			// it was previously in the view. This avoids having
			// window pop to caret if it is resized and the
			// caret is not in the view.
			psel->UpdateCaret(psel->IsCaretInView());
		}

		_fUpdateCaret = FALSE;
	}

Cleanup:

	if (hdcMeasure)
	{
		_ped->TxReleaseMeasureDC(hdcMeasure);
	}

   	// Reset DC in device descriptor
   	ResetDC();

	// Restore fonts to DCs
	if (hFontDraw != NULL)
	{
		SelectObject(hdcDraw, hFontDraw);
	}

	return hr;
}	


//====================================  View Recalc  ===================================
/*
 *	CDisplay::UpdateViewRectState(prcClient)
 *
 *	@mfunc	Compares new view to cached and updates the view as well as the
 *	what type of view recalculation needs to occur.
 */
void CDisplay::UpdateViewRectState(
	const RECT *prcClient)	//@parm New client rectangle
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CDisplay::UpdateViewRectState");

    // Check whether the view rect has changed since last rendering
    // If width has changed, need complete line recalc.
    // If height has changed, recalc all visible and update scrollbars
    if(prcClient->right - prcClient->left != _xWidthView)
    {
        _xWidthView = (SHORT)(prcClient->right - prcClient->left);
        _fViewChanged = TRUE;            
        _fNeedRecalc = TRUE;    // need full recalc
    }

    if(prcClient->bottom - prcClient->top != _yHeightView) 
    {
        _yHeightView = prcClient->bottom - prcClient->top;

		// The height can go negative when there is an inset and
		// the client rect is very small. We just set it to 0 because
		// that is the smallest the view can actually get.
		if (_yHeightView < 0)
		{
			_yHeightView = 0;
		}

        _fViewChanged = TRUE;
    } 
}

/*
 *	CDisplay::ReDrawOnRectChange
 *
 *	@mfunc	Compares new view to cached and updates the display both
 *	internal and visible state appropriately.
 */
void CDisplay::ReDrawOnRectChange( 
	HDC hicTarget,			//@param Target device
	const RECT *prcClient)	//@param New client rectangle
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CDisplay::ReDrawOnRectChange");

	_TEST_INVARIANT_

    RECT rcView;

	// Convert client rect to our view rect
  	GetViewRect(rcView, prcClient);

	// Update the x and y coordinates of the view based on the client rect
	UpdateViewRectState(&rcView);

	if (_fNeedRecalc || _fViewChanged)
	{
		// The client rect changed in some way so lets update our client
		// rect height for zoom.
		_yHeightClient = prcClient->bottom - prcClient->top;

		// Remeasure but don't update scroll bars now.
		RecalcView(FALSE);

		// Forms does not want the screen to reflect what the user clicked on
		// or moved the cursor to so we oblige them by not updating the screen
		// here but waiting for some future action to do so.
	}
}

/*
 *	CDisplay::RecalcView(rcView)
 *
 *	@mfunc
 *		RecalcView after the view rect changed
 *
 *	@rdesc
 *		TRUE if success
 */
BOOL CDisplay::RecalcView (
	const RECT &rcView)
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CDisplay::RecalcView");

	_TEST_INVARIANT_

	// Update the x and y coordinates of the view based on the client rect
	UpdateViewRectState(&rcView);

	// Ensure lines are recalced
	if(_fNeedRecalc)
	{
		// Display got recalculated so the caret needs to be repositioned.
		_fUpdateCaret = TRUE;
    	return RecalcView(TRUE);
	}
	if (_fViewChanged)
	{
		// The scroll bars are up to date so we can turn off the notification.
		_fViewChanged = FALSE;

		// A height change was noticed in UpdateViewRectState so make sure
		// the horizontal scroll bar (if any is correct).
		UpdateScrollBar(SB_HORZ);
	}
    return WaitForRecalcView();
}


//====================================  View Update  ===================================

/*
 *	CDisplay::UpdateView()
 *
 *	Purpose:
 *		Fully recalc all lines and update the visible part of the display 
 *		(the "view") on the screen.
 *
 *	Returns:
 *		TRUE if success
 */
BOOL CDisplay::UpdateView()
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CDisplay::UpdateView");

	_TEST_INVARIANT_

	BOOL fReturn = TRUE;

	if(_fNoUpdateView)
		return TRUE;

	if(!_ped->_fInPlaceActive)
    {
        // If not active, just invalidate everything
        InvalidateRecalc();
        _ped->TxInvalidateRect(NULL, FALSE);
		_ped->TxUpdateWindow();
        return TRUE;
    }

	// If we get here, we are updating some general characteristic of the display
	// and so we want the cursor updated as well as the general change otherwise
	// the cursor will land up in the wrong place.
	_fUpdateCaret = TRUE;

	RECT rcView;

	// Get the view rectangle
  	GetViewRect(rcView, NULL);
	
	// Update the size of the view which could have changed
	UpdateViewRectState(&rcView);

    // From here on we better be in place
    Assert(_ped->_fInPlaceActive);

	if (!CDevDesc::IsValid())
	{
		// Make our device valid
		SetDC(NULL);
	}

    // Recalc everything

#ifdef PWD_JUPITER
    // GuyBark: Watch for RecalcView failing...
    fReturn = 
#endif // PWD_JUPITER
    RecalcView(TRUE);

	// invalidate entire view
	_ped->TxInvalidateRect (NULL, FALSE);
	_ped->TxUpdateWindow();

	// Check if IME has hide the caret.
	// FUTURE: (v-honwch) - This is a work around the problem that
	// _fShowCaret is not being tested in CTxtSelection::Update()
	// as it always displays the caret, messing up IME composition.
	// It is an open issue as to whether Update should be paying
	// attention to the _fShowCaret. It is far too dangerous to
	// change this at this point in the release cycle, so we will
	// examine this in the future.
	{
		if ( _ped->IsIMEComposition() )
		{	
			CTxtSelection *psel;

			psel = _ped->GetSel();
			if ( psel && !psel->IsCaretShown() )
				_ped->TxShowCaret(FALSE);
		}
	}		

	return fReturn;
}



/*
 *	CDisplay::RoundToLine(hdc, pheight)
 *
 *	@mfunc
 *		Calculate number of default lines to fit in input height
 *
 *	@rdesc
 *		S_OK - Call completed successfully <nl>
 */
HRESULT CDisplay::RoundToLine(
	HDC hdc, 			//@parm DC for the window
	LONG width,			//@parm in - width of window; out max width
	LONG *pheight)		//@parm in - proposed height; out - actual
{
	// Set the DC
	SetDC(hdc);

	// Set the height temporarily so the zoom factor will work out
	LONG yOrigHeightClient = SetClientHeight((SHORT) *pheight);

	// Use this to adjust for the inset height
	LONG yAdjForInset = *pheight;

	// Get the rectangle adjusted for insets
	GetViewDim(width, *pheight);

	// Save the proposed height
	LONG yProposed = *pheight;

	// Calc inset adjusted height
	yAdjForInset -= yProposed;

	// Get the font
	const CCharFormat *pcf = _ped->GetCharFormat(-1);

    if (NULL == pcf)
    {
	    Assert(pcf);
	    return E_OUTOFMEMORY;
    }
    
	// Get the font cache object
	CCcs *pccs = fc().GetCcs(hdc, pcf, GetZoomNumerator(),
		GetZoomDenominator(), GetDeviceCaps(hdc, LOGPIXELSY));
 
	// Get the height of the font
	LONG yHeight = pccs->_yHeight;

	// All we wanted is the height and we have got it so dump the
	// font cache entry
	pccs->Release();

	// Figure out how many lines fit into the input height
	LONG cLines = yProposed / yHeight;

	// See if we need to round up
	if ((yProposed % yHeight != 0) || (0 == cLines))
	{
		cLines++;
	}

	// Set the height to the new value
	*pheight = yHeight * cLines + yAdjForInset;

	// Set the client height back to what it was
	SetClientHeight(yOrigHeightClient);

	// Reset the DC
	ResetDC();

	return NOERROR;
}


//=============================  Client and view rectangles  ===========================


/*
 * 	CDisplay::OnClientRectChange(&rcClient, &rcView)
 *
 *	Purpose:
 *		Update when either the client rectangle changes
 *      >>> Should be called only when in-place active <<<
 *  
 *  Arguments:
 *      rcClient    new client rectangle
 */
void CDisplay::OnClientRectChange(const RECT &rcClient)
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CDisplay::OnClientRectChange");

	_TEST_INVARIANT_

    RECT rcView;
    
	AssertSz(_ped->_fInPlaceActive, "CDisplay::OnClientRectChange() called when not in-place active");

	// Make sure our client rectangle is set correctly.
	_yHeightClient = rcClient.bottom - rcClient.top;

    // Use the view rect change notification
	GetViewRect(rcView);

	// Make sure that we will have a selection object at this point
	_ped->GetSel();

 	// Update when the view rectangle changes
	OnViewRectChange(rcView);
}

/*
 * 	CDisplay::OnViewRectChange(&rcView)
 *
 *	Purpose:
 *		Update when either the view rectangle changes
 *  
 *  Arguments:
 *      rcView   new view rectangle, in:
 *               - log units (twips) rel. to top/left of client rect if not in-place
 *               - containing window client coords if in-place active
 */
VOID CDisplay::OnViewRectChange(const RECT &rcView)
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CDisplay::OnViewRectChange");

	_TEST_INVARIANT_

    if(!_ped->_fInPlaceActive)
        // We'll adjust the view rect during next Draw.
        return;

	CTxtSelection *psel = _ped->GetSelNC();
	const BOOL fCaretShowing = psel ? psel->ShowCaret(FALSE) : FALSE;
	const BOOL fCaretInView = fCaretShowing ? psel->IsCaretInView() : FALSE;
    RECT rcV = rcView;
	COleObject *pipo;

	// Factor in selection bar space
	rcV.left += GetSelBarInPixels();

	// Recalc with new view rectangle
    // ??? What if this fails ?
    RecalcView(rcView);
	
	// Repaint window before showing the caret
    _ped->TxInvalidateRect(NULL, FALSE);  // ??? for now, we could be smarter 
	_ped->TxUpdateWindow();

	// Reposition the caret
	if(fCaretShowing)
	{
	    Assert(psel);
		psel->ShowCaret(TRUE);
		psel->UpdateCaret(fCaretInView);
	}

	// FUTURE: since we're now repositioning in place active 
	// objects every time we draw, this call seems to be 
	// superfluous (AndreiB)

	// Tell object subsystem to reposition any in place objects
	if( _ped->HasObjects() )
	{
		pipo = _ped->GetObjectMgr()->GetInPlaceActiveObject();
		if (NULL != pipo)
		{
			pipo->OnReposition( 0, 0 );
		}
	}
}

/*
 * 	CDisplay::RequestResize()
 *
 *	Purpose:
 *		Forces the control to resize vertically so that all text fit into it
 */
HRESULT CDisplay::RequestResize()
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CDisplay::RequestResize");

	_TEST_INVARIANT_

	if (_ped->TxGetAutoSize())
	{
		REQRESIZE resize;

		// if word wrapping is on, then the width is the normal
		// client width.  Otherwise, it's the width of the longest
		// line plus the width of the caret.

⌨️ 快捷键说明

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