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

📄 edit.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*
 *	@doc INTERNAL
 *
 *	@module	edit.cpp - main part of CTxtEdit |
 *	
 *		See also textserv.cpp (ITextServices and SendMessage interfaces)
 *		and tomDoc.cpp (ITextDocument interface)
 *	
 *	Authors: <nl>
 *		Original RichEdit code: David R. Fulmer <nl>
 *		Christian Fortini, Murray Sargent, Alex Gounares, Rick Sailor,
 *		Jon Matousek
 *	
 *	History: <nl>
 *		12/28/95 jonmat-Added support of Magellan mouse and smooth scrolling.
 *
 *	@devnote
 *		Be sure to set tabs at every four (4) columns.  In fact, don't even
 *		think of doing anything else!
 *
 */

#include "_common.h"
#include "_edit.h"
#include "_dispprt.h"
#include "_dispml.h"
#include "_dispsl.h"
#include "_select.h"
#include "_text.h"
#include "_runptr.h"
#include "_font.h"
#include "_measure.h"
#include "_render.h"
#include "_m_undo.h"
#include "_antievt.h"
#include "_rtext.h"

#include "_ime.h"
#include "_urlsup.h"
#include <intsafe.h>


#define CTRL(_ch) (_ch - 'A' + 1)


ASSERTDATA

#ifdef DEBUG
BOOL fInAssert = FALSE;
#endif

// This is not public because we don't really want folks using it.
// ITextServices is a private interface.
EXTERN_C const IID IID_ITextServices = { // 8d33f740-cf58-11ce-a89d-00aa006cadc5
	0x8d33f740,
	0xcf58,
	0x11ce,
	{0xa8, 0x9d, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5}
  };

// {13E670F4-1A5A-11cf-ABEB-00AA00B65EA1}
EXTERN_C const GUID IID_ITextHost = 
{ 0x13e670f4, 0x1a5a, 0x11cf, { 0xab, 0xeb, 0x0, 0xaa, 0x0, 0xb6, 0x5e, 0xa1 } };

// {13E670F5-1A5A-11cf-ABEB-00AA00B65EA1}
EXTERN_C const GUID IID_ITextHost2 = 
{ 0x13e670f5, 0x1a5a, 0x11cf, { 0xab, 0xeb, 0x0, 0xaa, 0x0, 0xb6, 0x5e, 0xa1 } };

// this is used internally do tell if a data object is one of our own.
EXTERN_C const GUID IID_IRichEditDO =
{ /* 21bc3b20-e5d5-11cf-93e1-00aa00b65ea1 */
    0x21bc3b20,
    0xe5d5,
    0x11cf,
    {0x93, 0xe1, 0x00, 0xaa, 0x00, 0xb6, 0x5e, 0xa1}
};

// Static data members

DWORD CTxtEdit::_dwTickDblClick;	// time of last double-click
POINT CTxtEdit::_ptDblClick;		// position of last double-click

//HCURSOR CTxtEdit::_hcurCross = 0;	// We don't implement outline drag move
HCURSOR CTxtEdit::_hcurArrow = 0;
HCURSOR CTxtEdit::_hcurHand = 0;
HCURSOR CTxtEdit::_hcurIBeam = 0;
HCURSOR CTxtEdit::_hcurItalic = 0;
HCURSOR CTxtEdit::_hcurSelBar = 0;

// ??? CF - These should probably go away
#pragma BEGIN_CODESPACE_DATA
TCHAR szCRLF[]	= TEXT("\r\n");
TCHAR szCR[]	= TEXT("\r");
#pragma END_CODESPACE_DATA

#ifdef PENWIN20
// hit test codes for CTxtEdit::OnHitTest
#define lHitText	1	// hit text
#define lHitSel		2	// hit selection
#endif // PENWIN20

LOCAL WORD 		ConvVKey (WORD vKey);

// NB! Global variable that tells us wether we're on a BiDi system or not  	
WORD	g_wLang = 0;					// Current LID of the system:
										// Arabic, Hebrew or "nonBiDi"
WORD	g_wFlags = 0;					// Keyboard controlled flags


///////////////// CTxtEdit Creation, Initialization, Destruction ///////////////////////////////////////

/*
 *	CTxtEdit::CTxtEdit()
 *
 *	@mfunc
 *		constructor
 */
CTxtEdit::CTxtEdit(ITextHost *phost, IUnknown *punk)
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::CTxtEdit");

	_unk.Init();
	_punk = (punk) ? punk : &_unk;
	_ldte.Init(this);
	_phost	  = phost;
	_cpAccelerator = -1;					// Default to no accelerator

	// Initialize _iCF and _iPF to something bogus
	_iCF = -1;
	_iPF = -1;

	// GuyBark JupiterJ IME: Imitially the display is NOT frozen.
	_fDisplayFrozen = FALSE;

	// Initialize local maximum text size to window default
	_cchTextMost = cInitTextMax;

	_DeleteBeforeConvert = 0;	// Fix for WinCEOS RAID #12736
}

/*
 *	CTxtEdit::~CTxtEdit()
 *
 *	@mfunc
 *		Destructor
 */
CTxtEdit::~CTxtEdit ()
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::~CTxtEdit");

	Assert(!_fMButtonCapture);				// Need to properly transition
											//  Magellan mouse if asserts!

	_fSelfDestruct = TRUE;					// Tell the Call Mgr not to
											//  call this any more
	if( _pdetecturl )
	{
		delete _pdetecturl;
	}

	// Flush the clipboard first
	_ldte.FlushClipboard();

	if(_pDocInfo)							// Do this before closing
	{										//  down internal structures
		CloseFile(TRUE);					// Close any open file
		delete _pDocInfo;					// Delete document info
		_pDocInfo = NULL;
	}

	ReleaseFormats(_iCF, _iPF);				// Release the default formats

	if( _pobjmgr )
	{
		delete _pobjmgr;
	}

	// Release our reference to selection object
	if (_psel)
	{
		_psel->Release();
	}

	// Delete undo manager
	if( _pundo )
	{
		_pundo->Destroy();
	}
	if( _predo )
	{
		_predo->Destroy();
	}

	delete _ime;					// Delete IME
	delete _pdp;					// Delete displays
	delete _pdpPrinter;
	_pdp = NULL;					// Break any further attempts to use
}									//  display

/*
 *	CTxtEdit::Init (prcClient)
 *
 *	@mfunc
 *		Initializes this CTxtEdit. Called by CreateTextServices()
 *
 *	@rdesc
 *		Return TRUE if successful
 */
BOOL CTxtEdit::Init (
	const RECT *prcClient)		//@parm Client RECT
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::Init");

	CCharFormat 		CF;
	DWORD				dwBits = 0;
	LONG				iCF, iPF;
	CParaFormat 		PF;
	ICharFormatCache *	pICFCache;
	IParaFormatCache *	pIPFCache;
	CCallMgr			callmgr(this);

	// Set up default CCharFormat and CParaFormat

	if( TxGetDefaultCharFormat(&CF) != NOERROR ||
		TxGetDefaultParaFormat(&PF) != NOERROR )
	{
		return FALSE;
	}
													// Got default formats
	if (FAILED(GetCharFormatCache(&pICFCache)) ||	// Now try to cache them
		FAILED(GetParaFormatCache(&pIPFCache)) ||
		FAILED(pICFCache->Cache(&CF, &iCF))	   ||
		FAILED(pIPFCache->Cache(&PF, &iPF)))
	{
		return FALSE;
	}												// Cached default formats
	_iCF = (WORD)iCF;								// Save format indices
	_iPF = (WORD)iPF;

	// Load mouse cursors (but only for first instance)
	if(!_hcurArrow)
	{
		_hcurArrow = LoadCursor(0, IDC_ARROW);
//		if(!_hcurCross)					// Don't currently use
//			_hcurCross	= LoadCursor(hinstRE, MAKEINTRESOURCE(CUR_CROSS));
		if(!_hcurHand)
			_hcurHand	= LoadCursor(hinstRE, MAKEINTRESOURCE(CUR_HAND));
		if(!_hcurIBeam)								// Load cursor
			_hcurIBeam	= LoadCursor(0, IDC_IBEAM);
		if(!_hcurItalic)
			_hcurItalic	= LoadCursor(hinstRE, MAKEINTRESOURCE(CUR_ITALIC));
		if(!_hcurSelBar)
			_hcurSelBar = LoadCursor(hinstRE, MAKEINTRESOURCE(CUR_SELBAR));
	}

	_pfnWB = (EDITWORDBREAKPROC) TxWordBreakProc;	// Set word breaking proc

#ifdef DEBUG
	// the host is going to do some checking on richtext vs. plain
	// text.
	_fRich = TRUE;
#endif // DEBUG

	if(_phost->TxGetPropertyBits (TXTBITS |		// Get host state flags
		TXTBIT_MULTILINE | TXTBIT_SHOWACCELERATOR,	//  that we cache or need
		&dwBits) != NOERROR )						//  for display setup
	{
		return FALSE;
	}												// Cache bits defined by
	_dwFlags = dwBits & TXTBITS;					//  TXTBITS mask

	if ((dwBits & TXTBIT_SHOWACCELERATOR) &&		// They want accelerator,
		FAILED(UpdateAccelerator()))				//  so let's get it
	{
		return FALSE;
	}		

	_fTransparent = TxGetBackStyle() == TXTBACK_TRANSPARENT;
	if( dwBits & TXTBIT_MULTILINE )					// Create and initialize
		_pdp = new CDisplayML(this);				//  display
	else
		_pdp = new CDisplaySL(this);

	if(!_pdp || !_pdp->Init())
		return FALSE;

	_fUseUndo = TRUE;

 	// Initialize some IME bits
	_fAutoFont = TRUE;
	_fAutoKeyboard = FALSE;


	// Set whether we are in our host or not
	ITextHost2 *phost2;
	if( _phost->QueryInterface(IID_ITextHost2, (void **)&phost2) 
		== NOERROR )
	{
		// We assume that ITextHost2 means this is our host
		phost2->Release();
		_fInOurHost = TRUE;
	}
	else
	{
		// Get the maximum from our host
		_phost->TxGetMaxLength((DWORD *) &_cchTextMost);
	}
	
	//			
	// Add EOP iff Rich Text
	//
	if (IsRich())
	{
		// we should _not_ be in 10 compatibility mode yet.
		// if we transition into 1.0 mode, we'll add a CRLF
		// at the end of the document.
		SetRichDocEndEOP(0);
	}

	// for Japanese, this virtual key indicates Kana mode.  
	// Check the toggle bit to see if it is on or offf.
	// If on, Kana characters (single byte Japanese char) are coming in via WM_CHAR.
	_fKANAMode = (GetKeyboardCodePage() == _JAPAN_CP) &&
		((GetKeyState(VK_KANA) & 0x1) != 0);

	return TRUE;
}


///////////////////////////// CTxtEdit IUnknown ////////////////////////////////

/*
 *	CTxtEdit::QueryInterface (riid, ppv)
 *
 *	@mfunc
 *		IUnknown method
 *
 *	@rdesc
 *		HRESULT = (if success) ? NOERROR : E_NOINTERFACE
 *
 *	@devnote
 *		This interface is aggregated. See textserv.cpp for discussion.
 */
HRESULT CTxtEdit::QueryInterface(REFIID riid, void **ppv)
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::QueryInterface");

	return _punk->QueryInterface(riid, ppv);
}

/*
 *	CTxtEdit::AddRef()
 *
 *	@mfunc
 *		IUnknown method
 *
 *	@rdesc
 *		ULONG - incremented reference count
 */
ULONG CTxtEdit::AddRef(void)
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::AddRef");

	return _punk->AddRef();
}

/*
 *	CTxtEdit::Release()
 *
 *	@mfunc
 *		IUnknown method
 *
 *	@rdesc
 *		ULONG - decremented reference count
 */
ULONG CTxtEdit::Release(void)
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::Release");

	return _punk->Release();
}

////////////////////////// Undo Management  //////////////////////////////

/*
 *	CTxtEdit::CreateUndoMgr (dwLim, flags)
 *
 *	@mfunc
 *		Creates an undo stack
 *
 *	@rdesc
 *		Ptr to new IUndoMgr 
 */
IUndoMgr *CTxtEdit::CreateUndoMgr(
	DWORD	dwLim,			//@parm Size limit for the
	USFlags flags)
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::CreateUndoMgr");

	IUndoMgr *pmgr = NULL;

	if( _fUseUndo )
	{
		pmgr = new CUndoStack(this, dwLim, flags);
		if( pmgr == NULL || pmgr->GetUndoLimit() == 0 )
		{
			// The undo stack failed to initialize properly (probably
			// lack of memory). Trash it and return NULL.
			if( pmgr != NULL)
			{
				pmgr->Destroy();
			}
			return NULL;
		}
		// We may be asked to create a new undo/redo manager
		// before we are completely done with initialization.
		// We need to clean up memory we have already allocated.
		if( flags & US_REDO )
		{
			if (_predo) {
				_predo->Destroy();
			}
			_predo = pmgr;
		}
		else
		{
			if (_pundo) {
				_pundo->Destroy();
			}
			_pundo = pmgr;
		}
	}
	
	return pmgr;
}

/*
 *	CTxtEdit::HandleUndoLimit (dwLim)
 *
 *	@mfunc
 *		Handles the EM_SETUNDOLIMIT message
 *
 *	@rdesc	
 *		Actual limit to which things were set.
 */
LRESULT CTxtEdit::HandleSetUndoLimit( 
	DWORD dwLim ) 		//@parm	Requested limit size
{
	TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::HandleSetUndoLimit");

	if( dwLim == 0 )
	{
		_fUseUndo = FALSE;

		if( _pundo )
		{
			_pundo->Destroy();
			_pundo = NULL;
		}

		if( _predo )
		{
			_predo->Destroy();
			_predo = NULL;
		}
	}
	else if ( !_pundo )
	{
		_fUseUndo = TRUE;
		// don't worry about return value; if it's NULL, we're
		// in the same boat as if the api wasn't called ( so later
		// on, we might try to allocate the default).
		CreateUndoMgr(dwLim, US_UNDO);
	}
	else
	{
		dwLim = _pundo->SetUndoLimit(dwLim);

		// setting the undo limit on the undo stack will return to
		// us the actual amount set.  Try to set the redo stack to 
		// the same size.  If it can't go that big, too bad.

		if( _predo )
		{
			_predo->SetUndoLimit(dwLim);
		}
	}
	return dwLim;
}

/*
 *	CTxtEdit::HandleSetTextMode
 *
 *	@mfunc	handles setting the text mode
 *
 *	@rdesc	LRESULT; 0 (NOERROR) on success, OLE failure code on failure.
 *
 *	@devnote	the text mode does not have to be fully specified; it
 *			is sufficient to merely specify the specific desired behavior.
 *
 *			Note that the edit control must be completely empty for this
 *			routine to work.
 */
LRESULT CTxtEdit::HandleSetTextMode(
	DWORD mode)			//@parm the desired mode
{
	LRESULT lres = 0;

	// first off, we must be completely empty
	if( GetAdjustedTextLength() || 
		(_pundo && _pundo->CanUndo()) ||
		(_predo && _predo->CanUndo()) )
	{
		return E_UNEXPECTED;
	}

	// These bits are considered one at a time; thus the absence of
	// any bits does _NOT_ imply any change in behavior.

	// TM_RICHTEXT && TM_PLAINTEXT are mutually exclusive; they cannot
	// be both set.  Same goes for TM_SINGLELEVELUNDO / TM_MULTILEVELUNDO
	// and TM_SINGLECODEPAGE / TM_MULTICODEPAGE

⌨️ 快捷键说明

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