📄 tenant.cpp
字号:
hr=pmkPage->ComposeWith(pmkTenant, FALSE, &pmkRel);
pmkTenant->Release();
//Hold on to the relative moniker
ReleaseInterface(m_pmk);
m_pmk=pmkRel;
if (SUCCEEDED(hr))
m_pIOleObject->SetMoniker(OLEWHICHMK_OBJREL, pmkRel);
}
}
return;
}
/*
* CTenant::Activate
*
* Purpose:
* Activates a verb on the object living in the tenant. Does
* nothing for static objects.
*
* Parameters:
* iVerb LONG of the verb to execute.
* pMSG LPMSG to the message causing the invocation.
*
* Return Value:
* BOOL TRUE if the object changed due to this verb
* execution.
*/
//CHAPTER22MOD
BOOL CTenant::Activate(LONG iVerb, LPMSG pMSG)
//End CHAPTER22MOD
{
RECT rc, rcH;
CHourglass *pHour;
SIZEL szl;
//Can't activate statics.
if (TENANTTYPE_STATIC==m_tType || NULL==m_pIOleObject)
{
MessageBeep(0);
return FALSE;
}
RECTFROMRECTL(rc, m_rcl);
RectConvertMappings(&rc, NULL, TRUE);
XformRectInPixelsToHimetric(NULL, &rc, &rcH);
pHour=new CHourglass;
//Get the server running first, then do a SetExtent, then show it
OleRun(m_pIOleObject);
if (m_fSetExtent)
{
SETSIZEL(szl, rcH.right-rcH.left, rcH.top-rcH.bottom);
m_pIOleObject->SetExtent(m_fe.dwAspect, &szl);
m_fSetExtent=FALSE;
}
//CHAPTER22MOD
m_pIOleObject->DoVerb(iVerb, pMSG, m_pImpIOleClientSite, 0
, m_hWnd, &rcH);
//End CHAPTER22MOD
delete pHour;
//If object changes, IAdviseSink::OnViewChange will see it.
return FALSE;
}
/*
* CTenant::Draw
*
* Purpose:
* Draws the tenant in its rectangle on the given hDC. We assume
* the DC is already set up for the mapping mode in which our
* rectangle is expressed, since the Page we're in tells us both
* the rect and the hDC.
*
* Parameters:
* hDC HDC in which to draw. Could be a metafile,
* memory DC, screen, or printer.
* ptd DVTARGETDEVICE * describing the device.
* hIC HDC holding an information context (printing).
* xOff, yOff int offsets for the page in lometric
* fNoColor BOOL indicating if we should do B & W
* fPrinter BOOL indicating if we should render for a
* printer.
*
* Return Value:
* None
*/
void CTenant::Draw(HDC hDC, DVTARGETDEVICE *ptd, HDC hIC
, int xOff, int yOff, BOOL fNoColor, BOOL fPrinter)
{
HRESULT hr;
RECT rc;
RECTL rcl;
UINT uMM;
//CHAPTER22MOD
/*
* Don't bother drawing anything but shading if we're doing in-place.
* It would just cause a lot of flicker.
*/
if (NULL!=m_pIOleIPObject)
return;
//End CHAPTER22MOD
RECTFROMRECTL(rc, m_rcl);
OffsetRect(&rc, -xOff, -yOff);
RECTLFROMRECT(rcl, rc);
//Repaint erases the rectangle to insure full object cleanup
if (!fNoColor && !fPrinter)
{
COLORREF cr;
cr=SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
ExtTextOut(hDC, rc.left, rc.top, ETO_OPAQUE, &rc, NULL
, 0, NULL);
SetBkColor(hDC, cr);
}
//We have to use Draw since we have a target device and IC.
hr=m_pIViewObject2->Draw(m_fe.dwAspect, -1, NULL, ptd, hIC, hDC
, &rcl, NULL, NULL, 0);
/*
* If Draw failed, then perhaps it couldn't work for the device,
* so try good old OleDraw as a last resort. The code will
* generally be OLE_E_BLANK.
*/
if (FAILED(hr))
OleDraw(m_pObj, m_fe.dwAspect, hDC, &rc);
if (!fPrinter)
{
/*
* Draw sizing handles to show the selection state. We
* convert things to MM_TEXT since that's what this
* function expects.
*/
RectConvertMappings(&rc, NULL, TRUE);
uMM=SetMapMode(hDC, MM_TEXT);
if (TENANTSTATE_SELECTED & m_dwState)
{
UIDrawHandles(&rc, hDC, UI_HANDLES_INSIDE
| UI_HANDLES_NOBORDER | UI_HANDLES_USEINVERSE
, CXYHANDLE, TRUE);
}
if (TENANTSTATE_OPEN & m_dwState)
UIDrawShading(&rc, hDC, UI_SHADE_FULLRECT, 0);
//Distinguish linked and embedded objects.
if (TENANTSTATE_SHOWTYPE & m_dwState)
{
UIShowObject(&rc, hDC
, (TENANTTYPE_LINKEDOBJECT==m_tType));
}
uMM=SetMapMode(hDC, uMM);
}
return;
}
/*
* CTenant::Repaint
* CTenant::Invalidate
*
* Purpose:
* Repaints the tenant where it lies or invalidates its area
* for later repainting.
*
* Parameters:
* None
*
* Return Value:
* None
*/
void CTenant::Repaint(void)
{
RECT rc;
HDC hDC;
/*
* We might be asked to repaint from
* IOleClientSite::OnShowWindow after we've switched pages if
* our server was running. This check on m_cOpens prevents that.
*/
if (0==m_cOpens || !m_fRepaintEnabled)
return;
hDC=GetDC(m_hWnd);
SetRect(&rc, m_pPG->m_xPos, m_pPG->m_yPos, 0, 0);
RectConvertMappings(&rc, NULL, FALSE);
SetMapMode(hDC, MM_LOMETRIC);
Draw(hDC, NULL, NULL, rc.left, rc.top, FALSE, FALSE);
ReleaseDC(m_hWnd, hDC);
return;
}
void CTenant::Invalidate(void)
{
RECTL rcl;
RECT rc;
RectGet(&rcl, TRUE);
RECTFROMRECTL(rc, rcl);
OffsetRect(&rc, -(int)m_pPG->m_xPos, -(int)m_pPG->m_yPos);
InvalidateRect(m_hWnd, &rc, FALSE);
return;
}
/*
* CTenant::FIsSelected
*
* Purpose:
* Returns the selection state of this tenant.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if selected, FALSE otherwise.
*/
BOOL CTenant::FIsSelected(void)
{
return (BOOL)(m_dwState & TENANTSTATE_SELECTED);
}
/*
* CTenant::ConvertToStatic
*
* Purpose:
* Changes the object that lives in this tenant to a static one.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if successful, FALSE otherwise.
*/
BOOL CTenant::ConvertToStatic(void)
{
/*
* If you SetSourceMoniker in IOleLink to NULL, then the link is
* gone as far as OLE is concerned. You only need to make sure
* the user doesn't have access to other functionality for this
* object, which we insure by changing our internal type. We
* set this on loading if GetSourceMoniker returns NULL.
*/
m_tType=TENANTTYPE_STATIC;
return TRUE;
}
/*
* CTenant::ObjectClassFormatAndIcon
*
* Purpose:
* Helper function for CPage::ConvertObject to retrieve necessary
* information about the object.
*
* Parameters:
* pClsID LPCLSID in which to store the CLSID.
* pwFormat LPWORD in which to store the clipboard format
* used.
* ppszType LPTSTR * in which to return a pointer to a
* type string.
* phMetaIcon HGLOBAL * in which to return the metafile
* icon currently in use.
*
* Return Value:
* None
*/
void CTenant::ObjectClassFormatAndIcon(LPCLSID pClsID
, LPWORD pwFormat, LPTSTR *ppszType, HGLOBAL *phMetaIcon
, LPTSTR *ppszLabel)
{
HRESULT hr;
TCHAR szType[128];
LPDATAOBJECT pIDataObject;
FORMATETC fe;
STGMEDIUM stm;
if (TENANTTYPE_EMBEDDEDOBJECT!=m_tType || NULL==m_pIOleObject)
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -