📄 page.cpp
字号:
/*
* User selected Activate As, so:
* 1. Add the TreatAs entry in the registry
* through CoTreatAsClass
* 2. Unload all objects of the old CLSID that you
* have loaded.
* 3. Reload objects as desired
* 4. Activate the current object.
*/
hr=CoTreatAsClass(ct.clsid, ct.clsidNew);
if (SUCCEEDED(hr))
{
PCTenant pTenant;
UINT i;
for (i=0; i < m_cTenants; i++)
{
if (TenantGet(i, &pTenant, FALSE))
{
pTenant->GetInfo(&ti);
pTenant->Close(FALSE);
pTenant->Load(m_pIStorage, &ti);
}
}
fActivate=TRUE;
}
}
//These two steps insure the object knows of the size.
m_pTenantCur->SizeGet(&szl, FALSE);
m_pTenantCur->SizeSet(&szl, FALSE, TRUE);
m_pTenantCur->EnableRepaint(TRUE);
m_pTenantCur->Repaint();
if (fActivate)
m_pTenantCur->Activate(OLEIVERB_SHOW, NULL);
SetCursor(hCur);
}
CoTaskMemFree((void*)ct.lpszUserType);
INOLE_MetafilePictIconFree(ct.hMetaPict);
return TRUE;
}
/*
* CPages::FQueryLinksInPage
*
* Purpose:
* Pass through to current page to see if there are any linked
* objects.
*
* Parameters:
* None
*
* Return Value:
* None
*/
BOOL CPage::FQueryLinksInPage()
{
PCTenant pTenant;
UINT i;
BOOL fRet=FALSE;
for (i=0; i < m_cTenants; i++)
{
if (TenantGet(i, &pTenant, FALSE))
fRet |= (pTenant->TypeGet()==TENANTTYPE_LINKEDOBJECT);
}
return fRet;
}
/*
* CPage::ScrolledWindow
*
* Purpose:
* Instructs the page to call CTenant::UpdateInPlaceObjectRects
* for the current tenant when the window is scrolled.
*
* Parameters:
* None
*
* Return Value:
* None
*/
void CPage::ScrolledWindow(void)
{
UINT i;
PCTenant pTenant;
/*
* Tell all tenants to update the position of in-place objects.
* If you do not support inside-out, only the selected object
* need be notified.
*/
for (i=0; i < m_cTenants; i++)
{
if (!TenantGet(i, &pTenant, FALSE))
continue;
pTenant->UpdateInPlaceObjectRects(NULL, TRUE);
}
return;
}
/*
* CPage::SwitchActiveTenant
*
* Purpose:
* Changes the activation of in-place objects from the current
* one known to the page to the new one passed to this function.
* This is called from IOleInPlaceSite::OnUIDeactivate.
*
* Parameters:
* pTenant PCTenant that is becoming active.
*
* Return Value:
* None
*/
void CPage::SwitchActiveTenant(PCTenant pTenant)
{
BOOL fSelect;
/*
* If we're UI activating the selected tenant, don't
* bother changing selection--just so activation.
*/
fSelect=(pTenant!=m_pTenantCur);
/*
* The first time we UI Activate we're not switching
* anything so avoid the whole sequence.
*/
if (m_fFirstUIActivate)
{
m_fFirstUIActivate=FALSE;
return;
}
if (NULL!=m_pTenantCur && fSelect)
m_pTenantCur->Select(FALSE, TRUE);
m_pTenantCur=pTenant;
//Select the new tenant, but don't activate it again
if (NULL!=m_pTenantCur)
{
UINT i;
if (fSelect)
m_pTenantCur->Select(TRUE, FALSE);
//Find the new tenant in our list and move to the top
for (i=0; i < m_cTenants; i++)
{
PCTenant pTenList;
if (TenantGet(i, &pTenList, FALSE))
{
if (pTenList==m_pTenantCur)
{
HWND hWndObj;
m_iTenantCur=0;
//Remove the tenant and add to the top again.
SendMessage(m_hWndTenantList, LB_DELETESTRING
, i, 0L);
SendMessage(m_hWndTenantList, LB_INSERTSTRING
, 0, (LONG)pTenant);
hWndObj=pTenant->ObjectWindow();
if (NULL!=hWndObj)
{
SetWindowPos(hWndObj, HWND_TOP, 0, 0, 0, 0
, SWP_NOMOVE | SWP_NOSIZE
| SWP_NOACTIVATE);
}
break;
}
}
}
}
return;
}
//CHAPTER24MOD
/*
* CPage::ToggleDesignMode
* CPage::ToggleUIDead
* CPage::ToggleHatchHandles
*
* Purpose:
* Loops through all the tenants and toggles a state.
*/
void CPage::ToggleDesignMode(BOOL fDesign)
{
PCTenant pTenant;
int i;
/*
* We do this in reverse order such that when we reactivate
* objects coming out of design mode we reactivate the
* visible "top" tenant last, therefore it's in-place window
* will be top of the z-order in the container and will overlap
* other objects correctly.
*/
for (i=(int)m_cTenants-1; i >=0; i--)
{
if (TenantGet(i, &pTenant, FALSE))
pTenant->ToggleDesignMode(fDesign);
}
return;
}
void CPage::ToggleUIDead(BOOL fUIDead)
{
PCTenant pTenant;
UINT i;
for (i=0; i < m_cTenants; i++)
{
if (TenantGet(i, &pTenant, FALSE))
pTenant->ToggleUIDead(fUIDead);
}
return;
}
void CPage::ToggleHatchHandles(BOOL fHatchHandles)
{
PCTenant pTenant;
UINT i;
for (i=0; i < m_cTenants; i++)
{
if (TenantGet(i, &pTenant, FALSE))
pTenant->ToggleHatchHandles(fHatchHandles);
}
return;
}
/*
* CPage::FQueryEnableEvents
*
* Purpose:
* Returns whether to enable events for the current tenant.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE to enable the item, FALSE otherwise.
*/
BOOL CPage::FQueryEnableEvents(void)
{
DWORD dwFlags;
if (NULL==m_pTenantCur)
return FALSE;
dwFlags=m_pTenantCur->GetControlFlags();
return 0!=(TENANTSTATE_EVENTS & dwFlags);
}
/*
* CPage::AssignEvents
*
* Purpose:
* Invokes a dialog in which the user can assign actions to
* control events.
*
* Parameters:
* hWndParent HWND to use as the dialog parent.
*
* Return Value:
* None
*/
void CPage::AssignEvents(HWND hWndParent)
{
DialogBoxParam(m_pPG->m_hInst, MAKEINTRESOURCE(IDD_EVENTS)
, hWndParent, EventsDlgProc
, (LONG)m_pTenantCur->EventMap());
return;
}
/*
* CPage::TryMnemonic
*
* Purpose:
* Loops through all the tenants checking each for a match
* with a keybord mnemonic.
*
* Parameters:
* pMsg LPMSG containing the message to check.
*
* Return Value:
* BOOL TRUE if the mnemonic was a match with any
* tenant, FALSE otherwise.
*/
BOOL CPage::TryMnemonic(LPMSG pMsg)
{
BOOL fRet=FALSE;
UINT i;
for (i=0; i < m_cTenants; i++)
{
PCTenant pTenant;
if (TenantGet(i, &pTenant, FALSE))
{
fRet=pTenant->TryMnemonic(pMsg);
if (fRet)
break;
}
else
break;
}
return fRet;
}
//End CHAPTER24MOD
/*
* 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::TenantGetFromID
* (Protected)
*
* Purpose:
* Finds a tenant pointer from an ID for use from
* IOleItemContainer::GetObject
*
* Parameters:
* dwID DWORD identifier of the tenant to find.
* ppTenant PCTenant * 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::TenantGetFromID(DWORD dwID, PCTenant *ppTenant
, BOOL fOpen)
{
UINT i;
PCTenant pTenant;
if (NULL==ppTenant)
return FALSE;
for (i=0; i < m_cTenants; i++)
{
if (!TenantGet(i, &pTenant, FALSE))
continue;
if (pTenant->GetID()==dwID)
{
if (fOpen)
pTenant->Open(m_pIStorage);
*ppTenant=pTenant;
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;
//The constructor doesn't AddRef, so we need to.
pTenant->AddRef();
//Now try to add to the listbox.
lr=SendMessage(m_hWndTenantList, LB_INSERTSTRING, iTenant
, (LONG)pTenant);
if (lr < 0)
{
pTenant->Release();
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;
HGLOBAL hMem;
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);
//If this is a linked object, just copy a presentation
if (TENANTTYPE_LINKEDOBJECT==m_pTenantCur->TypeGet())
m_pTenantCur->FormatEtcGet(&ppo->fe, TRUE);
SETDefFormatEtc(fe, m_pPG->m_cf, TYMED_HGLOBAL);
pIDataObject->SetData(&fe, &stm, TRUE);
/*
* Here now we have to include CFSTR_EMBEDDEDOBJECT and
* CFSTR_OBJECTDESCRIPTOR when what we have selected is, in
* fact, a compound document object. We'll just ask the tenant
* to set these in pIDataObject since it knows what the object.
* If we copy embedded object data, make sure the PATRONOBJECT
* structure has the right format in it as well.
*/
m_pTenantCur->CopyEmbeddedObject(pIDataObject, &ppo->fe, pptl);
hMem=stm.hGlobal;
//Copy the actual presentation.
m_pTenantCur->FormatEtcGet(&fe, TRUE);
pIDataT->GetData(&fe, &stm);
pIDataObject->SetData(&fe, &stm, TRUE);
//Copy a link to this tenant if it's embedded
m_pTenantCur->CopyLinkedObject(pIDataObject, &ppo->fe, pptl);
GlobalUnlock(hMem); //ppo
pIDataT->Release();
pObj->Release();
return pIDataObject; //Caller now responsible
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -