📄 coleobj.cpp
字号:
rc1.right = ppt->x + _rcPos.right - _rcPos.left;
rc1.bottom = prcRender->bottom;
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc1, NULL, 0, NULL);
}
if( _fInPlaceActive || !_fDraw)
{
// if we're inplace active, don't do anything, the
// server is drawing for us.
// We also don't do anything prior to the fDraw property being set
return;
}
ResetPosRect(&adjust); // Update position rectangle
// Draw the object where we are asked within the rendering rectangle
rc.top = ppt->y;
rc.top += adjust;
// Note we always convert bottom and top because this code is executed for
// all draws which can in turn be for the screen, the printer or a metafile.
rc.bottom = rc.top + MulDiv(_rcPos.bottom - _rcPos.top, pdp->GetXPerInch(),
sysparam.GetXPerInchScreenDC());
rc.left = ppt->x;
rc.right = rc.left + MulDiv(_rcPos.right - _rcPos.left, pdp->GetYPerInch(),
sysparam.GetYPerInchScreenDC());
SaveDC(hdc);
SetTextAlign(hdc, TA_TOP);
SaveDC(hdc); // calls to OLE object (IViewObject::Draw or OleDraw) might change HDC
if (_hdata)
{
// This is some Windows CE Dib, let's try the direct approach
DrawDib( hdc, &rc );
}
else if( fMetafile )
{
if( _punkobj->QueryInterface(IID_IViewObject, (void **)&pvo)
== NOERROR )
{
pdpPrint = (CDisplayPrinter *)pdp;
rc1 = pdpPrint->GetPrintPage();
// fix up rc for Draw()
rc1.bottom = rc1.bottom - rc1.top;
rc1.right = rc1.right - rc1.left;
pvo->Draw(_pi.dvaspect, -1, NULL, NULL, 0, hdc, (RECTL *)&rc,
(RECTL *)&rc1, NULL, 0);
pvo->Release();
}
}
else
{
pOleDraw(_punkobj, _pi.dvaspect, hdc, &rc);
}
RestoreDC(hdc, -1);
// Do selection stuff if the this is for the main (screen) view.
if (pdp->IsMain())
{
if( _pi.dwFlags & REO_OPEN )
{
OleUIDrawShading(&rc, hdc);
}
//If the object has been selected by clicking on it, draw
//a frame and handles around it. Otherwise, if we are selected
//as part of a range, invert ourselves.
if (!fMetafile && pobjmgr->GetSingleSelect() == this)
{
DrawFrame(pdp, hdc, &rc);
}
else
{
LONG cpMin, cpMost;
_ped->GetSelRangeForRender(&cpMin, &cpMost);
if ((LONG)_cp >= cpMin &&
(LONG)_cp < cpMost &&
cpMost - cpMin > 1)
{
InvertRect(hdc, &rc);
}
}
}
RestoreDC(hdc, -1);
}
/*
* COleObject::Delete
*
* @mfunc deletes this object from the backing store _without_
* making outgoing calls. The commit on generated anti-events
* will handle the outgoing calls
*/
void COleObject::Delete(IUndoBuilder *publdr)
{
CNotifyMgr *pnm;
IAntiEvent *pae;
Assert(_fInUndo == FALSE);
_fInUndo = TRUE;
pnm = _ped->GetNotifyMgr();
if( pnm )
{
pnm->Remove( (ITxNotify *)this );
}
if( publdr )
{
// the anti-event will take care of calling IOO::Close
// for us.
pae = gAEDispenser.CreateReplaceObjectAE(_ped, this);
if( pae )
{
publdr->AddAntiEvent(pae);
}
}
else
{
Close(OLECLOSE_NOSAVE);
MakeZombie();
}
// if we're being deleted, we can't be selected anymore
_pi.dwFlags &= ~REO_SELECTED;
_fDraw = 0;
}
/*
* COleObject::Restore
*
* @mfunc restores the object from the undo state back into the
* backing store
*
* No outgoing calls will be made
*/
void COleObject::Restore(void)
{
CNotifyMgr *pnm;
Assert(_fInUndo == TRUE);
_fInUndo = FALSE;
_fDraw = TRUE;
pnm = _ped->GetNotifyMgr();
if( pnm )
{
pnm->Add( (ITxNotify *)this );
}
}
/*
* COleObject::SetREOSELECTED
*
* @mfunc cmember set REO_SELECTED state
*
* @rdesc void
*/
void COleObject::SetREOSELECTED(BOOL fSelect)
{
if( fSelect )
{
_pi.dwFlags |= REO_SELECTED;
}
else
{
_pi.dwFlags &= ~REO_SELECTED;
}
}
/*
* COleObject::Close
*
* @mfunc closes this object
*
* @rdesc void
*/
void COleObject::Close(
DWORD dwSave) //same as IOleObject::Close
{
IOleObject *poo;
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEINTERN, "COleObject::Close");
if( !_punkobj )
{
return;
}
if( _punkobj->QueryInterface(IID_IOleObject, (void **)&poo) == NOERROR )
{
poo->Close(dwSave);
poo->Release();
}
}
/*
* COleObject::ScrollObject
*
* @mfunc updates _rcPos if we were scrolled
*
* @rdesc void
*/
void COleObject::ScrollObject(
LONG dx, //@parm change in the x direction
LONG dy, //@parm change in the y direction
LPCRECT prcScroll) //@parm the rect that is being scrolled
{
RECT rcInter;
// if we're inplace active, OnReposition will handle the scrolling
if( !_fInPlaceActive && !_fGuardPosRect &&
IntersectRect(&rcInter, &_rcPos, prcScroll) )
{
OffsetRect(&_rcPos, dx, dy);
}
}
//
// PRIVATE methods
//
/*
* COleObject::~COleObject
*
* @mfunc destructor
*
* @rdesc void
*/
COleObject::~COleObject(void)
{
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEINTERN, "COleObject::~COleObject");
CleanupState();
}
/*
* COleObject::SavePrivateState
*
* @mfunc Saves information such as the aspect and various flags
* into the object's storage.
*
* @devnote This method is used mostly for compatibility with
* richedit 1.0--we save the same information they did.
*
* Also note that this method returns void--even if any particular
* call failes, we should be able to "recover" and limp along.
* Richedit 1.0 also had this behavior.
*/
void COleObject::SavePrivateState(void)
{
HRESULT hr;
IStream * pstm;
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEINTERN, "COleObject::SavePrivateState");
Assert(_pstg);
hr = _pstg->CreateStream(szSiteFlagsStm, STGM_READWRITE |
STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, 0, &pstm );
if( IsZombie() )
{
return;
}
if( hr == NOERROR )
{
pstm->Write(&_pi, sizeof(PersistedInfo), NULL);
pstm->Release();
}
}
/*
* COleObject::FetchObjectExtents
*
* @mfunc determines the object's size in himetric. Typically, this
* is achieved via IOleObject::GetExtent, but some error
* recovery is implemented
*
* @rdesc void. _sizel is updated
*/
void COleObject::FetchObjectExtents(void)
{
HRESULT hr = NOERROR;
IOleObject *poo;
IViewObject2 *pvo;
CDisplay *pdp;
if( IsZombie() )
{
return;
}
// We _don't_ want to make calls to GetExtent if:
// (1) We have outstanding updates to _sizel for which we
// haven't successfully called SetExtent
// (2) This is a PaintBrush object and the most recent call
// to SetExtent for this PB object failed
if(!(_fSetExtent || (_fIsPaintBrush && _fPBUseLocalSizel)))
{
// try IOleObject::GetExtent as long as we shouldn't try for
// the metafile first.
if( !(_pi.dwFlags & REO_GETMETAFILE) )
{
hr = _punkobj->QueryInterface(IID_IOleObject, (void **)&poo);
if( hr == NOERROR )
{
hr = poo->GetExtent(_pi.dvaspect, &_sizel);
poo->Release();
}
if( IsZombie() )
{
return;
}
}
else
{
hr = E_FAIL;
}
if( hr != NOERROR )
{
if( _punkobj->QueryInterface(IID_IViewObject2, (void **)&pvo) == NOERROR )
{
hr = pvo->GetExtent(_pi.dvaspect, -1, NULL, &_sizel);
pvo->Release();
}
}
if( IsZombie() )
{
return;
}
if( hr != NOERROR || _sizel.cx == 0 || _sizel.cy == 0 )
{
_sizel.cx = _sizel.cy = 2000;
}
}
// If _fSetExtent==TRUE, we've made a change to _sizel for which
// we haven't called IOleObject::SetExtent successfully. Therefore
// fall through with existing _sizel.
//update our position rectangle
pdp = _ped->_pdp;
_rcPos.right = _rcPos.left + pdp->HimetricYtoDY(_sizel.cx);
_rcPos.bottom = _rcPos.top + pdp->HimetricXtoDX(_sizel.cy);
}
/*
* COleObject::ConnectObject
*
* @mfunc setup the necessary advises to the embedded object.
*
* @rdesc HRESULT
*
* @comm This code is similar to ole2ui's OleStdSetupAdvises
*
*/
HRESULT COleObject::ConnectObject()
{
IViewObject *pvo;
IOleObject *poo;
HRESULT hr;
CObjectMgr *pobjmgr;
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEINTERN, "COleObject::ConnectObject");
if( IsZombie() )
{
return CO_E_RELEASED;
}
Assert(_punkobj);
if( _punkobj->QueryInterface(IID_IViewObject, (void **)&pvo) == NOERROR )
{
pvo->SetAdvise(_pi.dvaspect, ADVF_PRIMEFIRST, (IAdviseSink *)this);
pvo->Release();
}
if( IsZombie() )
{
return CO_E_RELEASED;
}
if( (hr = _punkobj->QueryInterface(IID_IOleObject, (void **)&poo))
== NOERROR )
{
hr = poo->Advise((IAdviseSink *)this, &_dwConn);
pobjmgr = _ped->GetObjectMgr();
if (NULL == pobjmgr)
{
Assert(pobjmgr);
poo->Release();
return E_OUTOFMEMORY;
}
// the doc may be NULL, but not the app. Don't do anything
// if the app name is NULL
if( pobjmgr->GetAppName())
{
hr = poo->SetHostNames(pobjmgr->GetAppName(),
pobjmgr->GetDocName());
}
poo->Release();
}
if( IsZombie() )
{
return CO_E_RELEASED;
}
pOleSetContainedObject(_punkobj, TRUE);
return hr;
}
/*
* COleObject::DisconnectObject
*
* @mfunc reverses the connections made in ConnectObject and releases
* the object. Note that the object's storage is _NOT_
* released.
*/
void COleObject::DisconnectObject()
{
IOleObject *poo = NULL;
IViewObject *pvo = NULL;
if (IsZombie())
{
return; // Already Disconnected.
}
if( _punkobj->QueryInterface(IID_IOleObject, (void **)&poo) == NOERROR )
{
poo->SetClientSite(NULL);
if( _dwConn )
{
poo->Unadvise(_dwConn );
}
poo->Release();
}
if( _punkobj->QueryInterface(IID_IViewObject, (void **)&pvo) == NOERROR )
{
pvo->SetAdvise(_pi.dvaspect, ADVF_PRIMEFIRST, NULL);
pvo->Release();
}
pCoDisconnectObject(_punkobj, NULL);
SafeReleaseAndNULL(&_punkobj);
}
/*
* COleObject::MakeZombie()
*
* @mfunc Force this object to enter a zombie state. This
* is called when we should be gone but aren't. It cleans
* up our state and flags us so we don't do nasty things
* between now and the time were are deleted.
*
*/
void COleObject::MakeZombie()
{
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEINTERN, "COleObject::MakeZombie");
CleanupState();
Zombie();
}
/*
* COleObject::CleanupState()
*
* @mfunc Called on delete and when we become zombied. It cleans
* up our member data and any other dependencies that need to
* be resolved.
*
*/
void COleObject::CleanupState()
{
CNotifyMgr *pnm;
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEINTERN, "COleObject::CleanupState");
if( _ped && !_fInUndo )
{
pnm = _ped->GetNotifyMgr();
if( pnm )
{
pnm->Remove( (ITxNotify *)this );
}
_ped = NULL;
}
DisconnectObject();
if( _pstg )
{
SafeReleaseAndNULL((IUnknown**)&_pstg);
}
if (_hdib)
{
::DeleteObject(_hdib);
_hdib = NULL;
}
GlobalFree(_hdata);
_hdata = NULL;
if (_pimageinfo)
{
delete _pimageinfo;
_pimageinfo = NULL;
}
}
/*
* COleObject::ActivateObj
*
* @mfunc Activates the object.
* args:
* message components of message initiating activation
* UINT uiMsg
* WPARAM wParam
* LPARAM lParam
* @rdesc
* BOOL Whether the object has been activated.
*/
BOOL COleObject::ActivateObj(UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
LPOLEOBJECT poo;
HWND hwnd;
MSG msg;
DWORD dwPos;
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEINTERN, "COleObject::AcitvateObj");
if (_ped->TxGetWindow(&hwnd) != NOERROR)
{
return FALSE;
}
ResetPosRect();
// Fill in the message structure
msg.hwnd = hwnd;
msg.message = uiMsg;
msg.wParam = wParam;
msg.lParam = lParam;
msg.time = GetMessageTime();
dwPos = GetMessagePos();
msg.pt.x = (LONG) LOWORD(dwPos);
msg.pt.y = (LONG) HIWORD(dwPos);
// Execute the primary verb
if( _punkobj->QueryInterface(IID_IOleObject, (void **)&poo) == NOERROR )
{
//Make sure we tell the object it's size has changed if we have not
//already notified it.
if (_fSetExtent)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -