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

📄 coleobj.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	preobj->cp = _cp;
	
	if( _punkobj->QueryInterface(IID_IOleObject, (void **)&poo) == NOERROR )
	{
		// don't worry about failures here
		poo->GetUserClassID(&(preobj->clsid));
	}
	
	preobj->dwFlags 	= _pi.dwFlags;
	preobj->dvaspect 	= _pi.dvaspect;
	preobj->dwUser 		= _pi.dwUser;
	preobj->sizel		= _sizel;		

   	if( (dwFlags & REO_GETOBJ_POLEOBJ) )
	{
		preobj->poleobj = poo;
		if( poo )
		{
			poo->AddRef();
		}
	}
	else
	{
		preobj->poleobj = NULL;
	}

    if( poo )
        poo->Release();

    if( IsZombie() )
	{
        return CO_E_RELEASED;
	}
        
	if( (dwFlags & REO_GETOBJ_PSTG) )
	{
		preobj->pstg = _pstg;
		if( _pstg )
		{
			_pstg->AddRef();
		}
	}
	else
	{
		preobj->pstg = NULL;
	}

	if( (dwFlags & REO_GETOBJ_POLESITE) )
	{
		// COMPATIBILITY HACK!!  Note that we don't 'release' any pointer that
		// may already be in the stored in the site.  RichEdit1.0 always sets
		// the value, consequently several apps pass in garbage for the site.
		//
		// If the site was previously set, we will get a reference counting
		// bug, so be sure that doesn't happen!
     
       	preobj->polesite = (IOleClientSite *)this;
       	AddRef();
 	}
	else
	{
		preobj->polesite = NULL;
	}
	return NOERROR;
}	

/*
 *	COleObject::IsLink
 *
 *	@mfunc	returns TRUE if the object is a link
 *
 *	@rdesc	BOOL
 */
BOOL COleObject::IsLink()
{
	return !!(_pi.dwFlags & REO_LINK);
}


/*
 *	COleObject::InitFromREOBJECT
 *
 *	@mfunc	initializes this object's state from the given
 *			REOBJECT data structure
 *
 *	@rdesc	HRESULT
 */
HRESULT COleObject::InitFromREOBJECT(
	DWORD	cp,			//@parm the cp for the object
	REOBJECT *preobj)	//@parm	the data to use for initialization
{
	IOleLink *plink;
	HRESULT	hr = E_INVALIDARG;
	CRchTxtPtr rtp(_ped, 0);
	POINT pt;
	
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEINTERN, "COleObject::InitFromREOBJECT");
	
	Assert(_punkobj == NULL);
    if( IsZombie() )
	{
        return CO_E_RELEASED;
	}

	_cp = cp;

	if( preobj->poleobj )
	{
		hr = preobj->poleobj->QueryInterface(IID_IUnknown, (void **)&_punkobj);
	}
	else
	{
		_punkobj = (IOleClientSite *) this;
		AddRef();
		hr = NOERROR;
	}
        
	if( hr != NOERROR )
	{
		return hr;
	}
	
	_pstg = preobj->pstg;
	if( _pstg )
	{
		_pstg->AddRef();
	}

	_pi.dwFlags = preobj->dwFlags & REO_READWRITEMASK;
	_pi.dwUser = preobj->dwUser;
	_pi.dvaspect = preobj->dvaspect;

	_sizel = preobj->sizel;		// COMPATIBILITY ISSUE: the RE1.0 code had some
								// stuff to deal with REO_DYNAMICSIZE here.  We
								// do not currently support that.
	
	if( _punkobj->QueryInterface(IID_IOleLink, (void **)&plink) == NOERROR )
	{
		_pi.dwFlags |= REO_LINK | REO_LINKAVAILABLE;
		plink->Release();
	}

    if( IsZombie() )
	{
        return CO_E_RELEASED;
	}
        
	if( IsEqualCLSID(preobj->clsid, CLSID_StaticMetafile) ||
		IsEqualCLSID(preobj->clsid, CLSID_StaticDib) ||
		IsEqualCLSID(preobj->clsid, CLSID_Picture_EnhMetafile) )
	{
		_pi.dwFlags |= REO_STATIC;
	}
	else if( IsExcelCLSID(preobj->clsid) )
	{
		_pi.dwFlags |= REO_GETMETAFILE;
	}
	else if( IsEqualCLSID(preobj->clsid, CLSID_WordArt ) )
	{
		_fIsWordArt2 = TRUE;
	}
	else if(IsEqualCLSID(preobj->clsid, CLSID_PaintbrushPicture) ||
			IsEqualCLSID(preobj->clsid, CLSID_BitmapImage))
	{
		_fIsPaintBrush = TRUE;

		// These calls will initialize the flag, _fPBUseLocalSizel, which
		// indicates that for this PB object, SetExtent calls are not 
		// acknowledged by the object, and we are to use our local value
		// of _sizel as the object extents.
		FetchObjectExtents();
		SetExtent(SE_NOTACTIVATING);
	}

	hr = ConnectObject();

    if( IsZombie() )
	{
        return CO_E_RELEASED;
	}
        
	// this is a bit non-intuitive, but we need to figure out
	// where the object would be so that it can inplace activate correctly.

	if( cp )
	{
		cp--;
	}

	rtp.SetCp(cp);

	_ped->_pdp->PointFromTp(rtp, NULL, FALSE, pt, NULL, TA_TOP);
	_rcPos.top = _rcPos.bottom = pt.y;	//bottom will be set below in
		                                    // FetchExtents
	_rcPos.left = _rcPos.right = pt.x;

	if (preobj->sizel.cx || preobj->sizel.cy)
	{
		_sizel = preobj->sizel;
	}
	else
	{
		FetchObjectExtents();
	}
	ResetPosRect();

    if( IsZombie() )
	{
        return CO_E_RELEASED;
	}
    
    // finally, lock down Link objects so they we don't try to refetch their
	// extents from the server.  After initialization, link object size is
	// entirely determined by the container.
	if( (_pi.dwFlags & REO_LINK) )
    {
        // so we don't call GetExtents on remeasuring.
        _fSetExtent = TRUE;
	}
	return NOERROR;
}


/*
 *	COleObject::MeasureObj(pdp, xWidth, yHeight, yDescent)
 *
 *	@mfunc	calculates the size of this object in device units
 *
 *	@rdesc	void
 */
void COleObject::MeasureObj(
	const CDisplay *pdp,	//@parm	the device to measure for 
	LONG &xWidth,			//@parm the width of the object 
	LONG &yHeight,
	SHORT yDescent)		   	//@parm the height of the object
{
	xWidth = pdp->HimetricXtoDX(_sizel.cx);
	yHeight = pdp->HimetricYtoDY(_sizel.cy);
	if (!(_pi.dwFlags & REO_BELOWBASELINE))
	{
		yHeight += yDescent;
	}
}

/* 
 * COleObject::InHandle
 *
 * @mfunc  See if a point is in the rectangle defined by the handle at
 *		the given coordinates.
 *
 * @rdesc True if point is in handle.
 * 
 */
BOOL COleObject::InHandle(
	int x,	//@parm x pos of upper left corner coordinate of the handle box.
	int y,	//@parm y pos of upper left corner coordinate of the handle box.
	const POINT &pt)	//@parm point to check
{
    RECT    rc;
	BOOL	fRet;
    
    rc.left = x;
    rc.top = y;
	//Add one to bottom right because PtInRect does not consider
	//points on bottom or right to be in rect.
    rc.right = x + dxyHandle + 1;
    rc.bottom = y + dxyHandle + 1;
    fRet = PtInRect(&rc, pt);

	return fRet;
}  

/*
 *	COleObject::CheckForHandleHit
 *
 *	@mfunc	Check for a hit on any of the frame handles.
 *
 *	@rdesc	 NULL if no hit, cursor resource ID if there is a hit.
 *
 */
LPTSTR COleObject::CheckForHandleHit(
	const POINT &pt)	//@parm POINT containing client coord. of the cursor.
{
	RECT	rc;

	// if the object is not resizeable, no chance of hitting a resize
	// handle!
	if( !(_pi.dwFlags & REO_RESIZABLE) )
	{
		return NULL;
	}

	CopyRect(&rc, &_rcPos);

	if (!_dxyFrame)
	{
		_dxyFrame = dxyFrameDefault;
	}

	//Check to see if point is farther into the interior of the
	//object than the handles extent. If it is we can just bail.
	InflateRect(&rc, -(_dxyFrame + dxyHandle), -(_dxyFrame + dxyHandle));
	if (PtInRect(&rc, pt))
	{
		return NULL;
	}

	//Check to see if point is in any of the handles and
	//return the proper cursor ID if it is.
	InflateRect(&rc, dxyHandle, dxyHandle);

	if(InHandle(rc.left, rc.top, pt) ||
	   InHandle(rc.right-dxyHandle, rc.bottom-dxyHandle, pt))
	{
		return IDC_SIZENWSE;
	}
	if(InHandle(rc.left, rc.top+(rc.bottom-rc.top-dxyHandle)/2, pt) ||
	   InHandle(rc.right-dxyHandle,
			rc.top+(rc.bottom-rc.top-dxyHandle)/2, pt))
	{
		return IDC_SIZEWE;
	}
	if(InHandle(rc.left, rc.bottom-dxyHandle, pt) ||
	   InHandle(rc.right-dxyHandle, rc.top, pt))
	{
		return IDC_SIZENESW;
	}
	if(InHandle(rc.left+(rc.right-rc.left-dxyHandle)/2, rc.top, pt) ||
	   InHandle(rc.left+(rc.right-rc.left-dxyHandle)/2,
			rc.bottom-dxyHandle, pt))
	{
		return IDC_SIZENS;
	}
	return NULL;
}

/* 
 * COleObject::DrawHandle
 *
 * @mfunc  Draw a handle on the object frame at the specified coordinate
 *
 * @rdesc void
 * 
 */
void COleObject::DrawHandle(
	HDC hdc,	//@parm HDC to be drawn into
	int x,		//@parm x pos of upper left corner coordinate of the handle box
	int y)		//@parm y pos upper left corner coordinate of the handle box
{
    RECT    rc;
    
	//Draw the handle by inverting.
    rc.left = x;
    rc.top = y;
    rc.right = x + dxyHandle;
    rc.bottom = y + dxyHandle;
    InvertRect(hdc, (LPRECT)&rc);
}  

/*
 *	COleObject::DrawFrame
 *
 *	@mfunc	Draw a frame around the object.  Invert if required and
 *		include handles if required.
 *
 *	@rdesc	void
 *
 */
void COleObject::DrawFrame(
	const CDisplay *pdp,    //@parm the display to draw to
	HDC             hdc,	//@parm the device context
	RECT           *prc)  //@parm the rect around which to draw
{
	RECT	rc;

	CopyRect(&rc, prc);

	if (_pi.dwFlags & REO_INVERTEDSELECT)
	{
		//Invert entire object
		InvertRect(hdc, &rc);
	}
	else
	{
		// Just the border, so use a null brush
		SaveDC(hdc);
		SetROP2(hdc, R2_NOT);
		SelectObject(hdc, GetStockObject(NULL_BRUSH));
		Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom);
		RestoreDC(hdc, -1);
	}

	if (_pi.dwFlags & REO_RESIZABLE)
	{
		int     bkmodeOld;
		HPEN	hpen;
		LOGPEN	logpen;

		bkmodeOld = SetBkMode(hdc, TRANSPARENT);
		Assert(bkmodeOld);

		//Get the frame width
		_dxyFrame = dxyFrameDefault;
		hpen = (HPEN)GetCurrentObject(hdc, OBJ_PEN);
		if( W32->GetObject(hpen, sizeof(LOGPEN), &logpen) )
		{
			if( logpen.lopnWidth.x )
			{
				_dxyFrame = (SHORT)logpen.lopnWidth.x;
			}
		}

		// Draw the handles inside the rectangle boundary
 		InflateRect(&rc, -_dxyFrame, -_dxyFrame);

		DrawHandle(hdc, rc.left, rc.top);
		DrawHandle(hdc, rc.left, rc.top	+ (rc.bottom-rc.top-dxyHandle)/2);
		DrawHandle(hdc, rc.left, rc.bottom-dxyHandle);
		DrawHandle(hdc, rc.left + (rc.right - rc.left - dxyHandle)/2, rc.top);
		DrawHandle(hdc, rc.left+(rc.right-rc.left-dxyHandle)/2,
			rc.bottom-dxyHandle);
		DrawHandle(hdc, rc.right-dxyHandle, rc.top);
		DrawHandle(hdc, rc.right-dxyHandle,
			rc.top+(rc.bottom-rc.top-dxyHandle)/2);
		DrawHandle(hdc, rc.right-dxyHandle, rc.bottom-dxyHandle);

		SetBkMode(hdc, bkmodeOld);
	}
}


/*
 *	COleObject::CreateDib
 *
 *	@mfunc	Create DIB for Windows CE display
 *
 *	@rdesc	void
 *
 */
void COleObject::CreateDib(HDC hdc)
{
    BYTE            *pbDib;
	HGLOBAL			hnew = NULL;
	BYTE			*pbSrcBits;
	LPBITMAPINFO	pbmi = (LPBITMAPINFO) GlobalLock(_hdata);
	int				iBitsPerPix, iAdjustedWidth, iNumColors;
	DWORD			dwColors, dwImage;

	iBitsPerPix = pbmi->bmiHeader.biBitCount;

	ASSERT(iBitsPerPix == 1 || iBitsPerPix == 4 ||
		iBitsPerPix == 8 || iBitsPerPix == 16 || iBitsPerPix == 24 || iBitsPerPix == 32);

	iAdjustedWidth = ((pbmi->bmiHeader.biWidth * iBitsPerPix + 31) & ~31) / 8;

	iNumColors = pbmi->bmiHeader.biClrUsed;

	if ((iNumColors == 0) && (iBitsPerPix <= 8)){
		iNumColors = 1 << iBitsPerPix;
	}

	dwColors = iNumColors * sizeof(RGBQUAD) + (pbmi->bmiHeader.biCompression == BI_BITFIELDS ? 3 * sizeof(DWORD) : 0);		
	dwImage = pbmi->bmiHeader.biHeight * iAdjustedWidth;

	// Bitmap bits location
	pbSrcBits = (BYTE*)(pbmi) + sizeof(BITMAPINFOHEADER) + dwColors;

	if(16 == iBitsPerPix &&
		(pbmi->bmiHeader.biCompression == BI_BITFIELDS))	
	{
		// Sixteen-bit case: fill in the bitfields mask for 565
		#define MASK565_0    0x0000F800
		#define MASK565_1   0x000007E0
		#define MASK565_2   0x0000001F

		((DWORD*)(pbmi->bmiColors))[0] = MASK565_0;
		((DWORD*)(pbmi->bmiColors))[1] = MASK565_1;
		((DWORD*)(pbmi->bmiColors))[2] = MASK565_2;
	}

	_hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&pbDib, NULL, 0);
	if (_hdib == NULL)
	{
		DWORD dwle = ::GetLastError();

        _ped->GetCallMgr()->SetOutOfMemory();

        // V-GUYB:
        // Do not attempt to repaint this picture until the user starts typing in the
        // control. This allows the user to dismiss the oom that will appear and then
        // save the document, and then free up some space. If we don't do this here, 
        // every time the oom msg is dismissed it will appear again. This doesn't allow 
        // the user to save the document unless they can find some memory to free.
        _fDraw = FALSE;

		TRACEWARNSZ("Out of memory creating DIB");
		return;
	}

	// Move Bitmap bits
	CopyMemory(pbDib, pbSrcBits, dwImage);

	GlobalUnlock(pbmi);
	GlobalFree(hnew);
}

/*
 *	COleObject::DrawDib : Auxiliary function
 *
 *	@mfunc	draws the dib in the given dc
 *
 *	@rdesc void
 */
void COleObject::DrawDib(
	HDC hdc,
	RECT *prc
)
{
//	HDC hdcMem = CreateCompatibleDC(hdc);
	HDC hdcMem; // V-GUYB: Create hdcMem later in case we return early.
	LPBITMAPINFO	pbmi;

	if (!_hdib)
		{
		CreateDib(hdc);
		}
	// If _hdib is still NULL, just return.  Maybe out of memory.
	if (!_hdib)
		{
		goto leave;
		}

    // V-GUYB: NOW create the mem dc.
	hdcMem = CreateCompatibleDC(hdc);
	if(!hdcMem)
		{
		goto leave;
		}     

	pbmi = (LPBITMAPINFO) LocalLock(_hdata);
	SelectObject(hdcMem, _hdib);

    StretchBlt(hdc, prc->left, prc->top,
			prc->right - prc->left, prc->bottom - prc->top,
			hdcMem, 0, 0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight, SRCCOPY);

	GlobalUnlock(pbmi);
	DeleteDC(hdcMem);
leave:
	return;
}

/*
 *	COleObject::DrawObj
 *
 *	@mfunc	draws the object
 *
 *	@rdesc void
 */
void COleObject::DrawObj(
const CDisplay *pdp,	//@parm the display object for the view
	HDC hdc,				//@parm the drawing HDC (can be different
							//than the display.
	BOOL fMetafile,			//@parm whether the HDC is a metafile
	POINT *ppt,			 	//@parm top left corner of where to draw
	RECT  *prcRender)       //@parm pointer to render rectangle
{
	RECT rc, rc1;
	IViewObject *pvo;
	CDisplayPrinter *pdpPrint;
	LONG adjust = 0;
	CObjectMgr * pobjmgr = _ped->GetObjectMgr();

    if (NULL == pobjmgr)
    {
        Assert(pobjmgr);
        SetLastError(ERROR_OUTOFMEMORY);
        return;
    }
    

	// if we aren't running in transparent mode, 
	// Clear the space in the render rectangle
	// This includes space for the object
	// It also includes any surrounding space
	if( !_ped->_fTransparent )
	{
		rc1.left = prcRender->left;
		rc1.top = prcRender->top;

⌨️ 快捷键说明

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