📄 tenant.cpp
字号:
* Nothing is committed when being destroyed.
*
* Parameters:
* pIStorage LPSTORAGE contianing this page on which to call
* DestroyElement
*
* Return Value:
* None
*/
void CTenant::Destroy(LPSTORAGE pIStorage)
{
OLECHAR szTemp[32];
if (NULL!=pIStorage)
{
if (NULL!=m_pIOleObject)
{
DeactivateInPlaceObject(TRUE);
m_pIOleObject->Close(OLECLOSE_NOSAVE);
}
if (NULL!=m_pIStorage)
{
//Remove all reference/open counts on this storage.
while (0!=m_cOpens)
{
m_pIStorage->Release();
m_cOpens--;
}
}
GetStorageName(szTemp);
pIStorage->DestroyElement(szTemp);
m_pIStorage=NULL;
}
return;
}
/*
* CTenant::Select
*
* Purpose:
* Selects or deselects the tenant.
*
* Parameters:
* fSelect BOOL indicating the new state of the tenant.
* fActivate BOOL indicating whether to activate or
* deactivate an in-place object. If TRUE, then
* activation/deactivation will happen. If
* FALSE, no change in activation takes place.
*
* Return Value:
* None
*/
void CTenant::Select(BOOL fSelect, BOOL fActivate)
{
BOOL fWasSelected;
DWORD dwState;
RECT rc;
HDC hDC;
fWasSelected=(BOOL)(TENANTSTATE_SELECTED & m_dwState);
//Nothing to do when there's no change.
if (fWasSelected==fSelect)
return;
dwState=m_dwState & ~TENANTSTATE_SELECTED;
m_dwState=dwState | ((fSelect) ? TENANTSTATE_SELECTED : 0);
/*
* Draw sizing handles to show the selection state. We convert
* things to MM_TEXT since that's what this function expects.
*/
//CHAPTER24MOD
/*
* Suppress drawing any handles for invisible controls
* unless we're in design mode.
*/
if (!(OLEMISC_INVISIBLEATRUNTIME & m_grfMisc)
|| m_fDesignMode)
{
RECTFROMRECTL(rc, m_rcl);
RectConvertMappings(&rc, NULL, TRUE);
OffsetRect(&rc, -(int)m_pPG->m_xPos, -(int)m_pPG->m_yPos);
hDC=GetDC(m_hWnd);
UIDrawHandles(&rc, hDC, UI_HANDLES_INSIDE
| UI_HANDLES_NOBORDER | UI_HANDLES_USEINVERSE
, CXYHANDLE, !fWasSelected);
ReleaseDC(m_hWnd, hDC);
}
//Selecting only dirties in design mode
if (fSelect && m_fDesignMode)
m_pPG->m_fDirty=TRUE;
//End CHAPTER24MOD
if (fActivate)
{
if (!fSelect)
DeactivateInPlaceObject(FALSE);
else
{
//CHAPTER24MOD
/*
* Normally we'll send OLEIVERB_UIACTIVATE to any
* inside-out object. A control might be marked
* with OLEMISC_NOUIACTIVATE in which case we skip
* this step entirely.
*/
if ((m_grfMisc & OLEMISC_INSIDEOUT) &&
! (m_grfMisc & OLEMISC_NOUIACTIVATE))
//End CHAPTER24MOD
{
MSG msg;
DWORD dw;
//Include a message for in-place objects.
msg.hwnd=NULL;
msg.message=WM_LBUTTONDOWN;
msg.wParam=0;
msg.time=GetMessageTime();
dw=GetMessagePos();
msg.lParam=dw;
SETPOINT(msg.pt, LOWORD(dw), HIWORD(dw));
Activate(OLEIVERB_UIACTIVATE, &msg);
}
}
}
return;
}
/*
* CTenant::ShowAsOpen
*
* Purpose:
* Draws or removes the hatch pattern over an object.
*
* Parameters:
* fOpen BOOL indicating the open state of this tenant.
*
* Return Value:
* None
*/
void CTenant::ShowAsOpen(BOOL fOpen)
{
BOOL fWasOpen;
DWORD dwState;
RECT rc;
HDC hDC;
fWasOpen=(BOOL)(TENANTSTATE_OPEN & m_dwState);
dwState=m_dwState & ~TENANTSTATE_OPEN;
m_dwState=dwState | ((fOpen) ? TENANTSTATE_OPEN : 0);
//CHAPTER24MOD
/*
* Suppress drawing shading in any case if this object is
* invisible at run time and we're not in design mode.
*/
if ((OLEMISC_INVISIBLEATRUNTIME & m_grfMisc)
&& !m_fDesignMode)
{
return;
}
//End CHAPTER24MOD
//If this was not open, then just hatch, otherwise repaint.
if (!fWasOpen && fOpen)
{
RECTFROMRECTL(rc, m_rcl);
RectConvertMappings(&rc, NULL, TRUE);
OffsetRect(&rc, -(int)m_pPG->m_xPos, -(int)m_pPG->m_yPos);
hDC=GetDC(m_hWnd);
UIDrawShading(&rc, hDC, UI_SHADE_FULLRECT, 0);
ReleaseDC(m_hWnd, hDC);
}
if (fWasOpen && !fOpen)
Repaint();
return;
}
/*
* CTenant::ShowYourself
*
* Purpose:
* Function that really just implements IOleClientSite::ShowObject.
* Here we first check if the tenant is fully visible, and if so,
* then nothing needs to happen. Otherwise, if the upper left
* corner of the tenant is in the upper left visible quadrant of
* the window, we'll also consider ourselves done. Otherwise
* we'll put the upper left corner of the object at the upper left
* corner of the window.
*
* Parameters:
* None
*
* Return Value:
* None
*/
void CTenant::ShowYourself(void)
{
RECTL rcl;
RECT rc;
POINT pt1, pt2;
//Scrolling deals in device units; get our rectangle in those.
RectGet(&rcl, TRUE);
//Get the window rectangle offset for the current scroll pos.
GetClientRect(m_hWnd, &rc);
OffsetRect(&rc, m_pPG->m_xPos, m_pPG->m_yPos);
//Check if the object is already visible. (macro in bookguid.h)
SETPOINT(pt1, (int)rcl.left, (int)rcl.top);
SETPOINT(pt2, (int)rcl.right, (int)rcl.bottom);
/*
* If we're doing in-place, don't move anything if the
* object is visible AT ALL. IOleInPlaceSite::OnInPlaceActivate
* will have been called by now--the object will always
* make that call before showing itself.
*/
if (NULL!=m_pIOleIPObject && PtInRect(&rc, pt1))
return;
if (PtInRect(&rc, pt1) && PtInRect(&rc, pt2))
return;
//Check if the upper left is within the upper left quadrant
if (((int)rcl.left > rc.left
&& (int)rcl.left < ((rc.right+rc.left)/2))
&& ((int)rcl.top > rc.top
&& (int)rcl.top < ((rc.bottom+rc.top)/2)))
return;
//These are macros in INC\BOOK1632.H
SendScrollPosition(m_hWnd, WM_HSCROLL, rcl.left-8);
SendScrollPosition(m_hWnd, WM_VSCROLL, rcl.top-8);
return;
}
/*
* CTenant::AddVerbMenu
*
* Purpose:
* Creates the variable verb menu item for the object in this
* tenant.
*
* Parmeters:
* hMenu HMENU on which to add items.
* iPos UINT position on that menu to add items.
*
* Return Value:
* None
*/
void CTenant::AddVerbMenu(HMENU hMenu, UINT iPos)
{
HMENU hMenuTemp;
LPOLEOBJECT pObj=m_pIOleObject;
//If we're static, say we have no object.
if (TENANTTYPE_STATIC==m_tType)
pObj=NULL;
OleUIAddVerbMenu(pObj, NULL, hMenu, iPos, IDM_VERBMIN
, IDM_VERBMAX, TRUE, IDM_EDITCONVERT, &hMenuTemp);
return;
}
/*
* 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;
}
/*
* CTenant::CopyLinkedObject
*
* Purpose:
* Copies an linked 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 CF_LINKSOURCE
* if we put that in the data object.
* pptl PPOINTL to the pick point (NULL outside of
* drag-drop);
*
* Return Value:
* None
*/
void CTenant::CopyLinkedObject(LPDATAOBJECT pIDataObject
, LPFORMATETC pFE, PPOINTL pptl)
{
STGMEDIUM stm;
FORMATETC fe;
HRESULT hr;
UINT cf;
POINTL ptl;
LPMONIKER pmk;
CLSID clsID;
LPTSTR psz=NULL;
SIZEL szl;
//Can only copy links to embeddings from here.
if (TENANTTYPE_EMBEDDEDOBJECT!=m_tType || NULL==m_pIOleObject)
return;
//If we don't have a full moniker, no linking allowed
if (NULL==m_pmk)
return;
//If the object doesn't support this, return.
if (OLEMISC_CANTLINKINSIDE & m_grfMisc)
return;
if (NULL==pptl)
{
SETPOINTL(ptl, 0, 0);
pptl=&ptl;
}
/*
* We need to get CFSTR_LINKSOURCE, but the server may not be
* running, in which case we just grab the moniker and CLSID
* for this object and call INOLE_GetLinkSourceData.
*/
m_pIOleObject->GetUserClassID(&clsID);
hr=m_pIOleObject->GetMoniker(0, OLEWHICHMK_OBJFULL, &pmk);
if (FAILED(hr))
return;
stm.pUnkForRelease=NULL;
stm.tymed=TYMED_NULL;
cf=RegisterClipboardFormat(CFSTR_LINKSOURCE);
SETDefFormatEtc(fe, cf, TYMED_ISTREAM);
hr=INOLE_GetLinkSourceData(pmk, &clsID, &fe, &stm);
if (FAILED(hr))
{
pmk->Release();
return;
}
//Send it to the data object for transfer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -