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

📄 edit.cpp

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

	if (GetKeyState(VK_SHIFT) & 0x8000)
		iKeyState |= SHFT_ON;
	if (HIWORD(dwFlags) & KF_ALTDOWN)
		iKeyState |= ALT_ON;
	if (GetKeyState(VK_CONTROL) & 0x8000)
		iKeyState |= CTL_ON;

	CTxtSelection * const psel = GetSel();
	AssertSz(psel,"CTxtEdit::OnTxOutlineKeyDown() - No selection object !");
	CTxtRange rg(*psel);

	if ((iKeyState & (ALT_ON | CTL_ON)) == (ALT_ON | CTL_ON))
	{
		switch(vkey)
		{
		case 'N':				// Alt-Ctrl-N => Normal View
			SetViewKind(VM_NORMAL);
			break;	
		case 'O':				// Alt-Ctrl-O => Outline View
			SetViewKind(VM_OUTLINE);
			break;
		default :
			hr = S_FALSE;
			break;
		}
	}
	else if ((iKeyState & (ALT_ON | SHFT_ON)) == (ALT_ON | SHFT_ON))
	{
		switch(vkey)
		{
		case VK_LEFT:								// Left arrow
		case VK_RIGHT:								// Right arrow
			hr = rg.Promote(vkey == VK_LEFT ? 1 : -1, publdr);
			psel->Update_iFormat(-1);
			psel->Update(FALSE);
			break;

		case VK_UP:									// Up arrow
		case VK_DOWN:								// Down arrow
			hr = MoveSelection(vkey == VK_UP ? -1 : 1, publdr);
			psel->Update(TRUE);
			break;

		case VK_ADD:
		case VK_SUBTRACT:
			level = vkey == VK_ADD ? 1 : -1;
			fWholeDoc = FALSE;
			/* Fall through */
		case 'A':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			if (!level)
				level = vkey == 'A' ? 9 : vkey - '0';
#ifdef PWD_JUPITER // GuyBark 81387: Allow undo of expand/collapse operation
			hr = rg.ExpandOutline(level, fWholeDoc, publdr);
#else
			hr = rg.ExpandOutline(level, fWholeDoc);
#endif // PWD_JUPITER
			break;
		default :
			hr = S_FALSE;
		}
	}
	else if ((iKeyState & (SHFT_ON | CTL_ON)) == (SHFT_ON | CTL_ON))
	{
		if (vkey == 'N')					// Demote to Body
			hr = rg.Promote(0, publdr);
		else if (vkey == 'L')				// Fiddle bullet style
		{
			CParaFormat PF;					//  view, use Normal style
			psel->GetParaFormat(&PF);
			PF.dwMask = PFM_NUMBERING;
			PF.wNumbering++;
			PF.wNumbering %= tomListNumberAsUCRoman + 1;
			if (PF.wNumbering)
			{
				PF.dwMask |= PFM_NUMBERINGSTYLE | PFM_NUMBERINGSTART;
				PF.wNumberingStyle = PFNS_PERIOD;
				PF.wNumberingStart = 1;
			}
			hr = psel->SetParaFormat(&PF, publdr);
		}
		else
			hr = S_FALSE;

		if (hr != S_FALSE)
		{
			psel->Update_iFormat(-1);
			psel->Update(FALSE);
		}
	}
	else
		hr = S_FALSE;

	return hr;
}				

/*
 *	CTxtEdit::OnTxChar (vkey, dwFlags, publdr)
 *
 *	@mfunc
 *		Handle WM_CHAR message
 *
 *	@rdesc
 *		HRESULT with the following values:
 *
 *		S_OK				if key was understood and consumed
 *		S_MSG_KEY_IGNORED	if key was understood, but not consumed
 *		S_FALSE				if key was not understood (and not consumed)
 */
HRESULT CTxtEdit::OnTxChar(
	WORD		  vkey,		//@parm Translated key code
	DWORD		  dwFlags,	//@parm lparam of WM_KEYDOWN msg
	IUndoBuilder *publdr)	//@parm Undobuilder to receive antievents
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::OnTxChar");

	if (_fMouseDown || vkey == VK_ESCAPE ||	// Ctrl-Backspace generates VK_F16
		vkey == VK_BACK || vkey==VK_F16)	// Eat it since we process it
	{										//  in WM_KEYDOWN
		return S_OK;
	}

	CTxtSelection * const psel = GetSel();
	AssertSz(psel,
		"CTxtEdit::OnChar() - No selection object !");
	psel->SetExtend(FALSE);					// Shift doesn't mean extend for
											//  WM_CHAR
	if(_fReadOnly && vkey != 3)				// Don't allow input if read only,
	{										//  but allow copy (Ctrl-C)
		if(vkey >= ' ')
			Sound();
		return S_MSG_KEY_IGNORED;
	}

	if(vkey >= ' ' || vkey == VK_TAB)
	{
		SetCursor(0);

		if(IsntProtectedOrReadOnly(WM_CHAR, vkey, dwFlags))
		{
			LONG nDeadKey = _bDeadKey;
			if(nDeadKey)
			{
				LONG ch		  = vkey | 0x20;		// Convert to lower case
				BOOL fShift	  = vkey != ch;			//  (if ASCII letter)
				//					a	b	 c	 d	  e	  f  g  h    i	 j
				static chOff[] = {0xDF, 0, 0xE7, 0, 0xE7, 0, 0, 0, 0xEB, 0,
				//				  k  l  m    n     o   p  q  r  s  t    u
								  0, 0, 0, 0xF1, 0xF1, 0, 0, 0, 0, 0, 0xF8};

				_bDeadKey = 0;
				if(!IN_RANGE('a', ch, 'u'))			// Not relevant ASCII
					return S_OK;					//  letter
	
				vkey = chOff[ch - 'a'];				// Translate to base char
				if(!vkey)							// No accents available
					return S_OK;					//  in current approach

				if(ch == 'n')
				{
					if(nDeadKey != ACCENT_TILDE)
						return S_OK;
				}
				else if(nDeadKey == ACCENT_CEDILLA)
				{
					if(ch != 'c')
						return S_OK;
				}
				else								// aeiou
				{
					vkey += nDeadKey;
					if (nDeadKey >= ACCENT_TILDE &&	// eiu with ~ or :
						(vkey == 0xF0 || vkey & 8))		
					{
						if(nDeadKey != ACCENT_UMLAUT)// Only have umlauts
							return S_OK;
						vkey--;
					}
				}
				if(fShift)						
					vkey &= ~0x20;
			}

			// If there are conpotition string, then determin it.
			if(IsIMEComposition()){
				HIMC hIMC = TxImmGetContext();
				if(hIMC){
					pImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
					TxImmReleaseContext(hIMC);
				}
			}

			psel->PutChar((TCHAR)vkey, _fOverstrike, publdr);
		}
	}
	return S_OK;
}

HRESULT CTxtEdit::OnTxSysKeyDown(
	WORD		  vkey,				//@parm Virtual key code
	DWORD		  dwFlags,			//@parm lparam of WM_KEYDOWN msg
	IUndoBuilder *publdr)			//@parm Undobuilder to receive antievents
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::OnTxSysKeyDown");

	HRESULT hr = OnTxSpecialKeyDown(vkey, dwFlags, publdr);
	if (hr == S_OK)
		return hr;

	hr = S_FALSE;
	
	if(vkey == VK_BACK && (dwFlags & SYS_ALTERNATE))
	{
		if( _pundo && _pundo->CanUndo())
		{
			if( PopAndExecuteAntiEvent(_pundo, 0) != NOERROR )
			{
				hr = S_MSG_KEY_IGNORED;
			}
		}
		else
			Sound();
	}
	else if( (vkey == VK_F10 &&// F10
			!(dwFlags & SYS_PREVKEYSTATE) &&		// Key previously up
			(GetKeyState(VK_SHIFT) & 0x8000)))		// Shift is down
	{
		HandleKbdContextMenu();
	}

	return hr;
}

/////////////////////////////// Other system events //////////////////////////////

HRESULT CTxtEdit::OnContextMenu(LPARAM lparam)
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::OnContextMenu");

	POINT pt;

	pt.x = LOWORD(lparam);
	pt.y = HIWORD(lparam);

	if( TxScreenToClient(&pt) )
	{
		return OnTxRButtonUp(pt.x, pt.y, 0);
	}
	return S_FALSE;
}

/*
 *	CTxtEdit::HandleKbdContextMenu
 *
 *	@mfunc	decides where to put the context menu on the basis of where the
 *			the selection is.  Useful for shift-F10 and VK_APPS, where
 *			we aren't given a location.
 *
 *	@rdesc	void
 */
void CTxtEdit::HandleKbdContextMenu(void)
{
	POINT	pt;
	RECT	rc;
	const CTxtSelection * const psel = GetSel();

	// Figure out where selection ends and put context menu near it
	if(_pdp->PointFromTp(*psel, NULL, FALSE, pt, NULL, TA_TOP) < 0)
		return;

	// Make sure point is still within bounds of edit control
	_pdp->GetViewRect(rc);
	
	if (pt.x < rc.left)
		pt.x = rc.left;
	if (pt.x > rc.right - 2)
		pt.x = rc.right - 2;
	if (pt.y < rc.top)
		pt.y = rc.top;
	if (pt.y > rc.bottom - 2)
		pt.y = rc.bottom - 2;

	OnTxRButtonUp(pt.x, pt.y, 0);
}


/////////////////////////////// Format Range Commands //////////////////////////////


LONG CTxtEdit::OnFormatRange(
	FORMATRANGE *pfr, 
	SPrintControl prtcon,
	HDC hdcMeasure,
	LONG xMeasurePerInch,
	LONG yMeasurePerInch)
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::OnFormatRange");

	// Even if there is 0 text, we want to print the control so that it will
	// fill the control with background color.
	// Use Adjusted Text Length.  Embedded objects using RichEdit will get the empty
	// document they expect and will create a default size document.
	if(!pfr || 
		((pfr->chrg.cpMin >= (LONG)GetAdjustedTextLength()) && !prtcon._fPrintFromDraw))
	{	// we're done formatting, get rid of our printer's display context.
		delete _pdpPrinter;
		_pdpPrinter = NULL;

		return GetAdjustedTextLength();
	}

	LONG lRetVal = -1;
	BOOL fSetDCWorked = FALSE;
	HDC hdcLocal = pfr->hdc;

	// first time in with this printer, set up a new display context.
	// IMPORTANT: proper completion of the printing process is required
	// to dispose of this context and begin a new context.
	// This is implicitly done by printing the last character, or
	// sending an EM_FORMATRANGE message with pfr equal to NULL.
	if ( NULL == _pdpPrinter )
	{
		_pdpPrinter = new CDisplayPrinter (this, hdcLocal,
				pfr->rc.right - pfr->rc.left /* x width max */,
				pfr->rc.bottom - pfr->rc.top, /* y height max */ 
				prtcon);

		if ( _pdpPrinter ){
			_pdpPrinter->Init();

			// Future: (ricksa) This is a really yucky way to pass the draw info
			// to the printer but it was quick. We want to make this better.
			_pdpPrinter->ResetDrawInfo(_pdp);

			// Set the temporary zoom factor (if there is one).
			_pdpPrinter->SetTempZoomDenominator(
				_pdp->GetTempZoomDenominator());
		}
	}
	else
	{
		_pdpPrinter->SetPrintDimensions(&pfr->rc);
	}

	// We set the DC everytime because it could have changed.
	if (_pdpPrinter && GetDeviceCaps(hdcLocal, TECHNOLOGY) != DT_METAFILE)
	{
		// This is not a metafile so do the normal thing
		fSetDCWorked = _pdpPrinter->SetDC(hdcLocal);
	}
	else
	{
		// Is the measure DC already set up?
		if (NULL == hdcMeasure)
		{
			// We need to set up a metafile with an HDC we can use for
			// measuring. It is important to note the hack going on here.
			// Richedit 1.0 assumed that it could map metafiles using TWIPS.
			// Therefore, we pass the TRUE flag into CreateMeasureDC which
			// causes a measure DC to be created which is based on TWIPS.
			hdcMeasure = CreateMeasureDC(hdcLocal, NULL, TRUE, pfr->rcPage.left, 
				pfr->rcPage.top, pfr->rcPage.right - pfr->rcPage.left,
					pfr->rcPage.bottom - pfr->rcPage.top, &xMeasurePerInch, 
						&yMeasurePerInch);
		}

		// Were we able to set up a measure DC?
		if (hdcMeasure != NULL)
		{
			if ( _pdpPrinter ){
				_pdpPrinter->SetMetafileDC(hdcLocal, hdcMeasure,
					xMeasurePerInch, yMeasurePerInch);
			}
			fSetDCWorked = TRUE;
		}
	}

	if (fSetDCWorked)
	{
		// we set this everytime because it could have changed.
		if ( _pdpPrinter && _pdpPrinter->SetTargetDC( pfr->hdcTarget ) )
		{
			LONG	cpReturn;


			//	Format another, single page worth of text.
			cpReturn = _pdpPrinter->FormatRange( pfr->chrg.cpMin, pfr->chrg.cpMost);

			if (!prtcon._fPrintFromDraw)
			{
				// after formatting, we know where the bottom is. But we only 
				// want to set this if we are writing a page rather than
				// displaying a control on the printer.
				pfr->rc.bottom = INT 
					(pfr->rc.top + _pdpPrinter->DYtoLY( _pdpPrinter->GetHeight()) );
			}

			// remember this in case the host wishes to do its own banding.
			_pdpPrinter->SetPrintView( pfr->rc );	// we need to save this for OnDisplayBand.

			_pdpPrinter->SetPrintPage( pfr->rcPage );

			// if we're asked to render, then render the entire page in one go.
			if(prtcon._fDoPrint && ((cpReturn > 0) || prtcon._fPrintFromDraw))
			{
				OnDisplayBand( &pfr->rc, prtcon._fPrintFromDraw );

				// note: we can no longer call OnDisplayBand without reformating.
				_pdpPrinter->Clear(AF_DELETEMEM);	
			}

			lRetVal = cpReturn;
		}

	}

	if (hdcMeasure)
	{
		TxReleaseMeasureDC(hdcMeasure);
	    hdcMeasure = NULL;	
	}

	return lRetVal;
}

// Keep the compiler quiet about xPhys and yPhys below.
// The compiler complains incorrectly about possible use of uninitialized variable.
#pragma warning (disable : 4701)
BOOL CTxtEdit::OnDisplayBand(const RECT *prc, BOOL fPrintFromDraw)
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::OnDisplayBand");

	RECT	rc, rcPrint;

	HDC		hdcPrinter;

	// Make sure OnFormatRange was called and that it actually rendered something.
	if(!_pdpPrinter || !_pdpPrinter->Count())
		return FALSE;

	// proportionally map to printers extents.
	rc.left		= (INT) _pdpPrinter->LXtoDX(prc->left);
	rc.right	= (INT) _pdpPrinter->LXtoDX(prc->right);
	rc.top		= (INT) _pdpPrinter->LYtoDY(prc->top);
	rc.bottom	= (INT) _pdpPrinter->LYtoDY(prc->bottom);

	rcPrint			= _pdpPrinter->GetPrintView();
	rcPrint.left	= (INT) _pdpPrinter->LXtoDX(rcPrint.left);
	rcPrint.right	= (INT) _pdpPrinter->LXtoDX(rcPrint.right);
	rcPrint.top		= (INT) _pdpPrinter->LYtoDY(rcPrint.top);
	rcPrint.bottom	= (INT) _pdpPrinter->LYtoDY(rcPrint.bottom);

	// Get the DC for the printer because we use it below.
	hdcPrinter = _pdpPrinter->GetDC();

	if (fPrintFromDraw)
	{
		// We need to take the view inset into account
		_pdpPrinter->GetViewRect(rcPrint, &rcPrint);
	}

#ifdef PWD_JUPITER
    // GuyBark 34191 Jupiter: We must extent the right edge of the view, 
    // otherwise letters with overhangs get cut off. This may look rather
    // hard coded, but this is the same hard coded value used by PWord's 
    // doc.c. Ideally we'd not hard code the value, but there doesn't seem 
    // to be an easy way of finding the required inset here. We take 
    // similar action when the user scrolls the RichEdit window.
    rcPrint.right += 8;
#endif // PWD_JUPITER

	// Render this band.
	_pdpPrinter->Render(rcPrint, rc);

	return TRUE;
}
#pragma warning (default : 4701)



//////////////////////////////// Protected ranges //////////////////////////////////

/*
 *	CTxtEdit::IsProtected (msg, wparam, lparam)
 *
 *	@mfunc
 *		Find out if selection is protected
 *
 *	@rdesc
 *		TRUE iff 1) control is read-only or 2) selection is protected and
 *		parent query says to protect
 */
BOOL CTxtEdit::IsProtected(
	UINT	msg, 		//@parm	Message id
	WPARAM	wparam, 	//@parm WPARAM from window's message
	LPARAM	lparam)		//@parm LPARAM from window's message
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::IsProtected");
	
	LONG iDirection = 0;

	CTxtSelection *psel = GetSel();

	// there are a few special cases to consider, namely
	// backspacing into a protected range, 'del'eting into
	// a protected range, and type with overstrike into a protected
	// range.
	if( (msg == WM_KEYDOWN && (wparam == VK_BACK || wparam == VK_F16)) )
	{
		// check for the format behind the selection, if we are trying to 
		// backspace an insertion point.
		iDirection = -1;
	}
	else if( (msg == WM_KEYDOWN && wparam == VK_DELETE) || 
		(_fOverstrike && msg == WM_CHAR) )
	{
		iDirection = 1;
	}

	int iProt = 0;
	
	// HACK ALERT: we don't do fIsDBCS protection checking for EM_REPLACESEL,
	// EM_SETCHARFORMAT, or EM_SETPARAFORMAT.  Outlook uses 

⌨️ 快捷键说明

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