📄 coleobj.cpp
字号:
Assert(!pobjmgr->GetInPlaceActiveObject());
pobjmgr->SetInPlaceActiveObject(this);
_pi.dwFlags |= REO_INPLACEACTIVE;
// force this object to be selected, if it isn't already
if( !(_pi.dwFlags & REO_SELECTED) )
{
psel = _ped->GetSel();
if( psel )
{
psel->SetSelection(_cp, _cp + 1);
}
}
return NOERROR;
}
return E_UNEXPECTED;
}
/*
* COleObject::GetWindowContext
*
* @mfunc implementation of IOleInPlaceSite::GetWindowContext.
* Enables the in-place object to retrieve the window
* interfaces that form the window object hierarchy.
*
* @rdesc HRESULT
*/
STDMETHODIMP COleObject::GetWindowContext(
IOleInPlaceFrame **ppipframe, //@parm where to put the in-place frame
IOleInPlaceUIWindow **ppipuidoc,//@parm where to put the ui window
LPRECT prcPos, //@parm position rect
LPRECT prcClip, //@parm clipping rect
LPOLEINPLACEFRAMEINFO pipfinfo) //@parm accelerator information
{
IRichEditOleCallback *precall;
CCallMgr callmgr(_ped);
CStabilize stabilize(this);
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::GetWindowContext");
if( IsZombie() )
{
return CO_E_RELEASED;
}
// let the container verify other parameters; we don't use them
if( !prcPos || !prcClip )
{
return E_INVALIDARG;
}
precall = _ped->GetRECallback();
if( precall )
{
// recall that there are two rects here in client coordiantes:
// the rect for this object (_rcPos) and the rect for
// our main display;
*prcPos = _rcPos;
// FUTURE (alexgo); we may need to get this from the
// display instead to handle the inactive state if we ever
// want to support embedded objects with the inactive state.
_ped->TxGetClientRect(prcClip);
return precall->GetInPlaceContext(ppipframe, ppipuidoc, pipfinfo);
}
return E_UNEXPECTED;
}
/*
* COleObject::Scroll
*
* @mfunc implementation of IOleInPlaceSite::Scroll
*
* @rdesc E_NOTIMPL;
*/
STDMETHODIMP COleObject::Scroll(
SIZE sizeScroll) //@parm the amount to scroll
{
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::Scroll");
TRACEWARNSZ("method not implemented!");
return E_NOTIMPL;
}
/*
* COleObject::OnUIDeactivate
*
* @mfunc implementation of IOleInPlaceSite::OnUIDeactivate. Notifies
* the container that it should re-install it's user interface
*
* @rdesc HRESULT
*/
STDMETHODIMP COleObject::OnUIDeactivate(
BOOL fUndoable) //@parm -- whether or not you can undo anything here
{
IRichEditOleCallback *precall;
CCallMgr callmgr(_ped);
CStabilize stabilize(this);
CObjectMgr *pobjmgr;
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::OnUIDeactivate");
if( IsZombie() )
{
return CO_E_RELEASED;
}
pobjmgr = _ped->GetObjectMgr();
precall = _ped->GetRECallback();
if (_fIsPaintBrush)
{
// Hack for RAID 3293. Bitmap object disappears after editing.
// Apparently paint only triggers OnUIDeactivate and not OnInPlaceDeactivate
// assume that in-place objects can never be blank.
_fInPlaceActive = FALSE;
//Reset REO_INPLACEACTIVE
_pi.dwFlags &= ~REO_INPLACEACTIVE;
}
if( !precall )
{
return E_UNEXPECTED;
}
if( _ped->TxIsDoubleClickPending() )
{
_ped->GetObjectMgr()->SetShowUIPending(TRUE);
}
else
{
// ignore any errors; the old code did.
precall->ShowContainerUI(TRUE);
if( IsZombie() )
{
return CO_E_RELEASED;
}
}
pobjmgr->SetInPlaceActiveObject(NULL);
// get the focus back
_ped->TxSetFocus();
#ifdef DEBUG
// the OLE undo model is not very compatible with multi-level undo.
// For simplicity, just ignore stuff.
if( fUndoable )
{
TRACEWARNSZ("Ignoring a request to keep undo from an OLE object");
}
#endif
// some objects are lame and draw outside the
// areas they are supposed to. So we need to
// just invalidate everything and redraw.
_ped->TxInvalidateRect(NULL, TRUE);
return NOERROR;
}
/*
* COleObject::OnInPlaceDeactivate
*
* @mfunc implementation of IOleInPlaceSite::OnInPlaceDeactivate
*
* @rdesc NOERROR
*/
STDMETHODIMP COleObject::OnInPlaceDeactivate(void)
{
CCallMgr callmgr(_ped);
CStabilize stabilize(this);
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN,
"COleObject::OnInPlaceDeactivate");
_fInPlaceActive = FALSE;
//Reset REO_INPLACEACTIVE
_pi.dwFlags &= ~REO_INPLACEACTIVE;
if( !_punkobj )
{
return E_UNEXPECTED;
}
if( IsZombie() )
{
return CO_E_RELEASED;
}
// apparently, WordArt 2.0 had some sizing problems. The original
// code has this call to GetExtent-->SetExtent, so I've kept it
// here.
if( _fIsWordArt2 )
{
//ignore errors. If anything fails, too bad.
FetchObjectExtents(); // this will reset _sizel
SetExtent(SE_NOTACTIVATING);
}
// some objects are lame and draw outside the
// areas they are supposed to. So we need to
// just invalidate everything and redraw.
// Note that we do this in UIDeactivate as well; however, the
// double invalidation is necessary to cover some re-entrancy
// cases where we might be painted before everything is ready.
_ped->TxInvalidateRect(NULL, TRUE);
return NOERROR;
}
/*
* COleObject::DiscardUndoState
*
* @mfunc implementation of IOleInPlaceSite::DiscardUndoState.
*
* @rdesc NOERROR
*/
STDMETHODIMP COleObject::DiscardUndoState(void)
{
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN,
"COleObject::DiscardUndoState");
// nothing to do here; we don't keep any OLE-undo state as it's
// note very compatible with multi-level undo.
return NOERROR;
}
/*
* COleObject::DeactivateAndUndo
*
* @mfunc implementation of IOleInPlaceSite::DeactivateAndUndo--
* called by an active object when the user invokes undo
* in the active object
*
* @rdesc NOERROR (yep, richedit1.0 ignored all the errors here)
*/
STDMETHODIMP COleObject::DeactivateAndUndo(void)
{
CStabilize stabilize(this);
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::DeactivateAndUndo");
if( IsZombie() )
{
return CO_E_RELEASED;
}
// ignore the error
_ped->InPlaceDeactivate();
// COMPATIBILITY ISSUE: we don't bother doing any undo here, as
// a multi-level undo model is incompatible with OLE undo.
return NOERROR;
}
/*
* COleObject::OnPosRectChange
*
* @mfunc implementation of IOleInPlaceSite::OnPosRectChange. This
* method is called by an in-place object when its extents have
* changed
*
* @rdesc HRESULT
*/
STDMETHODIMP COleObject::OnPosRectChange(LPCRECT prcPos)
{
IOleInPlaceObject *pipo;
RECT rcClip;
RECT rcNewPos;
HRESULT hr;
CCallMgr callmgr(_ped);
CStabilize stabilize(this);
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::OnPosRectChange");
if( !prcPos )
{
return E_INVALIDARG;
}
if( !_punkobj )
{
return E_UNEXPECTED;
}
if( IsZombie() )
{
return CO_E_RELEASED;
}
if( !_ped->fInplaceActive() )
{
return E_UNEXPECTED;
}
// check to see if the rect moved; we don't allow this, but
// do allow the object to keep the new size
rcNewPos = *prcPos;
if( prcPos->left != _rcPos.left || prcPos->top != _rcPos.top )
{
rcNewPos.right = rcNewPos.left + (prcPos->right - prcPos->left);
rcNewPos.bottom = rcNewPos.top + (prcPos->bottom - prcPos->top);
}
_ped->TxGetClientRect(&rcClip);
if( (hr = _punkobj->QueryInterface(IID_IOleInPlaceObject, (void **)&pipo))
== NOERROR )
{
hr = pipo->SetObjectRects(&rcNewPos, &rcClip);
pipo->Release();
}
return hr;
}
/*
* COleObject::OnDataChange
*
* @mfunc implementation of IAdviseSink::OnDataChange
*
* @rdesc NOERROR
*/
STDMETHODIMP_(void) COleObject::OnDataChange(
FORMATETC *pformatetc, //@parm the format of the data that changed
STGMEDIUM *pmedium) //@parm the data that changed
{
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::OnDataChange");
CCallMgr callmgr(_ped);
if( IsZombie() )
{
return;
}
_pi.dwFlags &= ~REO_BLANK;
// this will also set the modified flag
_ped->GetCallMgr()->SetChangeEvent(CN_GENERIC);
return;
}
/*
* COleObject::OnViewChange
*
* @mfunc implementation of IAdviseSink::OnViewChange. Notifies
* us that the object's view has changed.
*
* @rdesc HRESULT
*
*/
STDMETHODIMP_(void) COleObject::OnViewChange(
DWORD dwAspect, //@parm the aspect that has changed
LONG lindex) //@parm unused
{
CStabilize stabilize(this);
CCallMgr callmgr(_ped);
CDisplay *pdp;
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::OnViewChange");
if( !_punkobj )
{
return; // E_UNEXPECTED
}
if( IsZombie() )
{
return;
}
_pi.dwFlags &= ~REO_BLANK;
// Richedit1.0 ignored errors on getting the object extents
FetchObjectExtents();
if( IsZombie() )
{
return;
}
pdp = _ped->_pdp;
if( pdp )
{
pdp->OnPostReplaceRange(INFINITE, 0, 0, _cp, _cp + 1);
}
_ped->GetCallMgr()->SetChangeEvent(CN_GENERIC);
return;
}
/*
* COleObject::OnRename
*
* @mfunc implementation of IAdviseSink::OnRename. Notifies the container
* that the object has been renamed
*
* @rdesc E_NOTIMPL
*/
STDMETHODIMP_(void) COleObject::OnRename(
IMoniker *pmk) //@parm the object's new name
{
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::OnRename");
TRACEWARNSZ("IAdviseSink::OnRename not implemented!");
return; // E_NOTIMPL;
}
/*
* COleObject::OnSave
*
* @mfunc implementation of IAdviseSink::OnSave. Notifies the container
* that an object has been saved
*
* @rdesc NOERROR
*/
STDMETHODIMP_(void) COleObject::OnSave(void)
{
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::OnSave");
_pi.dwFlags &= ~REO_BLANK;
}
/*
* COleObject::OnClose
*
* @mfunc implementation of IAdviseSink::OnClose. Notifies the container
* that an object has been closed.
*
* @rdesc NOERROR
*/
STDMETHODIMP_(void) COleObject::OnClose(void)
{
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::OnClose");
if( IsZombie() )
{
return;
}
// if the object is blank (i.e. no data in it),we don't want to leave
// it in the backing store--there is nothing for us to draw && therefore
// nothing for the user to click on! So just delete the object with
// a space. Note that 1.0 actually deleted the object; we'll just
// replace it with a space to make everything work out right.
if( (_pi.dwFlags & REO_BLANK) )
{
CCallMgr callmgr(_ped);
CStabilize stabilize(this);
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);
}
_ped->TxSetForegroundWindow();
}
/*
* COleObject::OnPreReplaceRange
*
* @mfunc implementation of ITxNotify::OnPreReplaceRange
* called before changes are made to the backing store
*
* @rdesc void
*/
void COleObject::OnPreReplaceRange(
DWORD cp, //@parm cp of the changes
DWORD cchDel, //@parm #of chars deleted
DWORD cchNew, //@parm # of chars added
DWORD cpFormatMin, //@parm min cp of formatting changes
DWORD cpFormatMax) //@parm max cp of formatting changes
{
Assert(_fInUndo == FALSE);
}
/*
* COleObject::OnPostReplaceRange
*
* @mfunc implementation of ITxNotify::OnPostReplaceRange
* called after changes are made to the backing store
*
* @rdesc void
*
* @comm we use this method to keep our cp's up-to-date
*/
void COleObject::OnPostReplaceRange(
DWORD cp, //@parm cp of the changes
DWORD cchDel, //@parm #of chars deleted
DWORD cchNew, //@parm # of chars added
DWORD cpFormatMin, //@parm min cp of formatting changes
DWORD cpFormatMax) //@parm max cp of formatting changes
{
// the only case we need to worry about is when the changes
// come before our object
Assert(_fInUndo == FALSE);
_fDraw = TRUE;
if( cp <= _cp )
{
if( cp + cchDel > _cp )
{
_fDraw = FALSE;
return;
}
else
{
_cp += (cchNew - cchDel);
}
}
}
/*
* COleObject::Zombie ()
*
* @mfunc
* Turn this object into a zombie
*
*/
void COleObject::Zombie ()
{
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "COleObject::Zombie");
_ped = NULL;
}
/*
* COleObject::COleObject
*
* @mfunc constructor
*
* @rdesc void
*/
COleObject::COleObject(
CTxtEdit *ped) //@parm context for this object
{
CNotifyMgr *pnm;
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEINTERN, "COleObject::COleObject");
AddRef();
// most of the values will be NULL by virtue of the allocator
_ped = ped;
pnm = ped->GetNotifyMgr();
if( pnm )
{
pnm->Add( (ITxNotify *)this );
}
}
/*
* COleObject::GetObjectData
*
* @mfunc fills out an REOBJECT structure with information relevant
* to this object
*
* @rdesc HRESULT
*/
HRESULT COleObject::GetObjectData(
REOBJECT *preobj, //@parm struct to fill out
DWORD dwFlags) //@parm indicate what data is requested
{
IOleObject *poo = NULL;
TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEINTERN, "COleObject::GetObjectData");
Assert(preobj);
Assert(_punkobj);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -