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

📄 tomdoc.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// 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 TOM
 *
 *	@module tomdoc.cpp - Implement the ITextDocument interface on CTxtEdit |
 *	
 *		This module contains the implementation of the TOM ITextDocument
 *		class as well as the global TOM type-info routines
 *
 *	History: <nl>
 *		sep-95	MurrayS: stubs and auto-doc created <nl>
 *		nov-95	MurrayS: upgrade to top-level TOM interface
 *		dec-95	MurrayS: implemented file I/O methods
 *
 *	@future
 *		1. Begin/EndEditCollection
 *		2. Freeze/Unfreeze
 *
 */

#include "_common.h"
#include "_range.h"
#include "_edit.h"
#include "_disp.h"
#include "_rtfconv.h"

ASSERTDATA

// TOM Type Info HRESULT and pointers
HRESULT		g_hrGetTypeInfo = NOERROR;
ITypeInfo *	g_pTypeInfoDoc;
ITypeInfo *	g_pTypeInfoSel;
ITypeInfo *	g_pTypeInfoFont;
ITypeInfo *	g_pTypeInfoPara;
ITypeLib  *	g_pTypeLib;


EXTERN_C const GUID LIBID_TOM = 
{ 0x8CC497C9, 0xA1DF, 0x11ce, { 0x80, 0x98, 0x0, 0xaa, 0x0, 0x47, 0xBE, 0x5D } };


//------------------------ Global TOM Type Info Methods -----------------------------

/*
 *	GetTypeInfoPtrs()
 *
 *	@func
 *		Ensure that global TOM ITypeInfo ptrs are valid (else g_pTypeInfoDoc
 *		is NULL).  Return NOERROR immediately if g_pTypeInfoDoc is not NULL,
 *		i.e., type info ptrs are already valid.
 *
 *	@rdesc
 *		HRESULT = (success) ? NOERROR
 *				: (HRESULT from LoadTypeLib or GetTypeInfoOfGuid)
 *
 *	@comm
 *		This routine should be called by any routine that uses the global
 *		type info ptrs, e.g., IDispatch::GetTypeInfo(), GetIDsOfNames, and
 *		Invoke.  That way if noone is using the type library info, it doesn't
 *		have to be loaded.
 *
 */
HRESULT GetTypeInfoPtrs()
{
	HRESULT	hr;
	CLock	lock;							// Only one thread at a time...

	if(g_pTypeInfoDoc)						// Type info ptrs already valid
		return NOERROR;

	if(g_hrGetTypeInfo != NOERROR)			// Tried to get before and failed
		return g_hrGetTypeInfo;

	if (pLoadRegTypeLib(LIBID_TOM, 1, 0, LANG_NEUTRAL, &g_pTypeLib) != NOERROR)
	{
		hr = pLoadTypeLib(OLESTR("RICHED20.DLL"), &g_pTypeLib);
		if(hr != NOERROR)
			goto err;
	}

	// Get ITypeInfo pointers with g_pTypeInfoDoc last
	hr = g_pTypeLib->GetTypeInfoOfGuid(IID_ITextSelection, &g_pTypeInfoSel);
	if(hr == NOERROR)
	{
	    g_pTypeLib->GetTypeInfoOfGuid(IID_ITextFont,	 &g_pTypeInfoFont);
		g_pTypeLib->GetTypeInfoOfGuid(IID_ITextPara,	 &g_pTypeInfoPara);
		g_pTypeLib->GetTypeInfoOfGuid(IID_ITextDocument, &g_pTypeInfoDoc);

		if(g_pTypeInfoFont && g_pTypeInfoPara && g_pTypeInfoDoc)
			return NOERROR;					// Got 'em all
	}
	hr = E_FAIL;

err:
	Assert("Error getting type info pointers");

	g_pTypeInfoDoc	= NULL;					// Type info ptrs not valid
	g_hrGetTypeInfo	= hr;					// Save HRESULT in case called
	return hr;								//  again
}

/*
 *	ReleaseTypeInfoPtrs()
 *
 *	@func
 *		Release TOM type info ptrs in case they have been defined.
 *		Called when RichEdit dll is being unloaded.
 */
void ReleaseTypeInfoPtrs()
{
	if(g_pTypeInfoDoc)
	{
		g_pTypeInfoDoc->Release();
		g_pTypeInfoSel->Release();
		g_pTypeInfoFont->Release();
		g_pTypeInfoPara->Release();
	}
	if(g_pTypeLib)
		g_pTypeLib->Release();
}

/*
 *	GetTypeInfo(iTypeInfo, &pTypeInfo, ppTypeInfo)
 *
 *	@func
 *		IDispatch helper function to check parameter validity and set
 *		*ppTypeInfo = pTypeInfo if OK
 *
 *	@rdesc
 *		HRESULT
 */
HRESULT GetTypeInfo(
	UINT		iTypeInfo,		//@parm Index of type info to return
	ITypeInfo *&pTypeInfo,		//@parm Address of desired type info ptr
	ITypeInfo **ppTypeInfo)		//@parm Out parm to receive type info
{
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtEdit::GetTypeInfo");

	if(!ppTypeInfo)
		return E_INVALIDARG;

	*ppTypeInfo = NULL;

	if(iTypeInfo > 1)
		return DISP_E_BADINDEX;

	HRESULT hr = GetTypeInfoPtrs();				// Ensure TypeInfo ptrs are OK
	if(hr == NOERROR)
	{
		*ppTypeInfo = pTypeInfo;				// Have to use reference in
		pTypeInfo->AddRef();					//  case defined in this call
	}
	return hr;
}

/*
 *	MyRead(dwCookie, pbBuffer, cb, pcb)
 *
 *	@func
 *		Callback function for converting a file into an editstream for
 *		input.
 *
 *	@rdesc
 *		(DWORD)HRESULT
 */
DWORD CALLBACK MyRead(DWORD dwCookie, BYTE *pbBuffer, long cb, long *pcb)
{
	if(!dwCookie)								// No handle defined
		return (DWORD)E_FAIL;

	Assert(pcb);
	*pcb = 0;

	if(!ReadFile((HANDLE)dwCookie, (void *)pbBuffer, (DWORD)cb,
					(DWORD *)pcb, NULL))
		return HRESULT_FROM_WIN32(GetLastError());

	return (DWORD)NOERROR;
}

/*
 *	MyWrite(dwCookie, pbBuffer, cb, pcb)
 *
 *	@func
 *		Callback function for converting a file into an editstream for
 *		output.
 *
 *	@rdesc
 *		(DWORD)HRESULT
 */
DWORD CALLBACK MyWrite(DWORD dwCookie, BYTE *pbBuffer, long cb, long *pcb)
{
	if(!dwCookie)								// No handle defined
		return (DWORD)E_FAIL;

	Assert(pcb);
	*pcb = 0;

	if(!WriteFile((HANDLE)dwCookie, (void *)pbBuffer, (DWORD)cb,
					(DWORD *)pcb, NULL))
		return HRESULT_FROM_WIN32(GetLastError());

	return (DWORD)(*pcb ? NOERROR : E_FAIL);
}


//-----------------CTxtEdit IUnknown methods: see textserv.cpp -----------------------------


//------------------------ CTxtEdit IDispatch methods -------------------------

/*
 *	CTxtEdit::GetTypeInfoCount(pcTypeInfo)
 *
 *	@mfunc
 *		Get the number of TYPEINFO elements (1)
 *
 *	@rdesc
 *		HRESULT = (pcTypeInfo) ? NOERROR : E_INVALIDARG;
 */
STDMETHODIMP CTxtEdit::GetTypeInfoCount(
	UINT *pcTypeInfo)	//@parm Out parm to receive count
{
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtEdit::GetTypeInfoCount");

	if(!pcTypeInfo)
		return E_INVALIDARG;

	*pcTypeInfo = 1;
	return NOERROR;
}

/*
 *	CTxtEdit::GetTypeInfo(iTypeInfo, lcid, ppTypeInfo)
 *
 *	@mfunc
 *		Return ptr to type information object for ITextDocument interface
 *
 *	@rdesc
 *		HRESULT
 */
STDMETHODIMP CTxtEdit::GetTypeInfo(
	UINT		iTypeInfo,		//@parm Index of type info to return
	LCID		lcid,			//@parm Local ID of type info
	ITypeInfo **ppTypeInfo)		//@parm Out parm to receive type info
 {
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtEdit::GetTypeInfo");

	return ::GetTypeInfo(iTypeInfo, g_pTypeInfoDoc, ppTypeInfo);
}

/*
 *	CTxtEdit::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid)
 *
 *	@mfunc
 *		Get DISPIDs for all TOM methods and properties
 *
 *	@rdesc
 *		HRESULT
 *
 *	@devnote
 *		This routine tries to find DISPIDs using the type information for
 *		ITextDocument. If that fails, it asks the selection to find the
 *		DISPIDs.
 */
STDMETHODIMP CTxtEdit::GetIDsOfNames(
	REFIID		riid,			//@parm Interface ID to interpret names for
	OLECHAR **	rgszNames,		//@parm Array of names to be mapped
	UINT		cNames,			//@parm Count of names to be mapped
	LCID		lcid,			//@parm Local ID to use for interpretation
	DISPID *	rgdispid)		//@parm Out parm to receive name mappings
{
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtEdit::GetIDsOfNames");

	HRESULT hr = GetTypeInfoPtrs();				// Ensure TypeInfo ptrs are OK
	if(hr != NOERROR)
		return hr;
		
	hr = g_pTypeInfoDoc->GetIDsOfNames(rgszNames, cNames, rgdispid);

	if(hr == NOERROR)							// Succeeded in finding an
		return NOERROR;							//  ITextDocument method

	IDispatch *pSel = (IDispatch *)GetSel();	// See if the selection knows
												//  the desired method
	if(!pSel)
		return hr;								// No selection

	return pSel->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);
}

/*
 *	CTxtEdit::Invoke(dispidMember, riid, lcid, wFlags, pdispparams,
 *					  pvarResult, pexcepinfo, puArgError)
 *	@mfunc
 *		Invoke members for all TOM DISPIDs, i.e., for ITextDocument,
 *		ITextSelection, ITextRange, ITextFont, and ITextPara.  TOM DISPIDs
 *		for all but ITextDocument are delegated to the selection object.
 *
 *	@rdesc
 *		HRESULT
 *
 *	@devnote
 *		This routine trys to invoke ITextDocument members if the DISPID is
 *		in the range 0 thru 0xff.  It trys to invoke ITextSelection members if
 *		the DISPID is in the range 0x100 thru 0x4ff (this includes
 *		ITextSelection, ITextRange, ITextFont, and ITextPara).  It returns
 *		E_MEMBERNOTFOUND for DISPIDs outside these ranges.
 */
STDMETHODIMP CTxtEdit::Invoke(
	DISPID		dispidMember,	//@parm Identifies member function
	REFIID		riid,			//@parm Pointer to interface ID
	LCID		lcid,			//@parm Locale ID for interpretation
	USHORT		wFlags,			//@parm Flags describing context of call
	DISPPARAMS *pdispparams,	//@parm Ptr to method arguments
	VARIANT *	pvarResult,		//@parm Out parm for result (if not NULL)
	EXCEPINFO * pexcepinfo,		//@parm Out parm for exception info
	UINT *		puArgError)		//@parm Out parm for error
{
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtEdit::Invoke");

	HRESULT hr = GetTypeInfoPtrs();				// Ensure TypeInfo ptrs are OK
	if(hr != NOERROR)
		return hr;
		
	if((DWORD)dispidMember < 0x100)				// ITextDocment method
		return g_pTypeInfoDoc->Invoke((IDispatch *)this, dispidMember, wFlags,
							 pdispparams, pvarResult, pexcepinfo, puArgError);

	IDispatch *pSel = (IDispatch *)GetSel();	// See if the selection has
												//  the desired method
	if(pSel && (DWORD)dispidMember <= 0x4ff)
		return pSel->Invoke(dispidMember, riid, lcid, wFlags,
							 pdispparams, pvarResult, pexcepinfo, puArgError);

	return DISP_E_MEMBERNOTFOUND;
}


//--------------------- ITextDocument Methods/Properties -----------------------

/*
 *	ITextDocument::BeginEditCollection()
 *
 *	@mfunc
 *		Method that turns on undo grouping
 *
 *	@rdesc
 *		HRESULT = (undo enabled) ? NOERROR : S_FALSE
 */
STDMETHODIMP CTxtEdit::BeginEditCollection ()
{
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtEdit::BeginEditCollection");

	return E_NOTIMPL;
}

/*
 *	ITextDocument::EndEditCollection() 
 *
 *	@mfunc
 *		Method that turns off undo grouping
 *
 *	@rdesc
 *		HRESULT = NOERROR
 */
STDMETHODIMP CTxtEdit::EndEditCollection () 
{
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtEdit::EndEditCollection");

	return E_NOTIMPL;
}

/*
 *	ITextDocument::Freeze(long *pValue) 
 *
 *	@mfunc
 *		Method to increment the freeze count. If this count is nonzero,
 *		screen updating is disabled.  This allows a sequence of editing
 *		operations to be performed without the performance loss and
 *		flicker of screen updating.  See Unfreeze() to decrement the
 *		freeze count.
 *
 *	@rdesc
 *		HRESULT = (screen updating disabled) ? NOERROR : S_FALSE
 *
 *	@devnote
 *		The ifdef'd code works in principle (need to add _cFreeze to
 *		_edit.h), but we don't enable it pending dealing with APIs like
 *		EM_LINEFROMCHAR that don't yet know how to react to a frozen display.
 */
STDMETHODIMP CTxtEdit::Freeze (
	long *pCount)		//@parm Out parm to receive updated freeze count
{
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtEdit::Freeze");

#ifdef FUTURE
	if(_pdp)
	{
		_pdp->Freeze();
		if(_pdp->IsFrozen())
			_cFreeze++;
		else
			_cFreeze = 0;
	}

	if(pCount)
		*pCount = _cFreeze;

	return _cFreeze ? NOERROR : S_FALSE;

#endif
	return E_NOTIMPL;
}

/*
 *	ITextDocument::GetDefaultTabStop (pValue) 
 *
 *	@mfunc
 *		Property get method that gets the default tab stop to be
 *		used whenever the explicit tabs don't extend far enough.
 *
 *	@rdesc
 *		HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
 */
STDMETHODIMP CTxtEdit::GetDefaultTabStop (
	float *	pValue)		//@parm Out parm to receive default tab stop
{
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtEdit::GetDefaultTabStop");

	if(!pValue)
		return E_INVALIDARG;
                                                                        
	const LONG lTab = GetDefaultTab();

	*pValue = TWIPS_TO_FPPTS(lTab);

	return NOERROR;
}

/*
 *	CTxtEdit::GetName (pName)
 *
 *	@mfunc
 *		Retrieve ITextDocument filename
 *
 *	@rdesc
 *		HRESULT = (!<p pName>) ? E_INVALIDARG :
 *				  (no name) ? S_FALSE :
 *				  (if not enough RAM) ? E_OUTOFMEMORY : NOERROR
 */
STDMETHODIMP CTxtEdit::GetName (
	BSTR * pName)		//@parm Out parm to receive filename
{
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtEdit::GetName");

	if(!pName)
		return E_INVALIDARG;

	*pName = NULL;
	if(!_pDocInfo || !_pDocInfo->pName)
		return S_FALSE;

	*pName = pSysAllocString(_pDocInfo->pName);
	
	return *pName ? NOERROR : E_OUTOFMEMORY;
}

/*
 *	ITextDocument::GetSaved (pValue) 
 *
 *	@mfunc
 *		Property get method that gets whether this instance has been
 *		saved, i.e., no changes since last save
 *
 *	@rdesc
 *		HRESULT = (!pValue) ? E_INVALIDARG : NOERROR
 *
 *	@comm
 *		Next time to aid C/C++ clients, we ought to make pValue optional
 *		and return S_FALSE if doc isn't saved, i.e., like our other
 *		boolean properties (see, e.g., ITextRange::IsEqual())
 */
STDMETHODIMP CTxtEdit::GetSaved (
	long *	pValue)		//@parm Out parm to receive Saved property
{
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtEdit::GetSaved");

	if(!pValue)
		return E_INVALIDARG;

	*pValue = _fSaved ? tomTrue : tomFalse;
	return NOERROR;
}

/*
 *	ITextDocument::GetSelection (ITextSelection **ppSel) 
 *
 *	@mfunc
 *		Property get method that gets the active selection. 

⌨️ 快捷键说明

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