📄 tenant.cpp
字号:
return;
if (NULL==pClsID || NULL==pwFormat || NULL==ppszType
|| NULL==phMetaIcon)
return;
/*
* For embedded objects get the real CLSID of the object and
* its format string. If this fails then we can try to ask
* the object, or we can look in the registry.
*/
hr=ReadClassStg(m_pIStorage, pClsID);
if (FAILED(hr))
{
hr=m_pIOleObject->GetUserClassID(pClsID);
if (FAILED(hr))
*pClsID=CLSID_NULL;
}
hr=ReadFmtUserTypeStg(m_pIStorage, pwFormat, ppszType);
if (FAILED(hr))
{
*pwFormat=0;
*ppszType=NULL;
if (INOLE_GetUserTypeOfClass(*pClsID, 0, szType
, sizeof(szType)))
{
*ppszType=INOLE_CopyString(szType);
}
}
/*
* Try to get the AuxUserType from the registry, using
* the short version (registered under AuxUserType\2).
* If that fails, just copy *ppszType.
*/
*ppszLabel=NULL;
if (INOLE_GetUserTypeOfClass(*pClsID, 2, szType
, sizeof(szType)))
{
*ppszLabel=INOLE_CopyString(szType);
}
else
*ppszLabel=INOLE_CopyString(*ppszType);
//Get the icon for this thing, if we're iconic.
*phMetaIcon=NULL;
hr=m_pObj->QueryInterface(IID_IDataObject
, (PPVOID)&pIDataObject);
if (SUCCEEDED(hr))
{
SETFormatEtc(fe, CF_METAFILEPICT, DVASPECT_ICON, NULL
, TYMED_MFPICT, -1);
hr=pIDataObject->GetData(&fe, &stm);
pIDataObject->Release();
if (SUCCEEDED(hr))
*phMetaIcon=stm.hGlobal;
else
*phMetaIcon=OleGetIconOfClass(*pClsID, NULL, TRUE);
}
return;
}
/*
* CTenant::SwitchOrUpdateAspect
*
* Purpose:
* Switches between DVASPECT_CONTENT and DVASPECT_ICON
*
* Parameters:
* hMetaIcon HGLOBAL to the new icon if we're changing the
* icon or switching to DVASPECT_ICON. NULL to
* change back to content.
* fPreserve BOOL indicating if we're to preserve the old
* aspect after changing.
*
* Return Value:
* BOOL TRUE if anything changed, FALSE otherwise.
*/
BOOL CTenant::SwitchOrUpdateAspect(HGLOBAL hMetaIcon
, BOOL fPreserve)
{
HRESULT hr;
DWORD dwAspect;
BOOL fUpdate=FALSE;
//Nothing to do if we're content already and there's no icon.
if (NULL==hMetaIcon && DVASPECT_CONTENT==m_fe.dwAspect)
return FALSE;
//If we're iconic already, just cache the new icon
if (NULL!=hMetaIcon && DVASPECT_ICON==m_fe.dwAspect)
hr=INOLE_SetIconInCache(m_pIOleObject, hMetaIcon);
else
{
//Otherwise, switch between iconic and content.
dwAspect=(NULL==hMetaIcon) ? DVASPECT_CONTENT : DVASPECT_ICON;
/*
* Switch between aspects, where dwAspect has the new one
* and m_fe.dwAspect will be changed in the process.
*/
hr=INOLE_SwitchDisplayAspect(m_pIOleObject
, &m_fe.dwAspect, dwAspect, hMetaIcon, !fPreserve
, TRUE, m_pImpIAdviseSink, &fUpdate);
if (SUCCEEDED(hr))
{
//Update MiscStatus for the new aspect
m_pIOleObject->GetMiscStatus(m_fe.dwAspect, &m_grfMisc);
if (fUpdate)
m_pIOleObject->Update(); //This repaints.
}
}
//If we switched, update our extents.
if (SUCCEEDED(hr))
{
SIZEL szl;
m_pIOleObject->GetExtent(m_fe.dwAspect, &szl);
if (0 > szl.cy)
szl.cy=-szl.cy;
//Convert HIMETRIC absolute units to our LOMETRIC mapping
if (0!=szl.cx && 0!=szl.cy)
SETSIZEL(szl, szl.cx/10, -szl.cy/10);
Invalidate(); //Remove old aspect
SizeSet(&szl, FALSE, FALSE); //Change size
Repaint(); //Paint the new one
}
return SUCCEEDED(hr);
}
/*
* CTenant::EnableRepaint
*
* Purpose:
* Toggles whether the Repaint function does anything. This
* is used during conversion/emulation of an object to disable
* repaints until the new object can be given the proper extents.
*
* Parameters:
* fEnable TRUE to enable repaints, FALSE to disable.
*
* Return Value:
* None
*/
void CTenant::EnableRepaint(BOOL fEnable)
{
m_fRepaintEnabled=fEnable;
return;
}
/*
* CTenant::ObjectGet
*
* Purpose:
* Retrieves the LPUNKNOWN of the object in use by this tenant
*
* Parameters:
* ppUnk LPUNKNOWN * in which to return the object
* pointer.
*
* Return Value:
* None
*/
void CTenant::ObjectGet(LPUNKNOWN *ppUnk)
{
if (NULL!=ppUnk)
{
*ppUnk=m_pObj;
m_pObj->AddRef();
}
return;
}
/*
* CTenant::FormatEtcGet
*
* Purpose:
* Retrieves the FORMATETC in use by this tenant
*
* Parameters:
* pFE LPFORMATETC in which to store the information.
* fPresentation BOOL indicating if we want the real format or
* that of the presentation.
*
* Return Value:
* None
*/
void CTenant::FormatEtcGet(LPFORMATETC pFE, BOOL fPresentation)
{
if (NULL!=pFE)
{
*pFE=m_fe;
//If there is no format, use metafile (for embedded objects)
if (fPresentation || 0==pFE->cfFormat)
{
//Don't mess with dwAspect; might be icon or content.
pFE->cfFormat=CF_METAFILEPICT;
pFE->tymed=TYMED_MFPICT;
}
}
return;
}
/*
* CTenant::SizeGet
* CTenant::SizeSet
* CTenant::RectGet
* CTenant::RectSet
*
* Purpose:
* Returns or sets the size/position of the object contained here.
*
* Parameters:
* pszl/prcl LPSIZEL (Size) or LPRECTL (Rect) with the
* extents of interest. In Get situations,
* this will receive the extents; in Set it
* contains the extents.
* fDevice BOOL indicating that pszl/prcl is expressed
* in device units. Otherwise it's LOMETRIC.
* fInformObj (Set Only) BOOL indicating if we need to inform
* the object all.
*
* Return Value:
* None
*/
void CTenant::SizeGet(LPSIZEL pszl, BOOL fDevice)
{
if (!fDevice)
{
pszl->cx=m_rcl.right-m_rcl.left;
pszl->cy=m_rcl.bottom-m_rcl.top;
}
else
{
RECT rc;
SetRect(&rc, (int)(m_rcl.right-m_rcl.left)
, (int)(m_rcl.bottom-m_rcl.top), 0, 0);
RectConvertMappings(&rc, NULL, TRUE);
pszl->cx=(long)rc.left;
pszl->cy=(long)rc.top;
}
return;
}
void CTenant::SizeSet(LPSIZEL pszl, BOOL fDevice, BOOL fInformObj)
{
SIZEL szl;
if (!fDevice)
{
szl=*pszl;
m_rcl.right =pszl->cx+m_rcl.left;
m_rcl.bottom=pszl->cy+m_rcl.top;
}
else
{
RECT rc;
SetRect(&rc, (int)pszl->cx, (int)pszl->cy, 0, 0);
RectConvertMappings(&rc, NULL, FALSE);
m_rcl.right =(long)rc.left+m_rcl.left;
m_rcl.bottom=(long)rc.top+m_rcl.top;
SETSIZEL(szl, (long)rc.left, (long)rc.top);
}
//Tell OLE that this object was resized.
if (NULL!=m_pIOleObject && fInformObj)
{
HRESULT hr;
BOOL fRun=FALSE;
//Convert our LOMETRIC into HIMETRIC by *=10
szl.cx*=10;
szl.cy*=-10; //Our size is stored negative.
/*
* If the MiscStatus bit of OLEMISC_RECOMPOSEONRESIZE
* is set, then we need to run the object before calling
* SetExtent to make sure it has a real chance to
* re-render the object. We have to update and close
* the object as well after this happens.
*/
if (OLEMISC_RECOMPOSEONRESIZE & m_grfMisc)
{
if (!OleIsRunning(m_pIOleObject))
{
OleRun(m_pIOleObject);
fRun=TRUE;
}
}
hr=m_pIOleObject->SetExtent(m_fe.dwAspect, &szl);
/*
* If the object is not running and it does not have
* RECOMPOSEONRESIZE, then SetExtent fails. Make
* sure that we call SetExtent again (by just calling
* SizeSet here again) when we next run the object.
*/
if (SUCCEEDED(hr))
{
m_fSetExtent=FALSE;
if (fRun)
{
m_pIOleObject->Update();
m_pIOleObject->Close(OLECLOSE_SAVEIFDIRTY);
}
}
else
{
if (OLE_E_NOTRUNNING==GetScode(hr))
m_fSetExtent=TRUE;
}
}
return;
}
void CTenant::RectGet(LPRECTL prcl, BOOL fDevice)
{
if (!fDevice)
*prcl=m_rcl;
else
{
RECT rc;
RECTFROMRECTL(rc, m_rcl);
RectConvertMappings(&rc, NULL, TRUE);
RECTLFROMRECT(*prcl, rc);
}
return;
}
void CTenant::RectSet(LPRECTL prcl, BOOL fDevice, BOOL fInformObj)
{
SIZEL szl;
LONG cx, cy;
/*
* Prevent reentrant calls that may come from calling
* UpdateInPlaceObjectRects here and elsewhere.
*/
if (m_fInRectSet)
return;
m_fInRectSet=TRUE;
cx=m_rcl.right-m_rcl.left;
cy=m_rcl.bottom-m_rcl.top;
if (!fDevice)
m_rcl=*prcl;
else
{
RECT rc;
RECTFROMRECTL(rc, *prcl);
RectConvertMappings(&rc, NULL, FALSE);
RECTLFROMRECT(m_rcl, rc);
}
/*
* Tell ourselves that the size changed, if it did. SizeSet
* will call IOleObject::SetExtent for us.
*/
if ((m_rcl.right-m_rcl.left)!=cx || (m_rcl.bottom-m_rcl.top)!=cy)
{
SETSIZEL(szl, m_rcl.right-m_rcl.left, m_rcl.bottom-m_rcl.top);
SizeSet(&szl, FALSE, fInformObj);
}
//Tell an in-place active object it moved too
UpdateInPlaceObjectRects(NULL, TRUE);
m_fInRectSet=FALSE;
return;
}
/*
* CTenant::CreateStatic
* (Protected)
*
* Purpose:
* Creates a new static bitmap or metafile object for this tenant
* using a freeloading method allowing us to specify exactly which
* type of data we want to paste since OleCreateStaticFromData
* doesn't.
*
* Parameters:
* pIDataObject LPDATAOBJECT from which to paste.
* pFE LPFORMATETC describing the format to paste.
* ppObj LPUNKNOWN * into which we store the
* object pointer.
*
* Return Value:
* HRESULT NOERROR on success, error code otherwise.
*/
HRESULT CTenant::CreateStatic(LPDATAOBJECT pIDataObject
, LPFORMATETC pFE, LPUNKNOWN *ppObj)
{
HRESULT hr;
STGMEDIUM stm;
LPUNKNOWN pIUnknown;
LPOLECACHE pIOleCache;
LPPERSISTSTORAGE pIPersistStorage;
CLSID clsID;
*ppObj=NULL;
//Try to get the data desired as specified in pFE->cfFormat
hr=pIDataObject->GetData(pFE, &stm);
if (FAILED(hr))
return hr;
//Create the object to handle this data.
if (CF_METAFILEPICT==pFE->cfFormat)
clsID=CLSID_Picture_Metafile;
else
clsID=CLSID_Picture_Dib;
hr=CreateDataCache(NULL, clsID, IID_IUnknown
, (PPVOID)&pIUnknown);
if (FAILED(hr))
{
ReleaseStgMedium(&stm);
return hr;
}
m_clsID=clsID;
//Stuff the data into the object
pIUnknown->QueryInterface(IID_IPersistStorage
, (PPVOID)&pIPersistStorage);
pIPersistStorage->InitNew(m_pIStorage);
//Now that we have the cache object, shove the data into it.
pIUnknown->QueryInterface(IID_IOleCache, (PPVOID)&pIOleCache);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -