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

📄 edit.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	if( ((mode & (TM_RICHTEXT | TM_PLAINTEXT)) == 
			(TM_RICHTEXT | TM_PLAINTEXT)) ||
		((mode & (TM_SINGLELEVELUNDO | TM_MULTILEVELUNDO)) ==
			(TM_SINGLELEVELUNDO | TM_MULTILEVELUNDO) ) ||
		((mode & (TM_SINGLECODEPAGE | TM_MULTICODEPAGE)) ==
			(TM_SINGLECODEPAGE | TM_MULTICODEPAGE)) )
	{
		lres = E_INVALIDARG;
	}
	else if( (mode & TM_PLAINTEXT) && IsRich())
	{
		lres = OnRichEditChange(FALSE);
	}
	else if( (mode & TM_RICHTEXT) && !IsRich())
	{
		lres = OnRichEditChange(TRUE);
	}

	if( lres == 0 )
	{
		if( (mode & TM_SINGLELEVELUNDO) )
		{
			if( !_pundo )
			{
				CreateUndoMgr(1, US_UNDO);
			}

			if( _pundo )
			{
				// we can 'Enable' single level mode as many times
				// as we want, so no need to check for it before hand.
				lres = ((CUndoStack *)_pundo)->EnableSingleLevelMode();
			}
			else
			{
				lres = E_OUTOFMEMORY;
			}
		}
		else if( (mode & TM_MULTILEVELUNDO) )
		{
			// if there's no undo stack, no need to do anything,
			// we're already in multi-level mode
			if( _pundo && ((CUndoStack *)_pundo)->GetSingleLevelMode())
			{
				((CUndoStack *)_pundo)->DisableSingleLevelMode();
			}
		}

		if( (mode & TM_SINGLECODEPAGE) )
		{
			_fSingleCodePage = TRUE;
		}
		else if( (mode & TM_MULTICODEPAGE) )
		{
			_fSingleCodePage = FALSE;
		}
	}

	// We don't want this marked modified after this operation to make us
	// work better in dialog boxes.
	_fModified = FALSE;

	return lres;
}

////////////////////////// Notification Manager //////////////////////////////

/*
 *	CTxtEdit::GetNotifyMgr()
 *
 *	@mfunc
 *		returns a pointer to the notification manager (creating it if necessary)
 *
 *	@rdesc
 *		Ptr to notification manager
 */
CNotifyMgr *CTxtEdit::GetNotifyMgr()
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::GetNotifyMgr");

	return &_nm;
}


////////////////////////// Object Manager ///////////////////////////////////

/*
 *	CTxtEdit::GetObjectMgr()
 *
 *	@mfunc
 *		returns a pointer to the object manager (creating if necessary )
 *
 *	@rdesc
 *		pointer to the object manager
 */
CObjectMgr *CTxtEdit::GetObjectMgr()
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::GetObjectMgr");

	if( !_pobjmgr )
	{
		_pobjmgr = new CObjectMgr();
	}

	return _pobjmgr;
}


////////////////////////////// Properties - Selection ////////////////////////////////


LONG CTxtEdit::GetSelMin() const
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::GetSelMin");

	return _psel ? _psel->GetCpMin() : 0;
}

LONG CTxtEdit::GetSelMost() const
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::GetSelMost");

	return _psel ? _psel->GetCpMost() : 0;
}

		
////////////////////////////// Properties - Text //////////////////////////////////////


LONG CTxtEdit::GetTextRange(LONG cpFirst, LONG cch, TCHAR *pch)
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::GetTextRange");

#ifdef DEBUG
	const LONG cchAsk = cch;
#endif
	CTxtPtr	tp(this, cpFirst);
	LONG	length = (LONG)GetAdjustedTextLength();

	if(--cch < 0 || cpFirst > length)
		return 0;

	cch = min(cch, length - cpFirst);

	if(cch > 0)
	{
		cch = tp.GetText(cch, pch);
		Assert(cch >= 0);
	}
	pch[cch] = TEXT('\0');

#ifdef DEBUG
	if(cch != cchAsk - 1)
		Tracef(TRCSEVINFO, "CmdGetText(): only got %ld out of %ld", cch, cchAsk - 1);
#endif

	return cch;
}

/*
 *	CTxtEdit::GetTextEx
 *
 *	@mfunc	grabs text according to various params
 *
 *	@rdesc	the number of bytes written
 */
LONG CTxtEdit::GetTextEx(
	GETTEXTEX *pgt,		//@parm info on what to get
	TCHAR *pch)			//@parm where to put the text
{
	CTxtPtr tp(this, 0);
	CTempWcharBuf twcb;
	TCHAR *pchUse = pch;
	LONG cch, cb;
	LONG cchGet = GetAdjustedTextLength();


	// allocate a big buffer; make sure that we have
	// enough room for lots of CRLFs if necessary
	if( (pgt->flags & GT_USECRLF) )
	{
		cchGet *= 2;
	}

	if( pgt->codepage != 1200 )
	{
		// if UNICODE, copy straight to clients buffer;
		// else, copy to temp buffer and translate cases first
		pchUse = twcb.GetBuf(cchGet + 1);
	}
	else
	{
		// be sure to leave room for the NULL terminator.
		cchGet = min(((pgt->cb/2) -1), (DWORD)cchGet);
	}

	// now grab the text.  
	
	if( (pgt->flags & GT_USECRLF) )
	{
		cch = tp.GetPlainText(cchGet, pchUse, tomForward, FALSE);
	}
	else
	{
		cch = tp.GetText(cchGet, pchUse);
	}

	pchUse[cch] = L'\0';

	// if we're just doing UNICODE, return the number of chars written.
	if( pgt->codepage == 1200 )
	{
		return cch;
	}

	// oops, gotta translate to ANSI.

	cb = WideCharToMultiByte(pgt->codepage, 0, pchUse, cch + 1, (char *)pch, 
			pgt->cb, pgt->lpDefaultChar, pgt->lpUsedDefChar);

	// don't count the NULL terminator for compatibility with WM_GETTEXT.
	return (cb) ? cb - 1 : 0;
}
			
/*
 *	CTxtEdit::GetTextLengthEx
 *
 *	@mfunc	calculates the length of the text in various ways.
 *
 *	@rdesc	varies by the input parameter
 */
LONG CTxtEdit::GetTextLengthEx(
	GETTEXTLENGTHEX *pgtl)	//@parm info describing how to calculate the
							// length
{
	LONG cchUnicode = GetAdjustedTextLength();
	GETTEXTEX gt;

	// make sure the flags are definied appropriately.
	if( ((pgtl->flags & GTL_CLOSE) && (pgtl->flags & GTL_PRECISE)) ||
		((pgtl->flags & GTL_NUMCHARS) && (pgtl->flags & GTL_NUMBYTES)) )
	{
		TRACEWARNSZ("Invalid flags for EM_GETTEXTLENGTHEX");
		return E_INVALIDARG;
	}

	if( (pgtl->flags & GTL_USECRLF) )
	{
		CTxtPtr tp(this, 0);
		DWORD numEOP = 0;
		
		while( tp.FindEOP(tomForward) )
		{
			numEOP++;
		}

		// take of the default EOD, if it exists.  Note
		// that in plain text, we may _think_ that there is
		// an EOP at the end when there really isn't.
		if( IsRich() || (numEOP && !tp.IsAfterEOP()))
		{
			Assert(numEOP);
			numEOP--;
		}

		cchUnicode += numEOP;
	}

	// if we're just looking for the number of characters, we've got it.
	if( (pgtl->flags & GTL_NUMCHARS) || !pgtl->flags )
	{
		return cchUnicode;
	}

	// hmm, they're looking for number of bytes, but don't care about 
	// precision, just multiply by two.  If neither PRECISE or CLOSE is
	// specified, default to CLOSE.
	// Note if we're UNICODE and asking for number of bytes, we also
	// just multiply by 2.
	if( (pgtl->flags & GTL_CLOSE) || !(pgtl->flags & GTL_PRECISE) ||
		pgtl->codepage == 1200 )
	{
		return cchUnicode *2;
	}

	// in order to get a precise answer, we're going to need to convert.
	gt.cb = 0;
	gt.flags = (pgtl->flags & GT_USECRLF);
	gt.codepage = pgtl->codepage;
	gt.lpDefaultChar = NULL;
	gt.lpUsedDefChar = NULL;

	return GetTextEx(&gt, NULL);
}


//////////////////////////////  Properties - Formats  //////////////////////////////////

const CCharFormat* CTxtEdit::GetCharFormat(LONG iCF)
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::GetCharFormat");

	const CCharFormat *	pCF;
	ICharFormatCache  *	pICache;
	
	if(iCF < 0)
		iCF = _iCF;

	Assert(iCF >= 0);

	if (FAILED(GetCharFormatCache(&pICache)) ||
		FAILED(pICache->Deref(iCF, &pCF)))
	{
		AssertSz(FALSE, "CTxtEdit::GetCharFormat: couldn't deref iCF");
		pCF = NULL;
	}
	return pCF;
}

const CParaFormat* CTxtEdit::GetParaFormat(LONG iPF)
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::GetParaFormat");

	IParaFormatCache  *	pICache;
	const CParaFormat *	pPF;
	
	if(iPF < 0)
		iPF = _iPF;

	Assert(iPF >= 0);

	if (FAILED(GetParaFormatCache(&pICache)) ||
		FAILED(pICache->Deref(iPF, &pPF)))
	{
		AssertSz(FALSE, "CTxtEdit::GetParaFormat: couldn't deref iPF");
		pPF = NULL;
	}
	return pPF;
}

/*
 *	CTxtEdit::HandleStyle (pCFTarget, pCF)
 *
 *	@mfunc
 *		If pCF specifies a style choice, initialize pCFTarget with the
 *		appropriate style, apply pCF, and return NOERROR.  Else return
 *		S_FALSE or an error
 *
 *	@rdesc
 *		HRESULT = (pCF specifies a style choice) ? NOERROR : S_FALSE or error code
 */
HRESULT CTxtEdit::HandleStyle(
	CCharFormat *pCFTarget,		//@parm Target CF to receive CF style content
	const CCharFormat *pCF)		//@parm Source CF that may specify a style
{
	if(pCF->fSetStyle())
	{
		// FUTURE: generalize to use client style if specified
		pCFTarget->Set(GetCharFormat(-1));
		pCFTarget->cbSize = sizeof(CHARFORMAT2);
		pCFTarget->ApplyDefaultStyle(pCF->sStyle);
		return pCFTarget->Apply(pCF, fInOurHost());
	}
	return S_FALSE;
}

/*
 *	CTxtEdit::HandleStyle (pPFTarget, pPF)
 *
 *	@mfunc
 *		If pPF specifies a style choice, initialize pPFTarget with the
 *		appropriate style, apply pPF, and return NOERROR.  Else return
 *		S_FALSE or an error
 *
 *	@rdesc
 *		HRESULT = (pPF specifies a style choice) ? NOERROR : S_FALSE or error code
 */
HRESULT CTxtEdit::HandleStyle(
	CParaFormat *pPFTarget,		//@parm Target PF to receive PF style content
	const CParaFormat *pPF)		//@parm Source PF that may specify a style
{
	if(pPF->fSetStyle())
	{
		// FUTURE: generalize to use client style if specified
		pPFTarget->Set(GetParaFormat(-1));
		pPFTarget->cbSize = sizeof(PARAFORMAT2);
		pPFTarget->ApplyDefaultStyle(pPF->sStyle);
		return pPFTarget->Apply(pPF);
	}
	return S_FALSE;
}

//////////////////////////// Mouse Commands /////////////////////////////////


HRESULT CTxtEdit::OnTxLButtonDblClk(
	INT x,
	INT y,
#ifdef PWD_JUPITER // GuyBark 81387: Allow undo of expand/collapse operation
	DWORD dwFlags, IUndoBuilder *publdr)
#else
	DWORD dwFlags)
#endif // PWD_JUPITER
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::OnTxLButtonDblClk");

	BOOL			fEnterParaSelMode = FALSE;
	HITTEST			Hit;
	CTxtSelection *	psel = GetSel();
	const POINT		pt = {x, y};

	AssertSz(psel, "CTxtEdit::OnLeftDblClick() - No selection object !");

	_dwTickDblClick = GetTickCount();
	_ptDblClick.x = x;
	_ptDblClick.y = y;

	TxUpdateWindow();		// Repaint window to show any exposed portions

	if(!_fFocus)
	{
		TxSetFocus();					// Create and display caret
		return S_OK;
	}

	// Find out what the cursor is pointing at
	_pdp->CpFromPoint(pt, NULL, NULL, NULL, FALSE, &Hit); 

	if(Hit == HT_Nothing)
		return S_OK;

	if(Hit == HT_OutlineSymbol)
	{
		CTxtRange rg(*psel);
#ifdef PWD_JUPITER // GuyBark 81387: Allow undo of expand/collapse operation
		rg.ExpandOutline(0, FALSE, publdr);
#else
		rg.ExpandOutline(0, FALSE);
#endif // PWD_JUPITER 
		return S_OK;
	}

	if(Hit == HT_SelectionBar || Hit == HT_LeftOfText)
		fEnterParaSelMode = TRUE;

	_fWantDrag = FALSE;					// just to be safe

	// if we are over a link, let the client have a chance to process
	// the message
	if(Hit == HT_Link && HandleLinkNotification(WM_LBUTTONDBLCLK, (WPARAM)dwFlags, 
			MAKELPARAM(x, y)) )
	{
		return S_OK;
	}

	if(dwFlags & MK_CONTROL)
		return S_OK;

	// Mark mouse down
	_fMouseDown = TRUE;

	if( _pobjmgr )
	{
		if( _pobjmgr->HandleDoubleClick(this, pt, dwFlags) == TRUE )
		{
			// the object subsystem handled everything
			_fMouseDown = FALSE;
			return S_OK;
		}
	}

	// Now update the selection
	if(fEnterParaSelMode)
		psel->SelectUnit(pt, tomParagraph);
	else
		psel->SelectWord(pt);

	return S_OK;
}

HRESULT CTxtEdit::OnTxLButtonDown(
	INT x,
	INT y,
	DWORD dwFlags)
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::OnTxLButtonDown");

	BOOL		fEnterLineSelMode = FALSE;
	BOOL		fShift = dwFlags & MK_SHIFT;
	HITTEST		Hit;
	const POINT pt = {x, y};
	COleObject *pobj;
	BOOL		fMustThaw = FALSE;

	const BOOL fTripleClick = GetTickCount() < _dwTickDblClick + sysparam.GetDCT() &&
				abs(x - _ptDblClick.x) <= sysparam.GetCxDoubleClk() &&
				abs(y - _ptDblClick.y) <= sysparam.GetCyDoubleClk();
	
	// Terminate composition for Korea
	if(IsIMEComposition())
		if(_ime->IsKoreanMode())
			_ime->TerminateIMEComposition(*this, CIme::TERMINATE_NORMAL );

	// If click isn't inside view, just activate, don't select

	if(!_fFocus)					// Sets focus if not already
	{
		// We may be removing an existing selection, so freeze
		// the display to avoid flicker
		_pdp->Freeze();
		fMustThaw = TRUE;
		TxSetFocus();				// creates and displays caret
	}

	// Grab selection object
	CTxtSelection * const psel = GetSel();
	AssertSz(psel,"CTxtEdit::OnLeftUp() - No selection object !");

	// Find out what the cursor is pointing at
	_pdp->CpFromPoint(pt, NULL, NULL, NULL, FALSE, &Hit); 

	if(Hit == HT_SelectionBar || Hit == HT_LeftOfText)
	{
		// shift click in sel bar treated as normal click
		if(!fShift)
		{
			// control selbar click and triple selbar click
			// are select all
			if((dwFlags & MK_CONTROL) || fTripleClick)
			{
				psel->SelectAll();
				goto cancel_modes;
			}
			fEnterLineSelMode = TRUE;

⌨️ 快捷键说明

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