📄 page.cpp
字号:
* NULL which is acceptable.
*/
if (m_pPG->DevReadConfig(&pcd, &hIC))
ptd=&(pcd->td);
}
for (i=(int)m_cTenants-1; i >=0; i--)
{
if (TenantGet(i, &pTenant, FALSE))
{
RECT rc, rcWin;
RECTL rcl;
//Paint this tenant only if visible.
pTenant->RectGet(&rcl, TRUE);
RECTFROMRECTL(rc, rcl);
OffsetRect(&rc, -(int)m_pPG->m_xPos
, -(int)m_pPG->m_yPos);
GetClientRect(m_hWnd, &rcWin);
if (IntersectRect(&rc, &rc, &rcWin))
{
pTenant->Draw(hDC, ptd, hIC, xOff, yOff
, fNoColor, fPrinter);
}
}
}
//Free whatever CPages::DevReadConfig returned.
if (NULL!=pcd)
{
LPMALLOC pIMalloc;
if (SUCCEEDED(CoGetMalloc(MEMCTX_TASK, &pIMalloc)))
{
pIMalloc->Free(pcd);
pIMalloc->Release();
}
}
if (NULL!=hIC)
DeleteDC(hIC);
return;
}
/*
* CPage::TenantCreate
*
* Purpose:
* Creates a new tenant of a specific type.
*
* Parameters:
* tType TENANTTYPE to create.
* pv LPVOID providing information for the new
* object creation.
* pFE LPFORMATETC describing how we want this
* rendered.
* ppo PPATRONOBJECT with placement data.
* dwData DWORD extra data to pass to the tenant.
*
* Return Value:
* None
*/
BOOL CPage::TenantCreate(TENANTTYPE tType, LPVOID pv
, LPFORMATETC pFE, PPATRONOBJECT ppo, DWORD dwData)
{
PCTenant pTenant;
UINT uRet;
int x, y;
int h, v;
POINTL ptl;
SIZEL szl;
RECTL rcl;
RECT rc;
//New tenants go at top of the pile; zero index to TenantAdd.
if (!TenantAdd(0, m_dwIDNext, &pTenant))
return FALSE;
uRet=pTenant->Create(tType, pv, pFE, &ptl, &szl, m_pIStorage
, ppo, dwData);
if (CREATE_FAILED==uRet)
{
//Reverse Create AND TenantAdd
SendMessage(m_hWndTenantList, LB_DELETESTRING, 0, 0L);
pTenant->Destroy(m_pIStorage);
delete pTenant;
return FALSE;
}
m_dwIDNext++;
m_cTenants++;
if (NULL!=m_pTenantCur)
m_pTenantCur->Select(FALSE);
m_iTenantCur=0; //First one in the list now.
m_pTenantCur=pTenant;
//Tell the tenant where it lives, default is (0,0) in print area
x=LOMETRIC_BORDER+m_pPG->m_xMarginLeft;
y=-LOMETRIC_BORDER-m_pPG->m_yMarginTop;
h=x;
v=y;
if (CREATE_PLACEDOBJECT==uRet)
{
SetRect(&rc, 3*CXYHANDLE, 3*CXYHANDLE, 0, 0);
RectConvertMappings(&rc, NULL, FALSE);
//Make sure place point is on page, otherwise go to (0,0)
if (((int)ptl.x > x)
&& ((int)ptl.x < x+(int)m_pPG->m_cx-rc.left))
x=(int)ptl.x;
//m_pPG->m_cy is absolute
if (((int)ptl.y < y)
&& ((int)ptl.y > y-(int)m_pPG->m_cy-rc.top))
y=(int)ptl.y;
}
//Bounds check size of the object and fit to page as necessary.
if (x+(int)szl.cx > (int)(h+m_pPG->m_cx))
szl.cx=h+m_pPG->m_cx-x;
//Remember that szl we get from Create is absolute
if (y-(int)szl.cy < (int)(v-m_pPG->m_cy))
szl.cy=-(int)(v-m_pPG->m_cy-y);
SETRECTL(rcl, x, y, x+szl.cx, y-szl.cy);
m_pTenantCur->RectSet(&rcl, FALSE);
//Force a repaint on this new guy
m_pTenantCur->Invalidate();
UpdateWindow(m_hWnd);
m_pTenantCur->Select(TRUE);
return TRUE;
}
/*
* CPage::TenantDestroy
*
* Purpose:
* Destroys the currently selected tenant on this page.
*
* Parameters:
* None
*
* Return Value:
* None
*/
BOOL CPage::TenantDestroy(void)
{
if (NULL==m_pTenantCur)
{
MessageBeep(0);
return FALSE;
}
SendMessage(m_hWndTenantList, LB_DELETESTRING
, m_iTenantCur, 0L);
m_pTenantCur->Invalidate();
m_pTenantCur->Destroy(m_pIStorage);
delete m_pTenantCur;
m_pTenantCur=NULL;
//Update counts, etc., and select the next tenant in the list.
if (m_iTenantCur==m_cTenants-1)
m_iTenantCur--;
if (0==--m_cTenants)
m_pTenantCur=NULL;
else
{
TenantGet(m_iTenantCur, &m_pTenantCur, TRUE);
m_pTenantCur->Select(TRUE);
}
UpdateWindow(m_hWnd);
return TRUE;
}
/*
* CPage::TenantClip
*
* Purpose:
* Copies or cuts the currently selected tenant to the clipoard.
*
* Parameters:
* fCut BOOL TRUE to cut the object, FALSE to copy.
*
* Return Value:
* BOOL TRUE if successful, FALSE otherwise.
*/
BOOL CPage::TenantClip(BOOL fCut)
{
LPDATAOBJECT pIDataObject;
BOOL fRet=FALSE;
if (NULL==m_pTenantCur)
return FALSE;
/*
* To perform a data transfer operation, we need to create a
* data object with the selected object's data inside. To do
* this we CoCreateInstance on CLSID_DataTransferObject
* (Also implemented in this chapter), retrieve data from the
* object we have, stuff that data into the transfer object,
* then stick that object on the clipboard.
*
* Since we'll want an identical object at other times, like for
* drag-drop, we use a private function to actually create it.
*/
pIDataObject=TransferObjectCreate(NULL);
if (NULL!=pIDataObject)
{
if (SUCCEEDED(OleSetClipboard(pIDataObject)))
{
if (fCut)
TenantDestroy();
fRet=TRUE;
}
pIDataObject->Release();
}
return fRet;
}
/*
* CPage::FQueryObjectSelected
*
* Purpose:
* Returns whether or not there is an object selected on this
* page for Cut, Copy, Delete functions.
*
* Parameters:
* hMenu HMENU of the Edit menu.
*
* Return Value:
* BOOL TRUE if we have an object, FALSE otherwise.
*/
BOOL CPage::FQueryObjectSelected(HMENU hMenu)
{
return (NULL!=m_pTenantCur);
}
/*
* CPage::TenantGet
* (Protected)
*
* Purpose:
* Returns a tenant of a given index returning a BOOL so it's
* simple to use this function inside if statements.
*
* Parameters:
* iTenant UINT tenant to retrieve 0 based.
* ppTenant PCPage * in which to return the tenant
* pointer
* fOpen BOOL indicating if we should open this
* tenant as well.
*
* Return Value:
* BOOL TRUE if successful, FALSE otherwise.
*/
BOOL CPage::TenantGet(UINT iTenant, PCTenant *ppTenant
, BOOL fOpen)
{
if (NULL==ppTenant)
return FALSE;
if (LB_ERR!=SendMessage(m_hWndTenantList, LB_GETTEXT
, iTenant, (LONG)ppTenant))
{
if (fOpen)
(*ppTenant)->Open(m_pIStorage);
return TRUE;
}
return FALSE;
}
/*
* CPage::TenantAdd
* (Protected)
*
* Purpose:
* Creates a new tenant initialized to the given values. The new
* tenants's storage is created if it does not already exist. If
* fOpenStorage is set the the tenants's storage is opened and left
* opened.
*
* Parameters:
* iTenant UINT Location at which to insert tenant; new
* tenant is inserted after this position. NOVALUE
* for the end.
* dwID DWORD ID for this tenant.
* ppNew PCTenant * in which to store the new tenant.
*
* Return Value:
* BOOL TRUE if the function succeeded, FALSE otherwise.
*/
BOOL CPage::TenantAdd(UINT iTenant, DWORD dwID
, PCTenant *ppNew)
{
PCTenant pTenant;
LRESULT lr;
if (NULL!=ppNew)
*ppNew=NULL;
pTenant=new CTenant(dwID, m_hWnd, m_pPG);
if (NULL==pTenant)
return FALSE;
//Now try to add to the listbox.
lr=SendMessage(m_hWndTenantList, LB_INSERTSTRING, iTenant
, (LONG)pTenant);
if (lr < 0)
{
delete pTenant;
return FALSE;
}
*ppNew=pTenant;
return TRUE;
}
/*
* CPage::TransferObjectCreate
* (Protected)
*
* Purpose:
* Creates a DataTransferObject and stuff the current selection's
* data into it.
*
* Parameters:
* pptl PPOINTL containing the pick point in device
* units applicable only to drag-drop; since
* drag-drop is inherently mouse oriented, we use
* device units for the point. Ignored if NULL.
*
* Return Value:
* LPDATAOBJECT Pointer to the object created, NULL on failure
*/
LPDATAOBJECT CPage::TransferObjectCreate(PPOINTL pptl)
{
LPDATAOBJECT pIDataObject;
LPDATAOBJECT pIDataT;
PPATRONOBJECT ppo;
RECTL rcl;
LPUNKNOWN pObj;
FORMATETC fe;
STGMEDIUM stm;
HRESULT hr;
m_pTenantCur->ObjectGet(&pObj);
hr=CoCreateInstance(CLSID_DataTransferObject, NULL
, CLSCTX_INPROC_SERVER, IID_IDataObject
, (PPVOID)&pIDataObject);
if (FAILED(hr))
return NULL;
//Go get the data we should hold on to.
hr=pObj->QueryInterface(IID_IDataObject, (PPVOID)&pIDataT);
if (FAILED(hr))
{
pIDataObject->Release();
pObj->Release();
return NULL;
}
//Copy from known obj into transfer obj. Ordering is important!
//Generate placeable object structure
stm.tymed=TYMED_HGLOBAL;
stm.pUnkForRelease=NULL;
stm.hGlobal=GlobalAlloc(GHND, sizeof(PATRONOBJECT));
if (NULL==stm.hGlobal)
{
pIDataObject->Release();
pObj->Release();
return NULL;
}
ppo=(PPATRONOBJECT)GlobalLock(stm.hGlobal);
m_pTenantCur->SizeGet(&ppo->szl, FALSE);
ppo->szl.cy=-ppo->szl.cy; //Negate to make absolute size
m_pTenantCur->RectGet(&rcl, FALSE);
ppo->ptl.x=rcl.left;
ppo->ptl.y=rcl.top;
if (NULL==pptl)
{
ppo->ptlPick.x=0;
ppo->ptlPick.y=0;
}
else
ppo->ptlPick=*pptl;
m_pTenantCur->FormatEtcGet(&ppo->fe, FALSE);
GlobalUnlock(stm.hGlobal);
SETDefFormatEtc(fe, m_pPG->m_cf, TYMED_HGLOBAL);
pIDataObject->SetData(&fe, &stm, TRUE);
//Copy the actual presentation.
m_pTenantCur->FormatEtcGet(&fe, TRUE);
pIDataT->GetData(&fe, &stm);
pIDataObject->SetData(&fe, &stm, TRUE);
pIDataT->Release();
pObj->Release();
return pIDataObject; //Caller now responsible
}
//End CHAPTER12MOD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -