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

📄 disp.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	COLORREF crBackground = _ped->TxGetBackColor();
	COffScreenDC osdc;

	//
	// Render the view to a memory DC
	//
	
	// Compute the zero based client rectangle
	rcClient.left = 0;
	rcClient.top = 0;
	rcClient.right = prcClient->right - prcClient->left;
	rcClient.bottom = prcClient->bottom - prcClient->top;

	// Create a memory DC
	hdcMem = osdc.Init(hdc, rcClient.right, rcClient.bottom, crBackground);

	if (NULL == hdcMem)
	{
		goto Cleanup;
	}

	// Initialize the display
	osdc.FillBitmap(rcClient.bottom, crBackground);

	// Set the DC to the memory DC
	SetDC(hdcMem);

	// Get the view rectangle that we need for rendering
  	GetViewRect(rcView, &rcClient);

	// Adjust point to be relative to the memory display
	pt.x -= prcClient->left;
	pt.y -= prcClient->top;

	// Initalize box around point. Note that we only really need to render
	// the data inside this box because this is the only area that we will
	// test.
	rcRender.top = pt.y - HIT_CLOSE_RECT_INC;

	if (rcRender.top < 0)
	{
		rcRender.top = 0;
	}

	rcRender.bottom = pt.y + HIT_CLOSE_RECT_INC;

	if (rcRender.bottom > rcClient.bottom)
	{
		rcRender.bottom = rcClient.bottom;	
	}

	rcRender.left = pt.x - HIT_CLOSE_RECT_INC;

	if (rcRender.left < 0)
	{
		rcRender.left = 0;
	}

	rcRender.right = pt.x + HIT_CLOSE_RECT_INC;

	if (rcRender.right > rcClient.right)
	{
		rcRender.right = rcClient.right;
	}

    // Now render
    Render(rcView, rcRender);

	//
	// Hit test
	//

	// Assume no hit
	*pHitResult = TXTHITRESULT_TRANSPARENT;

	// At this point we won't fail this
	hr = S_OK;

	// Is there an exact hit?
	if (GetPixel(hdcMem, pt.x, pt.y) != crBackground)
	{
		*pHitResult = TXTHITRESULT_HIT;
		goto Cleanup;
	}

	// Is it close? We determine closeness by putting
	// a 10 x 10 pixel box around the hit point and 
	// seeing if there is a hit there.


	// Loop examining each bit in the box to see if it is on.
	for (iRow = rcRender.top; iRow <= rcRender.bottom; iRow++)
	{
		for (int iCol = rcRender.left; iCol <= rcRender.right; iCol++)
		{
			if (GetPixel(hdcMem, iCol, iRow) != crBackground)
			{
				*pHitResult = TXTHITRESULT_CLOSE;
				goto Cleanup;
			}
		}
	}

Cleanup:

	ResetDC();

	return hr;
}

//=============================== ITxNotify Interface ===============================
/*
 *	CDisplay::OnPreReplaceRange
 *
 *	@mfunc
 *		Preprocess a change in backing store
 *
 *	@rdesc
 *		void
 *
 *	@devnote
 *		This display doesn't care about before changes
 */
void CDisplay::OnPreReplaceRange( 
	DWORD cp, 
	DWORD cchDel, 
	DWORD cchNew,
	DWORD cpFormatMin, DWORD cpFormatMax)
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CDisplay::OnPreReplaceRange");

	// Display doesn't care about before the fact
}

/*
 *	CDisplay::OnPostReplaceRange()
 *
 *	@mfunc
 *		Process a change to the backing store as it applies to the display
 *
 *	@rdesc
 *		void
 *
 */
void CDisplay::OnPostReplaceRange( 
	DWORD cp, 
	DWORD cchDel, 
	DWORD cchNew,
	DWORD cpFormatMin, 
	DWORD cpFormatMax)
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CDisplay::OnPostReplaceRange");

	// There is one NO-OP's for the display:
	// currently loading a file.
	//
	// We NO-OP the load case because loading an RTF file can consist
	// of potentially very many small actions as we peice together
	// the various bits of formatted text.  Once done, the load code
	// will go through and do an update-all to the display.
	Assert (cp != CONVERT_TO_PLAIN);			// Handled with PreReplace notifications

	// Figure out the range needed to update
	DWORD cpNew = min(cp, cpFormatMin);

	if (INFINITE == cpNew)
	{
		// If both cp's are infinite we don't need to bother with
		// this operation.
		return;
	}


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

	// Adjust cp for further calculations
	if (INFINITE == cp)
	{
		cp = 0;
	}

	// find the new max end of the original region.
	DWORD	cpForEnd = max( (cp + cchDel), cpFormatMax);

	// Number of deleted characters is the difference between the previous two
	DWORD cchDelForDisplay = cpForEnd - cpNew;

	// The number deleted is simply number of new characters adjusted by
	// the change in the number of characters.
	DWORD cchNewForDisplay = cchDelForDisplay + (cchNew - cchDel);

	if (_padc != NULL)
	{
		// Display is frozen so accumulate the change instead of actually
		// displaying it on the screen.
		_padc->UpdateRecalcRegion(cpNew, cchDelForDisplay, cchNewForDisplay);
		return;
	}		

	// tell the display to update
	CRchTxtPtr tp(_ped, cpNew);

	UpdateView(tp, cchDelForDisplay, cchNewForDisplay);
}


/*
 *	CDisplay::SetWordWrap()
 *
 *	@mfunc
 *		Sets the no wrap flag
 *
 *	@rdesc
 *		void
 *
 *	@devnote
 *		We will always allow the property to be set but we will not
 *		necessarily pay attention. In other words, word wrap has no
 *		effect on a single line edit control.
 */
void CDisplay::SetWordWrap(
	BOOL fWordWrap		//@param TRUE - turn on word wrap.
)
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CDisplay::SetWordWrap");

	AssertSz((fWordWrap == TRUE) ||	(fWordWrap == FALSE),
		"CDisplay::SetWordWrap bad input flag");

	// Set nowrap to whatever is comming in.
	_fWordWrap = fWordWrap;
}



/*
 *	CDisplay::GetWordWrap()
 *
 *	@mfunc
 *		Return the state of word wrap property
 *
 *	@rdesc
 *		TRUE - word wrap is on
 *		FALSE - word wrap is is off.
 *
 *	@devnote
 *		Derived classes such as CDisplaySL override this.
 */
BOOL CDisplay::GetWordWrap() const
{
	TRACEBEGIN(TRCSUBSYSDISP, TRCSCOPEINTERN, "CDisplay::GetWordWrap");

	return _fWordWrap;
}

/*
 *	CDisplay::GetViewDim()
 *
 *	@mfunc
 *		Return the height & width of view adjusted for view inset
 *
 *	@rdesc
 *		VOID
 *
 */
void CDisplay::GetViewDim(
	LONG& widthView,		//@parm Where to return the width
	LONG& heightView		//@parm Where to return the height
)
{
	// We build a client rectangle to take advantage of GetViewRect routine
	// which really does all the work for us.
	RECT rcClient;
	rcClient.left = 0;
	rcClient.top = 0;
	rcClient.right = widthView;
	rcClient.bottom = heightView;

	// Take into account inset and selection bar. The parameters here are a bit
	// of a trick. The second parameter gets copied into the first and since
	// we don't need the orignal client rect we save a rect off the stack.
	GetViewRect(rcClient, &rcClient);

	widthView = rcClient.right - rcClient.left;
	heightView = rcClient.bottom - rcClient.top;
 }


/*
 *	CDisplay::ModeOffsetIntoChar
 *
 *	@mfunc
 *		Calculates offset into character for given mode of TA_CENTER
 *		or TA_RIGHT.
 *
 *	@rdesc
 *		Offset appropriate for the mode.
 *
 */
LONG CDisplay::ModeOffsetIntoChar(
	LONG taMode,			//@parm Requested mode
	const CRchTxtPtr& tp)	//@parm text pointer to the character
{
	AssertSz(taMode & TA_CENTER, 
		"CDisplay::ModeOffsetIntoChar called with invalid mode");

	// Measure the single character
	CMeasurer me(this, tp);

	// And measure from there to where we are
	me.NewLine(FALSE);

	// Measure the character at the current cp
	LONG xCharWidth = me.MeasureText(1);

	if ((taMode & TA_CENTER) == TA_CENTER)
	{
		// Return offset to the middle of the character
		xCharWidth >>= 1;
	}

	return xCharWidth;
}


