📄 tenant.cpp
字号:
/*
* CTenant::TypeGet
*
* Purpose:
* Returns the type of this tenant
*
* Parameters:
* None
*
* Return Value:
* TENANTTYPE Type of the tenant.
*/
TENANTTYPE CTenant::TypeGet(void)
{
return m_tType;
}
/*
* CTenant::CopyEmbeddedObject
*
* Purpose:
* Copies an embedded object to the given data object (via SetData,
* assuming this is a data transfer object for clipboard/drag-drop)
* if that's what we're holding.
*
* Parameters:
* pIDataObject LPDATAOBJECT in which to store the copy.
* pFE LPFORMATETC into which to copy CFSTR_EMBEDDEDOBJECT
* if we put that in the data object.
* pptl PPOINTL to the pick point (NULL outside of
* drag-drop);
*
* Return Value:
* None
*/
void CTenant::CopyEmbeddedObject(LPDATAOBJECT pIDataObject
, LPFORMATETC pFE, PPOINTL pptl)
{
LPPERSISTSTORAGE pIPS;
STGMEDIUM stm;
FORMATETC fe;
HRESULT hr;
UINT cf;
POINTL ptl;
SIZEL szl;
//Can only copy embeddings.
if (TENANTTYPE_EMBEDDEDOBJECT!=m_tType || NULL==m_pIOleObject)
return;
if (NULL==pptl)
{
SETPOINTL(ptl, 0, 0);
pptl=&ptl;
}
/*
* Create CFSTR_EMBEDDEDOBJECT. This is simply an IStorage with
* a copy of the embedded object in it. The not-so-simple part
* is getting an IStorage to stuff it in. For this operation
* we'll use a temporary compound file.
*/
stm.pUnkForRelease=NULL;
stm.tymed=TYMED_ISTORAGE;
hr=StgCreateDocfile(NULL, STGM_TRANSACTED | STGM_READWRITE
| STGM_CREATE| STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE
, 0, &stm.pstg);
if (FAILED(hr))
return;
m_pObj->QueryInterface(IID_IPersistStorage, (PPVOID)&pIPS);
if (NOERROR==pIPS->IsDirty())
{
OleSave(pIPS, stm.pstg, FALSE);
pIPS->SaveCompleted(NULL);
}
else
m_pIStorage->CopyTo(0, NULL, NULL, stm.pstg);
pIPS->Release();
//stm.pstg now has a copy, so stuff it away.
cf=RegisterClipboardFormat(CFSTR_EMBEDDEDOBJECT);
SETDefFormatEtc(fe, cf, TYMED_ISTORAGE);
if (SUCCEEDED(pIDataObject->SetData(&fe, &stm, TRUE)))
*pFE=fe;
else
ReleaseStgMedium(&stm);
stm.tymed=TYMED_HGLOBAL;
/*
* You want to make sure that if this object is iconic, that you
* create the object descriptor with DVASPECT_ICON instead of
* the more typical DVASPECT_CONTENT. Also remember that
* the pick point is in HIMETRIC.
*/
XformSizeInPixelsToHimetric(NULL, (LPSIZEL)pptl, (LPSIZEL)&ptl);
SETSIZEL(szl, (10*(m_rcl.right-m_rcl.left))
, (10 * (m_rcl.bottom-m_rcl.top)));
stm.hGlobal=INOLE_ObjectDescriptorFromOleObject
(m_pIOleObject, m_fe.dwAspect, ptl, &szl);
cf=RegisterClipboardFormat(CFSTR_OBJECTDESCRIPTOR);
SETDefFormatEtc(fe, cf, TYMED_HGLOBAL);
if (FAILED(pIDataObject->SetData(&fe, &stm, TRUE)))
ReleaseStgMedium(&stm);
return;
}
//CHAPTER20MOD
/*
* CTenant::ShowObjectType
*
* Purpose:
* Tells the object to switch on or off an indication of whether
* it is linked or embedded.
*
* Parameters:
* fShow BOOL indicating to show the type (TRUE) or
* not (FALSE)
*
* Return Value:
* None
*/
void CTenant::ShowObjectType(BOOL fShow)
{
BOOL fWasShow;
DWORD dwState;
RECT rc;
HDC hDC;
fWasShow=(BOOL)(TENANTSTATE_SHOWTYPE & m_dwState);
dwState=m_dwState & ~TENANTSTATE_SHOWTYPE;
m_dwState=dwState | ((fShow) ? TENANTSTATE_SHOWTYPE : 0);
/*
* If this wasn't previously shown, just add the line,
* otherwise repaint.
*/
if (!fWasShow && fShow)
{
RECTFROMRECTL(rc, m_rcl);
RectConvertMappings(&rc, NULL, TRUE);
OffsetRect(&rc, -(int)m_pPG->m_xPos, -(int)m_pPG->m_yPos);
hDC=GetDC(m_hWnd);
UIShowObject(&rc, hDC, (TENANTTYPE_LINKEDOBJECT==m_tType));
ReleaseDC(m_hWnd, hDC);
}
if (fWasShow && !fShow)
Repaint();
return;
}
/*
* CTenant::NotifyOfRename
*
* Purpose:
* Instructs the tenant that the document was saved under a
* different name. In order to keep the right compound document
* user interface, this tenant needs to tell its object through
* IOleObject::SetHostNames.
*
* Parameters:
* pszFile LPTSTR of filename.
* pmk LPMONIKER of the new filename.
*
* Return Value:
* None
*/
void CTenant::NotifyOfRename(LPTSTR pszFile, LPMONIKER pmk)
{
TCHAR szObj[40];
TCHAR szApp[40];
if (NULL==m_pIOleObject)
return;
if (TEXT('\0')==*pszFile)
{
LoadString(m_pPG->m_hInst, IDS_UNTITLED, szObj
, sizeof(szObj));
}
else
{
GetFileTitle(pszFile, szObj, sizeof(szObj));
#ifndef WIN32
//Force filenames to uppercase in DOS versions.
AnsiUpper(szObj);
#endif
}
LoadString(m_pPG->m_hInst, IDS_CAPTION, szApp, sizeof(szApp));
#ifdef WIN32ANSI
OLECHAR szObjW[40], szAppW[40];
MultiByteToWideChar(CP_ACP, 0, szObj, -1, szObjW, 40);
MultiByteToWideChar(CP_ACP, 0, szApp, -1, szAppW, 40);
m_pIOleObject->SetHostNames(szAppW, szObjW);
#else
m_pIOleObject->SetHostNames(szApp, szObj);
#endif
if (NULL!=pmk)
{
if (NULL!=m_pmkFile)
m_pmkFile->Release();
m_pmkFile=pmk;
m_pmkFile->AddRef();
m_pIOleObject->SetMoniker(OLEWHICHMK_CONTAINER, pmk);
}
return;
}
//End CHAPTER20MOD
/*
* 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.
*
* Return Value:
* BOOL TRUE if the object changed due to this verb
* execution.
*/
BOOL CTenant::Activate(LONG iVerb)
{
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;
}
m_pIOleObject->DoVerb(iVerb, NULL, m_pImpIOleClientSite, 0
, m_hWnd, &rcH);
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;
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);
//CHAPTER20MOD
if (!fPrinter)
//End CHAPTER20MOD
{
/*
* 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);
//CHAPTER20MOD
//Distinguish linked and embedded objects.
if (TENANTSTATE_SHOWTYPE & m_dwState)
{
UIShowObject(&rc, hDC
, (TENANTTYPE_LINKEDOBJECT==m_tType));
}
//End CHAPTER20MOD
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;
}
//CHAPTER20MOD
/*
* 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;
}
//End CHAPTER20MOD
/*
* 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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -