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

📄 coleobj.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			SetExtent(SE_ACTIVATING);
		}

		HRESULT			hr;
		hr = poo->DoVerb(OLEIVERB_PRIMARY, &msg, (LPOLECLIENTSITE)this, 0, hwnd, &_rcPos);

#ifndef MACPORT
		if (FAILED(hr))
		{
			ENOLEOPFAILED	enoleopfailed;

			enoleopfailed.iob = _ped->_pobjmgr->FindIndexForCp(GetCp());
			enoleopfailed.lOper = OLEOP_DOVERB;
			enoleopfailed.hr = hr;
	        _ped->TxNotify( EN_OLEOPFAILED, &enoleopfailed );
		}
#endif
	    poo->Release();
	}
	else
	{
		return FALSE;
	}
	return TRUE;
}

/*
 *	COleObject::DeActivateObj
 *	
 *	@mfunc Deactivates the object.
 *
 */
HRESULT COleObject::DeActivateObj(void)
{
	IOleInPlaceObject * pipo;
	IOleObject *poo;
	MSG msg;
	HRESULT hr;

	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEINTERN, "COleObject::DeActivateObj");

	ResetPosRect();

	if( _punkobj->QueryInterface(IID_IOleInPlaceObject, (void **)&pipo) 
		== NOERROR )
	{

		if( (hr  =_punkobj->QueryInterface(IID_IOleObject, (void **)&poo)) ==
				NOERROR ) 
		{
			// this code is a bit different from 1.0, but seems to 
			// make things work a bit better.  Basically, we've taken a leaf
			// from various sample apps and do the most brute force "de-activate"
			// possible (you'd think just one call would be enough ;-)

			// don't bother with the error return here.
			pipo->UIDeactivate();
			
			//fake something
			ZeroMemory(&msg, sizeof(MSG));
			msg.message = WM_LBUTTONDOWN;	
			_ped->TxGetWindow(&msg.hwnd);

			// again, don't bother checking for errors; we need to
			// plow through and get rid of stuff as much as possible.
			poo->DoVerb(OLEIVERB_HIDE, &msg, (IOleClientSite *)this,
				-1, msg.hwnd, &_rcPos);

			// COMPATIBILITY ISSUE (alexgo): the RE1.0 code did some funny
			// stuff with undo here, but I don't think it's necessary now
			// with our multi-level undo model.
			hr = pipo->InPlaceDeactivate();

			poo->Release();
		}

	    pipo->Release();

		return hr;
	}
	return NOERROR; 
}

/*
 *	COleObject::Convert
 *
 *	@mfunc	Converts the object to the specified class.  Does reload
 *		the object but does NOT force an update (caller must do this).
 *
 *	@rdesc
 *		HRESULT				Success code.
 */
HRESULT COleObject::Convert( 
	REFCLSID rclsidNew,			//@parm the destination clsid
	LPCSTR lpstrUserTypeNew)	//@parm the new user type name
{
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::Convert");

	CLIPFORMAT cfOld;
	CLSID clsidOld;
	LPOLESTR szUserTypeOld = NULL;
	HRESULT hr;
	HRESULT hrLatest;
	UsesMakeOLESTR;


	// If object has no storage, return
	if (!_pstg)
	{
		return ResultFromScode(E_INVALIDARG);
	}

	// Read the old class, format, and user type in
	if ((hr = pReadClassStg(_pstg, &clsidOld)) ||
		(hr = pReadFmtUserTypeStg(_pstg, &cfOld, &szUserTypeOld)))
	{
		return hr;
	}

	// Unload the object
	Close(OLECLOSE_SAVEIFDIRTY);
	_punkobj->Release();

    if( IsZombie() )
	{
        return CO_E_RELEASED;
	}

	// Write the new class and user type, but old format, into the storage
	if ((hr = pWriteClassStg(_pstg, rclsidNew)) ||
		(hr = pWriteFmtUserTypeStg(_pstg, cfOld,
			(LPOLESTR) MakeOLESTR(lpstrUserTypeNew))) ||
		(hr = pSetConvertStg(_pstg, TRUE)) ||
		((hr = _pstg->Commit(0)) && (hr = _pstg->Commit(STGC_OVERWRITE))))
	{
		// Uh oh, we're in a bad state; rewrite the original info
		(VOID) pWriteClassStg(_pstg, clsidOld);
		(VOID) pWriteFmtUserTypeStg(_pstg, cfOld, szUserTypeOld);
	}

    if( IsZombie() )
	{
        return CO_E_RELEASED;
	}

	// Reload the object and connect. If we can't reload it, delete it.
	hrLatest = pOleLoad(_pstg, IID_IOleObject, (LPOLECLIENTSITE) this,
			(void **)&_punkobj);

	if (hrLatest != NOERROR)
	{
		CRchTxtPtr	rtp(_ped, _cp);

		// we don't want the delete of this object to go on the undo
		// stack.  We use a space so that cp's will work out right for
		// other undo actions.
		rtp.ReplaceRange(1, 1, L" ", NULL, -1);
	}
	else
	{
		ConnectObject();
	}

	// Free the old
	pCoTaskMemFree(szUserTypeOld);
	return hr ? hr : hrLatest;
}

/*
 *	COleObject::ActivateAs
 *
 *	@mfunc	Handles a request by the user to activate all objects of a particular
 *		class as objects of another class.
 *
 *	@rdesc
 *		HRESULT				Success code.
 */
HRESULT COleObject::ActivateAs(REFCLSID rclsid, REFCLSID rclsidAs)
{
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::ActivateAs");

	HRESULT hr = NOERROR;
	IOleObject * poo = NULL;
	CLSID	clsid;


	//Get the clsid of the object.
	hr = _punkobj->QueryInterface(IID_IOleObject, (void **)&poo);
	if( hr == NOERROR )
	{
		//NOTE:  We are depending on the behavior of GetUserClassID to
		//return the current clsid of the object (not the TreatAs id).
		//This should hold true as long as long as we haven't reloaded
		//it yet.  If there are problems with ActivateAs in the future,
		//this might be a suspect.
		hr = poo->GetUserClassID(&clsid);
		poo->Release();
	}

	if( hr != NOERROR )
	{
		return hr;
	}
	
    if( IsZombie() )
	{
        return CO_E_RELEASED;
	}

	//Check to see if the clsid of the object matches the clsid to be
	//treated as something else. If it is we need to unload and reload
	//the object.
	if( IsEqualCLSID(clsid, rclsid) )
	{
		// Unload the object
		Close(OLECLOSE_SAVEIFDIRTY);
		_punkobj->Release();

		if( IsZombie() )
		{
			return CO_E_RELEASED;
		}

		// Reload the object and connect. If we can't reload it, delete it.
		hr = pOleLoad(_pstg, IID_IOleObject, (LPOLECLIENTSITE) this,
				(void **)&_punkobj);

		if (hr != NOERROR)
		{
			CRchTxtPtr	rtp(_ped, _cp);

			// We don't want the delete of this object to go on the undo
			// stack.  We use a space so that cp's will work out right for
			// other undo actions.
			rtp.ReplaceRange(1, 1, L" ", NULL, -1);
		}
		else
		{
			ConnectObject();
		}
	}

	return hr;
}

/*
 *	COleObject::SetLinkAvailable
 *
 *	@mfunc
 *		Allows client to tell us whether the link is available or not.
 *
 *	@rdesc
 *		HRESULT				Success code.
 */
HRESULT COleObject::SetLinkAvailable( 
	BOOL fAvailable)	//@parm	if TRUE, make object linkable
{
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::SetLinkAvailable");
	
	// If this is not a link, return
	if (!(_pi.dwFlags & REO_LINK))
	{
		return E_INVALIDARG;
	}

	// Set the flag as appropriate
	if (fAvailable)
	{
		_pi.dwFlags |= REO_LINKAVAILABLE;
	}
	else
	{
		_pi.dwFlags &= ~REO_LINKAVAILABLE;
	}
	return NOERROR;
}

/*
 *	COleObject::WriteTextInfoToEditStream
 *
 *	@mfunc
 *		Used for textize support,  Tries to determine the text
 *		representation for an object and then writes that info
 *		to the given stream.  The only thing this is particularly useful
 *		for is to support richedit1.0's TEXTIZED data format.
 *
 *	@rdesc
 *		LONG				Number of chras written..
 */
LONG COleObject::WriteTextInfoToEditStream(
	EDITSTREAM *pes)
{
	LONG cch;
	LONG cbWritten = 0;
	HRESULT hr;
	IOleObject *poo;
	IDataObject *pdataobj;
	STGMEDIUM med;
	char *pch;			//we only deal with ANSI data here

	HANDLE		hGlobal;


	if((hr = _punkobj->QueryInterface(IID_IOleObject, (void **)&poo)) == NOERROR )
	{
		hr = poo->GetClipboardData( 0, &pdataobj);
        poo->Release();
	}

	if(FAILED(hr))
	{
		hr = _punkobj->QueryInterface(IID_IDataObject, (void **)&pdataobj);
		if(FAILED(hr))
		{
			pes->dwError = (DWORD) E_FAIL;
			goto Default;
		}
	}

	med.tymed = TYMED_HGLOBAL;
	med.pUnkForRelease = NULL;
	med.hGlobal = NULL;

	hr = pdataobj->GetData(&g_rgFETC[iAnsiFETC], &med);
	if(FAILED(hr))
	{
		pes->dwError = (DWORD)hr;
	}
	else
	{
		hGlobal = med.hGlobal;
		pch = (char *)GlobalLock(hGlobal);
		if( pch )
		{
			for (cch = 0; pch[cch]; cch++);
			pes->dwError = pes->pfnCallback(pes->dwCookie, (BYTE *)pch, cch,
												&cbWritten);
			GlobalUnlock(hGlobal);
		}

		pReleaseStgMedium(&med);
	}

Default:

	if(cbWritten <= 0)
	{
		char ch = ' ';

		pes->pfnCallback(pes->dwCookie, (BYTE *)&ch, sizeof(char), &cbWritten);
		pes->dwError = 0;
	}

    pdataobj->Release();
	return cbWritten;
}

/*
 *	COleObject::SetDvaspect
 *
 *	@mfunc	Allows client to tell us which aspect to use and force us
 *		to recompute positioning and redraw.
 *
 */
void COleObject::SetDvaspect( 
	DWORD dvaspect)	//@parm	the aspect to use
{
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::SetDvaspect");

	_pi.dvaspect = dvaspect;
	
	// Cause ourselves to redraw and update
	OnViewChange(dvaspect, (DWORD) -1);
}

/*
 *	COleObject::HandsOffStorage
 *
 *	@mfunc	See IPersistStore::HandsOffStorage.
 *
 */
void COleObject::HandsOffStorage(void)
{
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::HandsOffStorage");

	// Free the storage we currently have, if we have one.
	SafeReleaseAndNULL((IUnknown**)&_pstg);
}

/*
 *	COleObject::SaveCompleted
 *
 *	@mfunc	See IPersistStore::SaveCompleted.
 *
 */
void COleObject::SaveCompleted(
	LPSTORAGE lpstg)	//@parm	new storage
{
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::SaveCompleted");

	// Did our caller give us a new storage to remember?
	if (lpstg)
	{
		// Free the storage we currently have, if we have one
		if (_pstg)
		{
			SafeReleaseAndNULL((IUnknown**)&_pstg);
		}

		// Remember the storage we are given, since we are given one
		lpstg->AddRef();
		_pstg = lpstg;
	}
}

/*
 *	SetAllowedResizeDirections
 *	
 *	@func Resizing helper function
 *
 */
static void SetAllowedResizeDirections(
	const POINT  & pt,
	const RECT   & rc,
	      LPTSTR   lphand,
	      BOOL   & fTop,
	      BOOL   & fBottom,
	      BOOL   & fLeft,
	      BOOL   & fRight
)
{
   	fTop = abs(pt.y - rc.top) < abs(pt.y - rc.bottom);
	fBottom = !fTop;
	fLeft = abs(pt.x - rc.left) < abs(pt.x - rc.right);
	fRight = !fLeft;
	if (lphand == IDC_SIZENS)
	{
		fLeft = fRight = FALSE; 
	}
	else if (lphand == IDC_SIZEWE)
	{
		fTop = fBottom = FALSE;
	}
	return;
}

/*
*	SetRestriction.
 *	
 *	@func Resizing helper function determines bounding rectangle for resizing.
 *
 */
static void SetRestriction(
    RECT  & rc,
	HWND    hwnd,
	DWORD   dwScroll
)
{
	GetClientRect(hwnd, &rc);
	InflateRect(&rc, -1, -1);			// So rectangle is visible

	// allow objects to grow larger than the window in the
	// directions which have scrollbars
	if(dwScroll & WS_HSCROLL)
	{
		rc.right = MAXLONG;
	}
	if(dwScroll & WS_VSCROLL)
	{
		rc.bottom = MAXLONG;
	}
	return;
}

/*
*	Restrict
 *	
 *	@func Resizing helper function bounds a point within a rectangle
 *
 */
static void Restrict(
	POINT  &pt,
	RECT   &rc
)
{
	if (pt.x < rc.left)
	{
		pt.x = rc.left;
	}
	else if (pt.x > rc.right)
	{
		pt.x = rc.right;
	}
	if (pt.y < rc.top)
	{
		pt.y = rc.top;
	}
	else if (pt.y > rc.bottom)
	{
		pt.y = rc.bottom;
	}
	return;
}

/*
 *	COleObject::HandleResize
 *	
 *	@mfunc Deal with object resizing.
 *
 */
BOOL COleObject::HandleResize(const POINT &pt)
{
	LPTSTR lphand;
	DWORD  dwFlags = _pi.dwFlags;
	HDC    hdc;
 	HWND   hwnd;
	RECT   rcOld;
	RECT   rcRestrict;
	BOOL   fTop, fBottom, fLeft, fRight;
	BOOL   fEscape;
	CDisplay *pdp = _ped->_pdp;

	if (!(dwFlags & REO_SELECTED)	||
		!(dwFlags & REO_RESIZABLE)	||
		(lphand = CheckForHandleHit(pt)) == NULL || !pdp)
	{
		return FALSE;
	}
 	
	hdc = pdp->GetDC();
	rcOld = _rcPos;				// Save old size
	_ped->TxGetWindow(&hwnd);
	ASSERT(IsWindow(hwnd));
	SetCapture(hwnd);
	
	SetRestriction( rcRestrict, hwnd, _ped->TxGetScrollBars() );

	SetAllowedResizeDirections(pt, _rcPos, lphand,
		                       fTop, fBottom, fLeft, fRight);
	
	// Erase and redraw frame without handles.
	DrawFrame(pdp, hdc, &_rcPos);
	_pi.dwFlags = REO_NULL;
	DrawFrame(pdp, hdc, &_rcPos);

	fEscape = FALSE;
	const INT vkey = GetSystemMetrics(SM_SWAPBUTTON) ? VK_RBUTTON : VK_LBUTTON;
	while (GetAsyncKeyState(vkey) & 0x8000)
	{		
		POINT ptLast = pt;
		POINT ptCur;
		MSG msg;

		// Stop if the ESC key has been pressed
		if (GetAsyncKeyState(VK_ESCAPE) & 0x0001)
		{
			fEscape = TRUE;
			break;
		}
		
		GetCursorPos(&ptCur);
		ScreenToClient(hwnd, &ptCur);

// GetCursorPos() isn't supported on WinCE. We have  it hacked to
// be GetMessagePos() which unfortunately in this case will cause
// ptCur to never change. By removing this check we end up drawing
// multiple times when the user pauses during a resize. 
#ifndef UNDER_CE
		// If mouse hasn't moved, try again
		if ((ptCur.x == ptLast.x) && (ptCur.y == ptLast.y))
		{
			continue;
        }
#endif
		ptLast = ptCur;

		Restrict( ptCur, rcRestrict );

		// Erase old rectangle, update rectangle, and redraw
		DrawFrame(pdp, hdc, &_rcPos);	
		if (fLeft)   _rcPos.left   = ptCur.x;
		if (fRight)  _rcPos.right  = ptCur.x;
		if (fTop)    _rcPos.top    = ptCur.y;
		if (fBottom) _rcPos.bottom = ptCur.y;
		// Keep a minimun width and height
		INT xWidthSys = pdp->GetXWidthSys();
		

⌨️ 快捷键说明

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