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

📄 coleobj.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	COLEOBJ.CPP	OLE Object management class implemenation |
 *
 * 	Author:		alexgo 10/24/95
 *
 *	Note:	Much of this code is a port from Richedit1.0 sources
 *			(cleaned up a bit, ported to C++, etc.)  So if there's any
 *			bit of strangeness, it's probably there for a reason.
 *
 */

#include "_common.h"
#include "_edit.h"
#include "_coleobj.h"
#include "_objmgr.h"
#include "_select.h"
#include "_rtext.h"
#include "_disp.h"
#include "_dispprt.h"
#include "_antievt.h"
#include "_dxfrobj.h"

ASSERTDATA

// 
// data private to this file
//
static const OLECHAR szSiteFlagsStm[] = OLESTR("RichEditFlags");	

// 
// EXCEL clsid's.  We have to make some special purpose hacks
// for XL.
const CLSID rgclsidExcel[] =
{
    { 0x00020810L, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46} },  // Excel Worksheet
    { 0x00020811L, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46} },  // Excel Chart
    { 0x00020812L, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46} },  // Excel App1
    { 0x00020841L, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46} },  // Excel App2
};
const INT cclsidExcel = sizeof(rgclsidExcel) / sizeof(rgclsidExcel[0]);


//
//	WordArt CLSID for more special purpose hacks.
//
const GUID CLSID_WordArt = 
    { 0x000212F0L, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46} };
const GUID CLSID_PaintbrushPicture = 
    { 0x0003000AL, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
const GUID CLSID_BitmapImage = 
    { 0xD3E34B21L, 0x9D75, 0x101A, { 0x8C, 0x3D, 0x00, 0xAA, 0x00, 0x1A, 0x16, 0x52 } };


#define dxyHandle (6) // Object frame handle size
#define dxyFrameDefault  (1) // Object frame width

// 
// utility functions
//

/*
 *	IsExcelCLSID
 *
 *	@func	checks to see if the given clsid is one of XL's
 *
 *	@rdesc	TRUE/FALSE
 *
 */
BOOL IsExcelCLSID(REFGUID clsid)
{
	DWORD i;

    for( i = 0; i < cclsidExcel; i++ )
    {
        if (IsEqualCLSID(clsid, rgclsidExcel[i]))
        {
			return TRUE;
        }
    }

    return FALSE;
}

//
//	PUBLIC methods
//

/*
 *	COleObject::QueryInterface
 *
 *	@mfunc	the standard OLE QueryInterface
 *
 *	@rdesc	NOERROR		<nl>
 *			E_NOINTERFACE
 *
 */
STDMETHODIMP COleObject::QueryInterface(
	REFIID		riid,		//@parm the requested interface ID
	void **	ppv)		//@parm out param for the result
{
	HRESULT hr = NOERROR;

	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::QueryInterface");

    if( IsZombie() )
	{
        return CO_E_RELEASED;
	}
        
	if( !ppv )
	{
		return E_INVALIDARG;
	}
	else
	{
		*ppv = NULL;
	}

	if( IsEqualIID(riid, IID_IUnknown) )
	{
		*ppv = (IUnknown *)(IOleClientSite *)this;
	}
	else if( IsEqualIID(riid, IID_IOleClientSite) )
	{
		*ppv = (IOleClientSite *)this;
	}
	else if( IsEqualIID(riid, IID_IOleInPlaceSite) )
	{
		*ppv = (IOleInPlaceSite *)this;
	}
	else if( IsEqualIID(riid, IID_IAdviseSink) )
	{
		*ppv = (IAdviseSink *)this;
	}
	else if( IsEqualIID(riid, IID_IOleWindow) )
	{
		*ppv = (IOleWindow *)this;
	}
	else if( IsEqualIID(riid, IID_IRichEditOleCallback) )
	{
		//
		// NB!! Returning this pointer in our QI is 
		// phenomenally bogus; it breaks fundamental COM
		// identity rules (granted, not many understand them!).
		// Anyway, RichEdit 1.0 did this, so we better.
		//

		TRACEWARNSZ("Returning IRichEditOleCallback interface, COM "
			"identity rules broken!");

		*ppv = _ped->GetRECallback();
	}
	else
	{
		hr = E_NOINTERFACE;
	}

	if( *ppv )
	{
		(*(IUnknown **)ppv)->AddRef();
	}

	return hr;
}


/*
 *	COleObject::AddRef
 *
 *	@mfunc	increments the reference count
 *
 *	@rdesc	the new reference count
 *
 */
STDMETHODIMP_(ULONG) COleObject::AddRef(void)
{
    ULONG cRef;
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::AddRef");

    cRef = SafeAddRef();

	return cRef;
}

/*
 *	COleObject::Release
 *
 *	@mfunc	decrements the reference count
 *
 *	@rdesc	the new reference count
 *
 */
STDMETHODIMP_(ULONG) COleObject::Release(void)
{
    ULONG cRef;
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::Release");

	cRef = SafeRelease();

	return cRef;
}

/*
 *	COleObject::SaveObject
 *
 *	@mfunc	implemtenation of IOleClientSite::SaveObject
 *
 *	@rdesc	HRESULT
 *
 */
STDMETHODIMP COleObject::SaveObject(void)
{
	IPersistStorage *pps;
	HRESULT hr;
	CCallMgr	callmgr(_ped);
	CStabilize stabilize(this);

	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::SaveObject");

	if( !_punkobj || !_pstg )
	{
		TRACEWARNSZ("SaveObject called on invalid object");
		return E_UNEXPECTED;
	}

    if( IsZombie() )
	{
        return CO_E_RELEASED;
	}

	hr = _punkobj->QueryInterface(IID_IPersistStorage, (void **)&pps);

	TESTANDTRACEHR(hr);

	if( hr == NOERROR )
	{
        if( IsZombie() )
		{
            return CO_E_RELEASED;
		}
        
		SavePrivateState();
		
        if( IsZombie() )
		{
            return CO_E_RELEASED;
		}
        
		hr = pOleSave(pps, _pstg, TRUE);
	
	    if( IsZombie() )
		{
	        return CO_E_RELEASED;
		}
        
		TESTANDTRACEHR(hr);

		// note that SaveCompleted is called even if OleSave fails.
		// If both OleSave and SaveCompleted succeed, then go ahead
		// and commit the changes

		if( pps->SaveCompleted(NULL) == NOERROR && hr == NOERROR )
		{
		    if( IsZombie() )
			{
		        return CO_E_RELEASED;
			}
			
			hr = _pstg->Commit(STGC_DEFAULT);

			TESTANDTRACEHR(hr);
		}

        pps->Release();
	}

	return hr;
}

/*
 *	COleObject::GetMoniker
 *
 *	@mfunc	implementation of IOleClientSite::GetMoniker
 *
 *	@rdesc	E_NOTIMPL
 *
 */
STDMETHODIMP COleObject::GetMoniker(
	DWORD	dwAssign,			//@parm	force an assignment?
	DWORD	dwWhichMoniker,	//@parm	kind of moniker to get
	IMoniker **ppmk)			//@parm 	out param for result
{
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::GetMoniker");

	TRACEWARNSZ("method not implemented!");

	if( ppmk )
	{
		*ppmk = NULL;
	}

	return E_NOTIMPL;
}
	
/*
 *	COleObject::GetContainer
 *
 *	@mfunc	implementation of IOleClientSite::GetContainer
 *
 *	@rdesc	E_NOINTERFACE
 */
STDMETHODIMP COleObject::GetContainer(
	IOleContainer **ppcont)	//@parm	out parm for the result
{
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::GetContainer");

	TRACEWARNSZ("method not implemented!");

	if( ppcont )
	{
		*ppcont = NULL;
	}

	// richedit 1.0 returns E_NOINTERFACE instead of E_NOTIMPL.  Do
	// the same.

	return E_NOINTERFACE;
}

/*
 *	COleObject::ShowObject
 *
 *	@mfunc	Implementation of IOleClientSite::ShowObject.  
 *
 *	@rdesc	E_NOTIMPL
 *
 */
STDMETHODIMP COleObject::ShowObject(void)
{
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::ShowObject");

	TRACEWARNSZ("method not implemented!");

	return E_NOTIMPL;
}

/*
 *	COleObject::OnShowWindow
 *
 *	@mfunc	implementation of IOleClientSite::OnShowWindow -- notifies
 *	the client site that the object is or is not being shown in it's
 *	own application window.  This govens whether or not hatching should
 *	appear around the object in richedit.
 *
 *	@rdesc	HRESULT
 *
 */
STDMETHODIMP COleObject::OnShowWindow(
	BOOL fShow)		//@parm if TRUE, the object is being drawn in it's
					//own window
{
	DWORD dwFlags = _pi.dwFlags;
	CCallMgr	callmgr(_ped);
	CStabilize stabilize(this);

	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::OnShowWindow");

    if( IsZombie() )
	{
        return CO_E_RELEASED;
	}

	if( fShow )
	{
		_pi.dwFlags |= REO_OPEN;
	}
	else
	{
		_pi.dwFlags &= ~REO_OPEN;
	}

	// if something changed, redraw the object
	
	if( dwFlags != _pi.dwFlags )
	{
		// invalidate the rect that we're in.
		_ped->TxInvalidateRect(&_rcPos, FALSE);
		// We're not allowed to call invalidate rect by itself
		// without terminating it with a call to update window.
		// However, we don't care at this point if things are
		// redrawn right away.
		_ped->TxUpdateWindow();

		// COMPATIBILITY ISSUE: (alexgo) the RE1.0 code did some funny 
		// stuff with undo here.  I don't believe it's necessary to 
		// repeat that code with our multi-level undo model,
	}

	return NOERROR;
}

/*
 *	COleObject::RequestNewObjectLayout
 *
 *	@mfunc	Implementation of IOleClientSite::RequestNewObjectLayout
 *
 *	@rdesc	E_NOTIMPL
 */
STDMETHODIMP COleObject::RequestNewObjectLayout(void)
{
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, 
			"COleObject::RequestNewObjectLayout");

	TRACEWARNSZ("method not implemented!");

	return E_NOTIMPL;
}

/*
 *	COleObject::GetWindow
 *
 *	@mfunc	Implementation of IOleInPlaceSite::GetWindow
 *
 *	@rdesc	HRESULT
 */
STDMETHODIMP COleObject::GetWindow(
	HWND *phwnd)	//@parm where to put the window
{
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::GetWindow");

	// NB! this method is not stabilized.

    if( IsZombie() )
	{
        return CO_E_RELEASED;
	}
        
	if( phwnd )
	{
		return _ped->TxGetWindow(phwnd);
	}
	return E_INVALIDARG;
}

/*
 *	COleObject::ContextSensitiveHelp
 *
 *	@mfunc	Implemenation of IOleInPlaceSite::ContextSensitiveHelp
 *
 *	@rdesc	HRESULT
 */
 STDMETHODIMP COleObject::ContextSensitiveHelp(
 	BOOL fEnterMode)	//@parm, if TRUE, then we're in help mode
 {
 	IRichEditOleCallback *precall;
	CCallMgr	callmgr(_ped);
	CStabilize	stabilize(this);
	CObjectMgr  *pCObM = NULL;

	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, 
			"COleObject::ContextSensitiveHelp");

    if( IsZombie() )
	{
        return CO_E_RELEASED;
	}
        
	// if the mode changes
	if (pCObM = _ped->GetObjectMgr())
	{
    	if( pCObM->GetHelpMode() != fEnterMode )
    	{
    		pCObM->SetHelpMode(fEnterMode);

    		precall = _ped->GetRECallback();

    		if( precall )
    		{
    			return precall->ContextSensitiveHelp(fEnterMode);
    		}
	    }
	}
	return NOERROR;
}

/*
 *	COleObject::CanInPlaceActivate
 *
 *	@mfunc	implementation of IOleInPlaceSite::CanInPlaceActivate
 *
 *	@rdesc	NOERROR or S_FALSE
 */
STDMETHODIMP COleObject::CanInPlaceActivate(void)
{
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, 
			"COleObject::CanInPlaceActivate");

    if( IsZombie() )
	{
        return CO_E_RELEASED;
	}
        
	// if we have a callback && the object is willing to show
	// content, then we can in-place activate

	if( _ped->GetRECallback() && 
		_pi.dvaspect == DVASPECT_CONTENT )
	{
		return NOERROR;
	}
	else
	{
		return S_FALSE;
	}
}

/*
 *	COleObject::OnInPlaceActivate
 *
 *	@mfunc	implementation of IOleInPlaceSite::OnInPlaceActivate
 *
 *	@rdesc	noerror
 */
STDMETHODIMP	COleObject::OnInPlaceActivate(void)
{
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::OnInPlaceActivate");
	// assume that in-place objects can never be blank.
	_pi.dwFlags &= ~REO_BLANK;
	_fInPlaceActive = TRUE;

	return NOERROR;
}

/*
 *	COleObject::OnUIActivate
 *
 *	@mfunc	implementation of IOleInPlaceSite::OnUIActivate.  Notifies
 *			the container that the object is about to be activated in
 *			place with UI elements suchs as merged menus
 *
 *	@rdesc	HRESULT
 */
STDMETHODIMP COleObject::OnUIActivate(void)
{
	IRichEditOleCallback *precall;
	CTxtSelection *psel;
	CCallMgr	callmgr(_ped);
	CStabilize stabilize(this);
	CObjectMgr *pobjmgr;

	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::OnUIActivate");

    if( IsZombie() )
	{
        return CO_E_RELEASED;
	}
        
	pobjmgr = _ped->GetObjectMgr();
	if(!pobjmgr)
		{
		return E_OUTOFMEMORY;
		}
	precall = pobjmgr->GetRECallback();

	if( precall )
	{
		precall->ShowContainerUI(FALSE);
	    if( IsZombie() )
		{
	        return CO_E_RELEASED;
		}
        
		// this is an optimization for activating multiple
		pobjmgr->SetShowUIPending(FALSE);

⌨️ 快捷键说明

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