353 lines
9 KiB
C++
353 lines
9 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (C) 1996-1999 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
iviewobj.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Implementation of the IViewObject interface.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "polyline.h"
|
||
|
#include "unihelpr.h"
|
||
|
#include "unkhlpr.h"
|
||
|
|
||
|
/*
|
||
|
* CImpIViewObject interface implementation
|
||
|
*/
|
||
|
|
||
|
IMPLEMENT_CONTAINED_INTERFACE(CPolyline, CImpIViewObject)
|
||
|
|
||
|
/*
|
||
|
* CImpIViewObject::Draw
|
||
|
*
|
||
|
* Purpose:
|
||
|
* Draws the object on the given hDC specifically for the requested
|
||
|
* aspect, device, and within the appropriate bounds.
|
||
|
*
|
||
|
* Parameters:
|
||
|
* dwAspect DWORD aspect to draw.
|
||
|
* lindex LONG index of the piece to draw.
|
||
|
* pvAspect LPVOID for extra information, always NULL.
|
||
|
* ptd DVTARGETDEVICE * containing device
|
||
|
* information.
|
||
|
* hICDev HDC containing the IC for the device.
|
||
|
* hDC HDC on which to draw.
|
||
|
* pRectBounds LPCRECTL describing the rectangle in which
|
||
|
* to draw.
|
||
|
* pRectWBounds LPCRECTL describing the placement rectangle
|
||
|
* if part of what you draw is another metafile.
|
||
|
* pfnContinue Function to call periodically during
|
||
|
* long repaints.
|
||
|
* dwContinue DWORD extra information to pass to the
|
||
|
* pfnContinue.
|
||
|
*
|
||
|
* Return Value:
|
||
|
* HRESULT NOERROR or a general error value.
|
||
|
*/
|
||
|
|
||
|
STDMETHODIMP CImpIViewObject::Draw(
|
||
|
DWORD dwAspect,
|
||
|
LONG lindex,
|
||
|
LPVOID pvAspect,
|
||
|
DVTARGETDEVICE *ptd,
|
||
|
HDC hICDev,
|
||
|
HDC hDC,
|
||
|
LPCRECTL pRectBounds,
|
||
|
LPCRECTL pRectWBounds,
|
||
|
BOOL (CALLBACK *pfnContinue) (DWORD_PTR),
|
||
|
DWORD_PTR dwContinue )
|
||
|
{
|
||
|
HRESULT hr = NOERROR;
|
||
|
RECT rc;
|
||
|
RECTL rectBoundsDP;
|
||
|
BOOL bMetafile = FALSE;
|
||
|
BOOL bDeleteDC = FALSE;
|
||
|
HDC hLocalICDev;
|
||
|
|
||
|
//Delegate iconic and printed representations.
|
||
|
if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspect)) {
|
||
|
hr = m_pObj->m_pDefIViewObject->Draw(dwAspect, lindex
|
||
|
, pvAspect, ptd, hICDev, hDC, pRectBounds, pRectWBounds
|
||
|
, pfnContinue, dwContinue);
|
||
|
} else {
|
||
|
|
||
|
if ( NULL == hDC ) {
|
||
|
hr = E_INVALIDARG;
|
||
|
} else if ( NULL == pRectBounds ) {
|
||
|
hr = E_POINTER;
|
||
|
} else {
|
||
|
if (hICDev == NULL) {
|
||
|
hLocalICDev = CreateTargetDC(hDC, ptd);
|
||
|
bDeleteDC = (hLocalICDev != hDC );
|
||
|
} else {
|
||
|
hLocalICDev = hICDev;
|
||
|
}
|
||
|
if ( NULL == hLocalICDev ) {
|
||
|
hr = E_UNEXPECTED;
|
||
|
} else {
|
||
|
|
||
|
rectBoundsDP = *pRectBounds;
|
||
|
bMetafile = GetDeviceCaps(hDC, TECHNOLOGY) == DT_METAFILE;
|
||
|
|
||
|
if (!bMetafile) {
|
||
|
::LPtoDP ( hLocalICDev, (LPPOINT)&rectBoundsDP, 2);
|
||
|
SaveDC ( hDC );
|
||
|
}
|
||
|
|
||
|
RECTFROMRECTL(rc, rectBoundsDP);
|
||
|
|
||
|
m_pObj->Draw(hDC, hLocalICDev, FALSE, TRUE, &rc);
|
||
|
|
||
|
if (bDeleteDC)
|
||
|
::DeleteDC(hLocalICDev);
|
||
|
if (!bMetafile)
|
||
|
RestoreDC(hDC, -1);
|
||
|
|
||
|
hr = NOERROR;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* CImpIViewObject::GetColorSet
|
||
|
*
|
||
|
* Purpose:
|
||
|
* Retrieves the color palette used by the object.
|
||
|
*
|
||
|
* Parameters:
|
||
|
* dwAspect DWORD aspect of interest.
|
||
|
* lindex LONG piece of interest.
|
||
|
* pvAspect LPVOID with extra information, always NULL.
|
||
|
* ptd DVTARGETDEVICE * containing device info.
|
||
|
* hICDev HDC containing the IC for the device.
|
||
|
* ppColorSet LPLOGPALETTE * into which to return the
|
||
|
* pointer to the palette in this color set.
|
||
|
*
|
||
|
* Return Value:
|
||
|
* HRESULT NOERROR or a general error value.
|
||
|
*/
|
||
|
|
||
|
STDMETHODIMP CImpIViewObject::GetColorSet(
|
||
|
DWORD, // dwDrawAspect
|
||
|
LONG, // lindex
|
||
|
LPVOID, // pvAspect,
|
||
|
DVTARGETDEVICE *, // ptd
|
||
|
HDC, // hICDev,
|
||
|
LPLOGPALETTE * /* ppColorSet */) {
|
||
|
return ResultFromScode(E_NOTIMPL);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* CImpIViewObject::Freeze
|
||
|
*
|
||
|
* Purpose:
|
||
|
* Freezes the view of a particular aspect such that data
|
||
|
* changes do not affect the view.
|
||
|
*
|
||
|
* Parameters:
|
||
|
* dwAspect DWORD aspect to freeze.
|
||
|
* lindex LONG piece index under consideration.
|
||
|
* pvAspect LPVOID for further information, always NULL.
|
||
|
* pdwFreeze LPDWORD in which to return the key.
|
||
|
*
|
||
|
* Return Value:
|
||
|
* HRESULT NOERROR or a general error value.
|
||
|
*/
|
||
|
|
||
|
STDMETHODIMP CImpIViewObject::Freeze(DWORD dwAspect, LONG lindex
|
||
|
, LPVOID pvAspect, LPDWORD pdwFreeze)
|
||
|
{
|
||
|
//Delegate anything for ICON or DOCPRINT aspects
|
||
|
if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspect))
|
||
|
{
|
||
|
return m_pObj->m_pDefIViewObject->Freeze(dwAspect, lindex
|
||
|
, pvAspect, pdwFreeze);
|
||
|
}
|
||
|
|
||
|
if (dwAspect & m_pObj->m_dwFrozenAspects)
|
||
|
{
|
||
|
*pdwFreeze=dwAspect + FREEZE_KEY_OFFSET;
|
||
|
return ResultFromScode(VIEW_S_ALREADY_FROZEN);
|
||
|
}
|
||
|
|
||
|
m_pObj->m_dwFrozenAspects |= dwAspect;
|
||
|
|
||
|
if (NULL!=pdwFreeze)
|
||
|
*pdwFreeze=dwAspect + FREEZE_KEY_OFFSET;
|
||
|
|
||
|
return NOERROR;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* CImpIViewObject::Unfreeze
|
||
|
*
|
||
|
* Purpose:
|
||
|
* Thaws an aspect frozen in ::Freeze. We expect that a container
|
||
|
* will redraw us after freezing if necessary, so we don't send
|
||
|
* any sort of notification here.
|
||
|
*
|
||
|
* Parameters:
|
||
|
* dwFreeze DWORD key returned from ::Freeze.
|
||
|
*
|
||
|
* Return Value:
|
||
|
* HRESULT NOERROR or a general error value.
|
||
|
*/
|
||
|
|
||
|
STDMETHODIMP CImpIViewObject::Unfreeze(DWORD dwFreeze)
|
||
|
{
|
||
|
DWORD dwAspect=dwFreeze - FREEZE_KEY_OFFSET;
|
||
|
|
||
|
//Delegate anything for ICON or DOCPRINT aspects
|
||
|
if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspect))
|
||
|
m_pObj->m_pDefIViewObject->Unfreeze(dwFreeze);
|
||
|
|
||
|
//The aspect to unfreeze is in the key.
|
||
|
m_pObj->m_dwFrozenAspects &= ~(dwAspect);
|
||
|
|
||
|
/*
|
||
|
* Since we always kept our current data up to date, we don't
|
||
|
* have to do anything thing here like requesting data again.
|
||
|
* Because we removed dwAspect from m_dwFrozenAspects, Draw
|
||
|
* will again use the current data.
|
||
|
*/
|
||
|
|
||
|
return NOERROR;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* CImpIViewObject::SetAdvise
|
||
|
*
|
||
|
* Purpose:
|
||
|
* Provides an advise sink to the view object enabling
|
||
|
* notifications for a specific aspect.
|
||
|
*
|
||
|
* Parameters:
|
||
|
* dwAspects DWORD describing the aspects of interest.
|
||
|
* dwAdvf DWORD containing advise flags.
|
||
|
* pIAdviseSink LPADVISESINK to notify.
|
||
|
*
|
||
|
* Return Value:
|
||
|
* HRESULT NOERROR or a general error value.
|
||
|
*/
|
||
|
|
||
|
STDMETHODIMP CImpIViewObject::SetAdvise(DWORD dwAspects, DWORD dwAdvf
|
||
|
, LPADVISESINK pIAdviseSink)
|
||
|
{
|
||
|
//Pass anything with DVASPECT_ICON or _DOCPRINT to the handler.
|
||
|
if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspects))
|
||
|
{
|
||
|
m_pObj->m_pDefIViewObject->SetAdvise(dwAspects, dwAdvf
|
||
|
, pIAdviseSink);
|
||
|
}
|
||
|
|
||
|
//We continue because dwAspects may have more than one in it.
|
||
|
if (NULL!=m_pObj->m_pIAdviseSink)
|
||
|
m_pObj->m_pIAdviseSink->Release();
|
||
|
|
||
|
m_pObj->m_pIAdviseSink=pIAdviseSink;
|
||
|
m_pObj->m_dwAdviseAspects=dwAspects;
|
||
|
m_pObj->m_dwAdviseFlags=dwAdvf;
|
||
|
|
||
|
if (NULL!=m_pObj->m_pIAdviseSink)
|
||
|
m_pObj->m_pIAdviseSink->AddRef();
|
||
|
|
||
|
return NOERROR;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* CImpIViewObject::GetAdvise
|
||
|
*
|
||
|
* Purpose:
|
||
|
* Returns the last known IAdviseSink seen by ::SetAdvise.
|
||
|
*
|
||
|
* Parameters:
|
||
|
* pdwAspects LPDWORD in which to store the last
|
||
|
* requested aspects.
|
||
|
* pdwAdvf LPDWORD in which to store the last
|
||
|
* requested flags.
|
||
|
* ppIAdvSink LPADVISESINK * in which to store the
|
||
|
* IAdviseSink.
|
||
|
*
|
||
|
* Return Value:
|
||
|
* HRESULT NOERROR or a general error value.
|
||
|
*/
|
||
|
|
||
|
STDMETHODIMP CImpIViewObject::GetAdvise(LPDWORD pdwAspects
|
||
|
, LPDWORD pdwAdvf, LPADVISESINK *ppAdvSink)
|
||
|
{
|
||
|
if (NULL != ppAdvSink) {
|
||
|
|
||
|
*ppAdvSink = m_pObj->m_pIAdviseSink;
|
||
|
|
||
|
if (m_pObj->m_pIAdviseSink != NULL)
|
||
|
m_pObj->m_pIAdviseSink->AddRef();
|
||
|
}
|
||
|
|
||
|
if (NULL != pdwAspects)
|
||
|
*pdwAspects = m_pObj->m_dwAdviseAspects;
|
||
|
|
||
|
if (NULL != pdwAdvf)
|
||
|
*pdwAdvf = m_pObj->m_dwAdviseFlags;
|
||
|
|
||
|
return NOERROR;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* CImpIViewObject::GetExtent
|
||
|
*
|
||
|
* Purpose:
|
||
|
* Retrieves the extents of the object's display.
|
||
|
*
|
||
|
* Parameters:
|
||
|
* dwAspect DWORD of the aspect of interest.
|
||
|
* lindex LONG index of the piece of interest.
|
||
|
* ptd DVTARGETDEVICE * with device information.
|
||
|
* pszl LPSIZEL to the structure in which to return
|
||
|
* the extents.
|
||
|
*
|
||
|
* Return Value:
|
||
|
* HRESULT NOERROR or a general error value.
|
||
|
*/
|
||
|
|
||
|
STDMETHODIMP CImpIViewObject::GetExtent(DWORD dwAspect, LONG lindex
|
||
|
, DVTARGETDEVICE *ptd, LPSIZEL pszl)
|
||
|
{
|
||
|
RECT rc;
|
||
|
|
||
|
if (!(DVASPECT_CONTENT & dwAspect))
|
||
|
{
|
||
|
return m_pObj->m_pDefIViewObject->GetExtent(dwAspect
|
||
|
, lindex, ptd, pszl);
|
||
|
}
|
||
|
|
||
|
m_pObj->m_pImpIPolyline->RectGet(&rc);
|
||
|
m_pObj->RectConvertMappings(&rc, FALSE);
|
||
|
|
||
|
pszl->cx=rc.right-rc.left;
|
||
|
pszl->cy=rc.bottom-rc.top;
|
||
|
|
||
|
return NOERROR;
|
||
|
}
|
||
|
|