/*
 *	CDisplay::SaveUpdateCaret
 *
 *	@mfunc	Save UpdateCaret parameter so update caret can be called
 *			after the display is thawed.
 *
 *	@rdesc	None.
 *
 *	@devnote
 *			This should only be called if IsFrozen is true.
 *
 */
void CDisplay::SaveUpdateCaret(
	BOOL fScrollIntoView)
{
#ifdef DEBUG
	if (_padc == NULL)
	{
		TRACEERRORSZ("CDisplay::SaveUpdateCaret called on thawed display");
	}
#endif // DEBUG
	if (_padc != NULL)
	{
		_padc->SaveUpdateCaret(fScrollIntoView);
	}
}





/*
 *	CDisplay::Freeze
 *
 *	@mfunc
 *		Prevent any updates from occuring in the display
 *
 *	@rdesc
 *		None
 *
 */
void CDisplay::Freeze()
{
	if (NULL == _padc)
	{
		// Allocate object to keep track of changes
		_padc = new CAccumDisplayChanges();

		// We can now return because the accum object has a reference
		// or the memory allocation failed. If the memory allocation 
		// failed, This really isn't a catastrophe because all it means 
		// is that things will get displayed ugly temporarily, so we can 
		// pretend it didn't happen.
		return;
	}

	// Tell the object that that an additional freeze has occurred.
	_padc->AddRef();

}

/*
 *	CDisplay::Thaw
 *
 *	@mfunc
 *		If this is the last thaw, then cause display to be updated.
 *
 *	@rdesc
 *		None
 *
 */
void CDisplay::Thaw()
{
	DWORD cp;
	DWORD cchNew;
	DWORD cchDel;
	BOOL fUpdateCaret;
	CTxtSelection *psel;
	BOOL fScrollIntoView;

	if (_padc != NULL)
	{
		// Release the reference to the accum object
		if (_padc->Release() == 0)
		{
			// Last thaw so we need to update display

			// Get the changes
			_padc->GetUpdateRegion(&cp, &cchDel, &cchNew, 
				&fUpdateCaret, &fScrollIntoView);

			// Clear the object - note we do this before
			// the update just on the off chance that
			// a new freeze manages to get in during the 
			// update of the display.
			delete _padc;
			_padc = NULL;

			if( cp != INFINITE )
			{
				// Display changed
				if (!_ped->fInplaceActive())
				{
					// Are not inplace active so we need to put this operation
					// off till a more appropriate time.

					InvalidateRecalc();
					_ped->TxInvalidateRect(NULL, FALSE);
					_ped->TxUpdateWindow();
					return;
				}
				// Update the display
				CRchTxtPtr rtp(_ped, cp);
				if(!UpdateView(rtp, cchDel, cchNew))
					return;							// Update failed
			}

			// Did the selection request a caret update?
			if (fUpdateCaret && _ped->fInplaceActive())
			{
				if (psel = _ped->GetSel())
				{
			        psel->UpdateCaret(fScrollIntoView);
			    }
			    else
			    {
				    Assert(psel);

		        }
			}
		}
	}
}


/*
 *	CDisplay::IsPrinter
 *
 *	@mfunc
 *		Returns whether this is a printer
 *
 *	@rdesc
 *		TRUE - is a display to a printer
 *		FALSE - is not a display to a printer
 *
 *	@devnote
 *		No display except a display	CDisplayPrinter should
 *		ever have a chance to return TRUE to this function.
 *
 */
BOOL CDisplay::IsPrinter() const
{
	return FALSE;
}

/*
 *	CDisplay::Zombie ()
 *
 *	@mfunc
 *		Turn this object into a zombie
 */
void CDisplay::Zombie ()
{
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "CDisplay::Zombie");

}

/*
 *	CDisplay::IsHScrollEnabled ()
 *
 *	@mfunc
 *		Return whether horizontal scroll bar is enabled
 *
 *	@rdesc
 *		TRUE - yes
 *		FALSE - no
 *
 *	@devnote
 *		The reason for this routine is that _fHScrollEnabled means
 *		to scroll text and can be set even if there is no scroll
 *		bar. Therefore, we need to look at the host properties
 *		as well to tell use whether this means there are scroll
 *		bars.
 */
BOOL CDisplay::IsHScrollEnabled()	  
{
	return _fHScrollEnabled && ((_ped->TxGetScrollBars() & WS_HSCROLL) != 0);
}


⌨️ 快捷键说明

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