2312 lines
51 KiB
C++
2312 lines
51 KiB
C++
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1992 - 1993.
|
||
|
//
|
||
|
// File: mf.cpp
|
||
|
//
|
||
|
// Contents: Implentation of hte metafile picture object
|
||
|
//
|
||
|
// Classes: CMfObject
|
||
|
//
|
||
|
// Functions: OleIsDcMeta
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 01-Feb-95 t-ScottH added Dump method to CMfObject
|
||
|
// added DumpCMfObject API
|
||
|
// initialize m_pfnContinue in constructor
|
||
|
// 25-Jan-94 alexgo first pass at converting to Cairo-style
|
||
|
// memory allocations.
|
||
|
// 11-Jan-93 alexgo added VDATEHEAP macros to every
|
||
|
// function and method
|
||
|
// 31-Dec-93 ErikGav chicago port
|
||
|
// 17-Dec-93 ChrisWe fixed second argument to SelectPalette calls
|
||
|
// in CallbackFuncForDraw
|
||
|
// 07-Dec-93 ChrisWe made default params to StSetSize explicit
|
||
|
// 07-Dec-93 alexgo merged 16bit RC9 changes
|
||
|
// 29-Nov-93 alexgo 32bit port
|
||
|
// 04-Jun-93 srinik support for demand loading and discarding
|
||
|
// of caches
|
||
|
// 13-Mar-92 srinik created
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
#include <le2int.h>
|
||
|
#include <qd2gdi.h>
|
||
|
#include "mf.h"
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#include <dbgdump.h>
|
||
|
#endif // _DEBUG
|
||
|
|
||
|
#define M_HPRES() (m_hPres ? m_hPres : LoadHPRES())
|
||
|
|
||
|
/*
|
||
|
* IMPLEMENTATION of CMfObject
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::CMfObject
|
||
|
//
|
||
|
// Synopsis: constructor for the metafile object
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [pCacheNode] -- pointer to the cache node for this object
|
||
|
// [dwAspect] -- drawing aspect for the object
|
||
|
// [fConvert] -- specifies whether to convert from Mac
|
||
|
// QuickDraw format
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 13-Feb-95 t-ScottH initialize m_pfnContinue
|
||
|
// 29-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
CMfObject::CMfObject(LPCACHENODE pCacheNode, DWORD dwAspect, BOOL fConvert)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
m_ulRefs = 1;
|
||
|
m_hPres = NULL;
|
||
|
m_dwSize = 0;
|
||
|
m_dwAspect = dwAspect;
|
||
|
m_pCacheNode = pCacheNode;
|
||
|
m_dwContinue = 0;
|
||
|
m_pfnContinue = NULL;
|
||
|
m_lWidth = 0;
|
||
|
m_lHeight = 0;
|
||
|
|
||
|
m_fConvert = fConvert;
|
||
|
m_pMetaInfo = NULL;
|
||
|
m_pCurMdc = NULL;
|
||
|
m_fMetaDC = FALSE;
|
||
|
m_nRecord = 0;
|
||
|
m_error = NOERROR;
|
||
|
m_pColorSet = NULL;
|
||
|
|
||
|
m_hPalDCOriginal = NULL;
|
||
|
m_hPalLast = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::~CMfObject
|
||
|
//
|
||
|
// Synopsis: Destroys a metafile presentation object
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: void
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: void
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 29-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
CMfObject::~CMfObject (void)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
CMfObject::DiscardHPRES();
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::QueryInterface
|
||
|
//
|
||
|
// Synopsis: returns supported interfaces
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [iid] -- the requested interface ID
|
||
|
// [ppvObj] -- where to put the interface pointer
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: NOERROR, E_NOINTERFACE
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation: IOlePresObj
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 29-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP CMfObject::QueryInterface (REFIID iid, void FAR* FAR* ppvObj)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
if (IsEqualIID(iid, IID_IUnknown) || IsEqualIID(iid, IID_IOlePresObj))
|
||
|
{
|
||
|
*ppvObj = this;
|
||
|
AddRef();
|
||
|
return NOERROR;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*ppvObj = NULL;
|
||
|
return E_NOINTERFACE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::AddRef
|
||
|
//
|
||
|
// Synopsis: Increments the reference count
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: void
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: ULONG -- the new reference count
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation: IOlePresObj
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 29-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CMfObject::AddRef(void)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
return ++m_ulRefs;
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::Release
|
||
|
//
|
||
|
// Synopsis: decrements the reference count
|
||
|
//
|
||
|
// Effects: deletes the object once the ref count goes to zero
|
||
|
//
|
||
|
// Arguments: void
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: ULONG -- the new reference count
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation: IOlePresObj
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 29-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CMfObject::Release(void)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
if (--m_ulRefs == 0) {
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return m_ulRefs;
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::GetData
|
||
|
//
|
||
|
// Synopsis: Retrieves data in the specified format from the object
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [pformatetcIn] -- the requested data format
|
||
|
// [pmedium] -- where to put the data
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: HRESULT
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation: IOlePresObject
|
||
|
//
|
||
|
// Algorithm: Does error checking and then gets a copy of the metafilepict
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 29-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP CMfObject::GetData(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
SCODE sc;
|
||
|
|
||
|
// null out in case of error
|
||
|
pmedium->tymed = (DWORD) TYMED_NULL;
|
||
|
pmedium->pUnkForRelease = NULL;
|
||
|
|
||
|
if (!(pformatetcIn->tymed & (DWORD) TYMED_MFPICT))
|
||
|
{
|
||
|
sc = DV_E_TYMED;
|
||
|
}
|
||
|
else if (pformatetcIn->cfFormat != CF_METAFILEPICT)
|
||
|
{
|
||
|
sc = DV_E_CLIPFORMAT;
|
||
|
}
|
||
|
else if (IsBlank())
|
||
|
{
|
||
|
sc = OLE_E_BLANK;
|
||
|
}
|
||
|
// here we actually try to get the data
|
||
|
else if (NULL == (pmedium->hGlobal = GetHmfp()))
|
||
|
{
|
||
|
sc = E_OUTOFMEMORY;
|
||
|
}
|
||
|
else {
|
||
|
pmedium->tymed = (DWORD) TYMED_MFPICT;
|
||
|
return NOERROR;
|
||
|
}
|
||
|
|
||
|
return ResultFromScode(sc);
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::GetDataHere
|
||
|
//
|
||
|
// Synopsis: Retrieves data of the specified format into the specified
|
||
|
// medium
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [pformatetcIn] -- the requested data format
|
||
|
// [pmedium] -- where to put the data
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: HRESULT
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation: IOlePresObj
|
||
|
//
|
||
|
// Algorithm: Does error checking and then copies the metafile into a
|
||
|
// stream.
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 29-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP CMfObject::GetDataHere
|
||
|
(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
SCODE sc;
|
||
|
|
||
|
if (pformatetcIn->cfFormat != CF_METAFILEPICT)
|
||
|
{
|
||
|
sc = DV_E_CLIPFORMAT;
|
||
|
}
|
||
|
else if (pmedium->tymed != (DWORD) TYMED_ISTREAM)
|
||
|
{
|
||
|
sc = DV_E_TYMED;
|
||
|
}
|
||
|
else if (pmedium->pstm == NULL)
|
||
|
{
|
||
|
sc = E_INVALIDARG;
|
||
|
}
|
||
|
else if (IsBlank())
|
||
|
{
|
||
|
sc = OLE_E_BLANK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
HANDLE hpres = M_HPRES();
|
||
|
return UtHMFToPlaceableMFStm(&hpres, m_dwSize, m_lWidth,
|
||
|
m_lHeight, pmedium->pstm);
|
||
|
}
|
||
|
|
||
|
return ResultFromScode(sc);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::SetDataWDO
|
||
|
//
|
||
|
// Synopsis: Stores a metafile in this object
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [pformatetc] -- format of the data coming in
|
||
|
// [pmedium] -- the new metafile (data)
|
||
|
// [fRelease] -- if true, then we'll release the [pmedium]
|
||
|
// [pDataObj] -- unused for MF objects
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: HRESULT
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation: IOlePresObj
|
||
|
//
|
||
|
// Algorithm: does error checking and then stores the new data.
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 29-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP CMfObject::SetDataWDO (LPFORMATETC pformatetc,
|
||
|
STGMEDIUM * pmedium,
|
||
|
BOOL fRelease,
|
||
|
IDataObject * /* UNUSED */)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
HRESULT error;
|
||
|
BOOL fTakeData = FALSE;
|
||
|
|
||
|
if (pformatetc->cfFormat != CF_METAFILEPICT)
|
||
|
{
|
||
|
return ResultFromScode(DV_E_CLIPFORMAT);
|
||
|
}
|
||
|
|
||
|
if (pmedium->tymed != (DWORD) TYMED_MFPICT)
|
||
|
{
|
||
|
return ResultFromScode(DV_E_TYMED);
|
||
|
}
|
||
|
|
||
|
if ((pmedium->pUnkForRelease == NULL) && fRelease)
|
||
|
{
|
||
|
// we can take the ownership of the data
|
||
|
fTakeData = TRUE;
|
||
|
}
|
||
|
|
||
|
// ChangeData will keep the data if fRelease is TRUE, else it copies
|
||
|
error = ChangeData (pmedium->hGlobal, fTakeData);
|
||
|
|
||
|
if (fTakeData)
|
||
|
{
|
||
|
pmedium->tymed = (DWORD) TYMED_NULL;
|
||
|
}
|
||
|
else if (fRelease)
|
||
|
{
|
||
|
ReleaseStgMedium(pmedium);
|
||
|
}
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::GetHmfp (internal)
|
||
|
//
|
||
|
// Synopsis: Gets a copy of the stored metafile presentation
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: void
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: HANDLE
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation: IOlePresObj
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 29-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
INTERNAL_(HANDLE) CMfObject::GetHmfp (void)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
return UtGetHMFPICT((HMETAFILE)GetCopyOfHPRES(), TRUE, m_lWidth,
|
||
|
m_lHeight);
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::ChangeData (internal)
|
||
|
//
|
||
|
// Synopsis: Swaps the stored metafile presentation
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [hMfp] -- the new metafile
|
||
|
// [fDelete] -- if TRUE, then delete [hMfp]
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: HRESULT
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 29-Nov-93 alexgo 32bit port, fixed GlobalUnlock bug
|
||
|
// Notes:
|
||
|
//
|
||
|
// If the routine fails then the object will be left with it's old data.
|
||
|
// If fDelete is TRUE, then hMeta, and the hMF it contains will be deleted
|
||
|
// whether the routine is successful or not.
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
INTERNAL CMfObject::ChangeData (HANDLE hMfp, BOOL fDelete)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
|
||
|
HANDLE hNewMF;
|
||
|
LPMETAFILEPICT lpMetaPict;
|
||
|
DWORD dwSize;
|
||
|
HRESULT error = NOERROR;
|
||
|
|
||
|
if ((lpMetaPict = (LPMETAFILEPICT) GlobalLock (hMfp)) == NULL)
|
||
|
{
|
||
|
if (fDelete)
|
||
|
{
|
||
|
LEVERIFY( NULL == GlobalFree (hMfp) );
|
||
|
}
|
||
|
return E_OUTOFMEMORY;
|
||
|
}
|
||
|
|
||
|
if (!fDelete) {
|
||
|
if (NULL == (hNewMF = CopyMetaFile (lpMetaPict->hMF, NULL)))
|
||
|
{
|
||
|
return E_OUTOFMEMORY;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hNewMF = lpMetaPict->hMF;
|
||
|
}
|
||
|
|
||
|
|
||
|
if (lpMetaPict->mm != MM_ANISOTROPIC)
|
||
|
{
|
||
|
error = ResultFromScode(E_UNSPEC);
|
||
|
LEWARN( error, "Mapping mode is not anisotropic" );
|
||
|
|
||
|
}
|
||
|
else if (0 == (dwSize = MfGetSize (&hNewMF)))
|
||
|
{
|
||
|
error = ResultFromScode(OLE_E_BLANK);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (m_hPres)
|
||
|
{
|
||
|
LEVERIFY( DeleteMetaFile (m_hPres) );
|
||
|
}
|
||
|
m_hPres = (HMETAFILE)hNewMF;
|
||
|
m_dwSize = dwSize;
|
||
|
m_lWidth = lpMetaPict->xExt;
|
||
|
m_lHeight = lpMetaPict->yExt;
|
||
|
}
|
||
|
|
||
|
GlobalUnlock (hMfp);
|
||
|
|
||
|
if (error != NOERROR)
|
||
|
{
|
||
|
LEVERIFY( DeleteMetaFile ((HMETAFILE)hNewMF) );
|
||
|
}
|
||
|
|
||
|
if (fDelete)
|
||
|
{
|
||
|
LEVERIFY( NULL == GlobalFree (hMfp) );
|
||
|
}
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::Draw
|
||
|
//
|
||
|
// Synopsis: Draws the stored presentation
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [pvAspect] -- the drawing aspect
|
||
|
// [hicTargetDev] -- the target device
|
||
|
// [hdcDraw] -- hdc to draw into
|
||
|
// [lprcBounds] -- bounding rectangle to draw into
|
||
|
// [lprcWBounds] -- bounding rectangle for the metafile
|
||
|
// [pfnContinue] -- function to call while drawing
|
||
|
// [dwContinue] -- parameter to [pfnContinue]
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: HRESULT
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation: IOlePresObj
|
||
|
//
|
||
|
// Algorithm: Sets the viewport and metafile boundaries, then plays
|
||
|
// the metafile
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 29-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP CMfObject::Draw (void * /* UNUSED pvAspect */,
|
||
|
HDC /* UNUSED hicTargetDev */,
|
||
|
HDC hdcDraw,
|
||
|
LPCRECTL lprcBounds,
|
||
|
LPCRECTL lprcWBounds,
|
||
|
BOOL (CALLBACK * pfnContinue)(ULONG_PTR),
|
||
|
ULONG_PTR dwContinue)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
m_error = NOERROR;
|
||
|
|
||
|
int iRgn;
|
||
|
int iOldDc;
|
||
|
RECT rect;
|
||
|
LPRECT lpRrc = (LPRECT) ▭
|
||
|
|
||
|
Assert(lprcBounds);
|
||
|
|
||
|
if (!M_HPRES())
|
||
|
{
|
||
|
return ResultFromScode(OLE_E_BLANK);
|
||
|
}
|
||
|
|
||
|
rect.left = lprcBounds->left;
|
||
|
rect.right = lprcBounds->right;
|
||
|
rect.top = lprcBounds->top;
|
||
|
rect.bottom = lprcBounds->bottom;
|
||
|
|
||
|
iOldDc = SaveDC (hdcDraw);
|
||
|
if (0 == iOldDc)
|
||
|
{
|
||
|
return ResultFromScode(E_OUTOFMEMORY);
|
||
|
}
|
||
|
|
||
|
m_nRecord = RECORD_COUNT;
|
||
|
m_fMetaDC = OleIsDcMeta (hdcDraw);
|
||
|
|
||
|
if (!m_fMetaDC) {
|
||
|
iRgn = IntersectClipRect (hdcDraw, lpRrc->left, lpRrc->top,
|
||
|
lpRrc->right, lpRrc->bottom);
|
||
|
Assert( ERROR != iRgn );
|
||
|
|
||
|
if (iRgn == NULLREGION) {
|
||
|
goto errRtn;
|
||
|
}
|
||
|
if (iRgn == ERROR) {
|
||
|
m_error = ResultFromScode(E_UNSPEC);
|
||
|
goto errRtn;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Because the LPToDP conversion takes the current world
|
||
|
// transform into consideration, we must check to see
|
||
|
// if we are in a GM_ADVANCED device context. If so,
|
||
|
// save its state and reset to GM_COMPATIBLE while we
|
||
|
// convert LP to DP (then restore the DC).
|
||
|
|
||
|
if (GM_ADVANCED == GetGraphicsMode(hdcDraw))
|
||
|
{
|
||
|
HDC screendc = GetDC(NULL);
|
||
|
RECT rect = {0, 0, 1000, 1000};
|
||
|
HDC emfdc = CreateEnhMetaFile(screendc, NULL, &rect, NULL);
|
||
|
PlayMetaFile( emfdc, m_hPres);
|
||
|
HENHMETAFILE hemf = CloseEnhMetaFile(emfdc);
|
||
|
PlayEnhMetaFile( hdcDraw, hemf, lpRrc);
|
||
|
DeleteEnhMetaFile( hemf );
|
||
|
|
||
|
goto errRtn;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
LEVERIFY( LPtoDP (hdcDraw, (LPPOINT) lpRrc, 2) );
|
||
|
}
|
||
|
|
||
|
LEVERIFY( 0 != SetMapMode (hdcDraw, MM_ANISOTROPIC) );
|
||
|
LEVERIFY( SetViewportOrg (hdcDraw, lpRrc->left, lpRrc->top) );
|
||
|
LEVERIFY( SetViewportExt (hdcDraw, lpRrc->right - lpRrc->left,
|
||
|
lpRrc->bottom - lpRrc->top) );
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
iOldDc = -1;
|
||
|
|
||
|
if (!lprcWBounds)
|
||
|
{
|
||
|
return ResultFromScode(E_DRAW);
|
||
|
}
|
||
|
|
||
|
m_pMetaInfo = (LPMETAINFO)PrivMemAlloc(sizeof(METAINFO));
|
||
|
if( !m_pMetaInfo )
|
||
|
{
|
||
|
AssertSz(m_pMetaInfo, "Memory allocation failed");
|
||
|
m_error = ResultFromScode(E_OUTOFMEMORY);
|
||
|
goto errRtn;
|
||
|
}
|
||
|
|
||
|
m_pCurMdc = (LPMETADC) (m_pMetaInfo);
|
||
|
|
||
|
m_pMetaInfo->xwo = lprcWBounds->left;
|
||
|
m_pMetaInfo->ywo = lprcWBounds->top;
|
||
|
m_pMetaInfo->xwe = lprcWBounds->right;
|
||
|
m_pMetaInfo->ywe = lprcWBounds->bottom;
|
||
|
|
||
|
m_pMetaInfo->xro = lpRrc->left - lprcWBounds->left;
|
||
|
m_pMetaInfo->yro = lpRrc->top - lprcWBounds->top;
|
||
|
|
||
|
m_pCurMdc->xre = lpRrc->right - lpRrc->left;
|
||
|
m_pCurMdc->yre = lpRrc->bottom - lpRrc->top;
|
||
|
m_pCurMdc->xMwo = 0;
|
||
|
m_pCurMdc->yMwo = 0;
|
||
|
m_pCurMdc->xMwe = 0;
|
||
|
m_pCurMdc->yMwe = 0;
|
||
|
m_pCurMdc->pNext = NULL;
|
||
|
}
|
||
|
|
||
|
m_pfnContinue = pfnContinue;
|
||
|
m_dwContinue = dwContinue;
|
||
|
|
||
|
// m_hPalDCOriginal and m_hPalLast are used to clean up any
|
||
|
// palettes that are selected into a DC during the metafile
|
||
|
// enumeration.
|
||
|
m_hPalDCOriginal = NULL;
|
||
|
m_hPalLast = NULL;
|
||
|
|
||
|
LEVERIFY( EnumMetaFile(hdcDraw, m_hPres, MfCallbackFuncForDraw,
|
||
|
(LPARAM) this) );
|
||
|
|
||
|
if (m_fMetaDC)
|
||
|
{
|
||
|
CleanStack();
|
||
|
|
||
|
}
|
||
|
|
||
|
// if m_hPalLast exists at this point, we have duped a palette
|
||
|
// and it needs to be freed.
|
||
|
if (m_hPalLast)
|
||
|
{
|
||
|
HPALETTE hPalTemp;
|
||
|
|
||
|
// when calling SelectPalette on a Metafile DC, the old
|
||
|
// palette is not returned. We need to select another
|
||
|
// palette into the metafile DC so DeleteObject can be
|
||
|
// called. To do this, we will use the stock palette.
|
||
|
if (m_fMetaDC)
|
||
|
{
|
||
|
hPalTemp = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Get the original palette selected in the DC.
|
||
|
hPalTemp = m_hPalDCOriginal;
|
||
|
}
|
||
|
|
||
|
// hPalTemp could be NULL...
|
||
|
|
||
|
if (hPalTemp)
|
||
|
{
|
||
|
// Should this palette be selected in the foreground?
|
||
|
// [Probably not, this code is well-tested]
|
||
|
SelectPalette(hdcDraw, hPalTemp, TRUE);
|
||
|
}
|
||
|
|
||
|
DeleteObject(m_hPalLast);
|
||
|
}
|
||
|
|
||
|
m_fMetaDC = FALSE;
|
||
|
|
||
|
errRtn:
|
||
|
|
||
|
LEVERIFY( RestoreDC (hdcDraw, iOldDc) );
|
||
|
return m_error;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::GetColorSet
|
||
|
//
|
||
|
// Synopsis: Retrieves the logical palette associated with the metafile
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [pvAspect] -- the drawing aspect
|
||
|
// [hicTargetDev] -- target device
|
||
|
// [ppColorSet] -- where to put the logical palette pointer
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: HRESULT
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation: IOlePresObj
|
||
|
//
|
||
|
// Algorithm: Plays the metafile into a new metafile. The play callback
|
||
|
// function stores the metafile palette which is then returned.
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 29-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
STDMETHODIMP CMfObject::GetColorSet (LPVOID /* UNUSED pvAspect */,
|
||
|
HDC /* UNUSED hicTargetDev */,
|
||
|
LPLOGPALETTE * ppColorSet)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
if (IsBlank() || !M_HPRES())
|
||
|
{
|
||
|
return ResultFromScode(OLE_E_BLANK);
|
||
|
}
|
||
|
|
||
|
m_pColorSet = NULL;
|
||
|
|
||
|
HDC hdcMeta = CreateMetaFile(NULL);
|
||
|
if (NULL == hdcMeta)
|
||
|
{
|
||
|
return ResultFromScode(E_OUTOFMEMORY);
|
||
|
}
|
||
|
|
||
|
m_error = NOERROR;
|
||
|
|
||
|
|
||
|
LEVERIFY( EnumMetaFile(hdcMeta, m_hPres, MfCallbackFuncForGetColorSet,
|
||
|
(LPARAM) this) );
|
||
|
|
||
|
HMETAFILE hMetaFile = CloseMetaFile(hdcMeta);
|
||
|
|
||
|
if( hMetaFile )
|
||
|
{
|
||
|
DeleteMetaFile(hMetaFile);
|
||
|
}
|
||
|
|
||
|
if( m_error != NOERROR )
|
||
|
{
|
||
|
return m_error;
|
||
|
}
|
||
|
|
||
|
if ((*ppColorSet = m_pColorSet) == NULL)
|
||
|
{
|
||
|
return ResultFromScode(S_FALSE);
|
||
|
}
|
||
|
|
||
|
return NOERROR;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: MfCallBackFunForDraw
|
||
|
//
|
||
|
// Synopsis: callback function for drawing metafiles -- call's the caller's
|
||
|
// draw method (via a passed in this pointer)
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [hdc] -- the device context
|
||
|
// [lpHTable] -- pointer to the MF handle table
|
||
|
// [lpMFR] -- pointer to metafile record
|
||
|
// [nObj] -- number of objects
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: non-zero to continue, zero stops the drawing
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 29-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
int CALLBACK __loadds MfCallbackFuncForDraw
|
||
|
(HDC hdc, HANDLETABLE FAR* lpHTable, METARECORD FAR* lpMFR, int nObj,
|
||
|
LPARAM lpobj)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
return ((CMfObject FAR*) lpobj)->CallbackFuncForDraw(hdc, lpHTable,
|
||
|
lpMFR, nObj);
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: MfCallbackFuncForGetColorSet
|
||
|
//
|
||
|
// Synopsis: callback function for grabbing the palette from a metafile
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [hdc] -- the device context
|
||
|
// [lpHTable] -- pointer to the MF handle table
|
||
|
// [lpMFR] -- pointer to metafile record
|
||
|
// [nObj] -- number of objects
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: non-zero to continue, zero stops the drawing
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 29-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
int CALLBACK __loadds MfCallbackFuncForGetColorSet
|
||
|
(HDC hdc, HANDLETABLE FAR* lpHTable, METARECORD FAR* lpMFR, int nObj,
|
||
|
LPARAM lpobj)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
return ((CMfObject FAR*) lpobj)->CallbackFuncForGetColorSet(hdc, lpHTable,
|
||
|
lpMFR, nObj);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::CallbackFuncForGetColorSet
|
||
|
//
|
||
|
// Synopsis: Merges all the color palettes in the metafile into
|
||
|
// one palette (called when GetColorSet enumerates the metafile)
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [hdc] -- the device context
|
||
|
// [lpHTable] -- pointer to the MF handle table
|
||
|
// [lpMFR] -- pointer to metafile record
|
||
|
// [nObj] -- number of objects
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: non-zero to continue, zero stops the drawing
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 29-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
int CMfObject::CallbackFuncForGetColorSet(HDC /* UNUSED hdc */,
|
||
|
LPHANDLETABLE /* UNUSED lpHTable */,
|
||
|
LPMETARECORD lpMFR,
|
||
|
int /* UNUSED nObj */)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
if (lpMFR->rdFunction == META_CREATEPALETTE)
|
||
|
{
|
||
|
LPLOGPALETTE lplogpal = (LPLOGPALETTE) &(lpMFR->rdParm[0]);
|
||
|
UINT uPalSize = (lplogpal->palNumEntries) *
|
||
|
sizeof(PALETTEENTRY)
|
||
|
+ 2 * sizeof(WORD);
|
||
|
|
||
|
if (m_pColorSet == NULL)
|
||
|
{
|
||
|
// This is the first CreatePalette record.
|
||
|
|
||
|
m_pColorSet = (LPLOGPALETTE)PubMemAlloc(uPalSize);
|
||
|
if(NULL == m_pColorSet)
|
||
|
{
|
||
|
m_error = ResultFromScode(E_OUTOFMEMORY);
|
||
|
return FALSE;
|
||
|
}
|
||
|
_xmemcpy(m_pColorSet, lplogpal, (size_t) uPalSize);
|
||
|
}
|
||
|
|
||
|
// if we hit more than one CreatePalette record then, we need to
|
||
|
// merge those palette records.
|
||
|
|
||
|
// REVIEW32:: err, we don't ever seem to do this
|
||
|
// mergeing referred to above :(
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::CallbackFuncForDraw
|
||
|
//
|
||
|
// Synopsis: Draws the metafile
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [hdc] -- the device context
|
||
|
// [lpHTable] -- pointer to the MF handle table
|
||
|
// [lpMFR] -- pointer to metafile record
|
||
|
// [nObj] -- number of objects
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: non-zero to continue, zero stops the drawing
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 17-Dec-93 ChrisWe fixed second argument to SelectPalette calls
|
||
|
// 29-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
int CMfObject::CallbackFuncForDraw
|
||
|
(HDC hdc, LPHANDLETABLE lpHTable, LPMETARECORD lpMFR, int nObj)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
|
||
|
if (!--m_nRecord)
|
||
|
{
|
||
|
m_nRecord = RECORD_COUNT;
|
||
|
|
||
|
if (m_pfnContinue && !((*(m_pfnContinue))(m_dwContinue)))
|
||
|
{
|
||
|
m_error = ResultFromScode(E_ABORT);
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (m_fMetaDC)
|
||
|
{
|
||
|
switch (lpMFR->rdFunction)
|
||
|
{
|
||
|
case META_SETWINDOWORG:
|
||
|
SetPictOrg (hdc, (SHORT)lpMFR->rdParm[1], (SHORT)lpMFR->rdParm[0],
|
||
|
FALSE);
|
||
|
return TRUE;
|
||
|
|
||
|
case META_OFFSETWINDOWORG:
|
||
|
SetPictOrg (hdc, (SHORT)lpMFR->rdParm[1], (SHORT)lpMFR->rdParm[0],
|
||
|
TRUE);
|
||
|
return TRUE;
|
||
|
|
||
|
case META_SETWINDOWEXT:
|
||
|
SetPictExt (hdc, (SHORT)lpMFR->rdParm[1], (SHORT)lpMFR->rdParm[0]);
|
||
|
return TRUE;
|
||
|
|
||
|
case META_SCALEWINDOWEXT:
|
||
|
ScalePictExt (hdc, (SHORT)lpMFR->rdParm[3], (SHORT)lpMFR->rdParm[2],
|
||
|
(SHORT)lpMFR->rdParm[1], (SHORT)lpMFR->rdParm[0]);
|
||
|
return TRUE;
|
||
|
|
||
|
case META_SCALEVIEWPORTEXT:
|
||
|
ScaleRectExt (hdc, (SHORT)lpMFR->rdParm[3], (SHORT)lpMFR->rdParm[2],
|
||
|
(SHORT)lpMFR->rdParm[1], (SHORT)lpMFR->rdParm[0]);
|
||
|
return TRUE;
|
||
|
|
||
|
case META_SAVEDC:
|
||
|
{
|
||
|
BOOL fSucceeded = PushDc();
|
||
|
LEVERIFY( fSucceeded );
|
||
|
if (!fSucceeded)
|
||
|
return FALSE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case META_RESTOREDC:
|
||
|
LEVERIFY( PopDc() );
|
||
|
break;
|
||
|
|
||
|
case META_SELECTPALETTE:
|
||
|
{
|
||
|
// All selectpalette records are recorded such that the
|
||
|
// palette is rendered in foreground mode. Rather than
|
||
|
// allowing the record to play out in this fashion, we
|
||
|
// grab the handle and select it ourselves, forcing it
|
||
|
// to background (using colors already mapped in the DC)
|
||
|
|
||
|
// Dupe the palette.
|
||
|
HPALETTE hPal = UtDupPalette((HPALETTE) lpHTable->objectHandle[lpMFR->rdParm[0]]);
|
||
|
|
||
|
// Select the dupe into the DC. EnumMetaFile calls DeleteObject
|
||
|
// on the palette handle in the metafile handle table. If that
|
||
|
// palette is currently selected into a DC, we rip and leak the
|
||
|
// resource.
|
||
|
LEVERIFY( NULL != SelectPalette(hdc, hPal, TRUE) );
|
||
|
|
||
|
// if we had previously saved a palette, we need to delete
|
||
|
// it (for the case of multiple SelectPalette calls in a
|
||
|
// MetaFile).
|
||
|
if (m_hPalLast)
|
||
|
{
|
||
|
DeleteObject(m_hPalLast);
|
||
|
}
|
||
|
|
||
|
// remember our duped palette so that it can be properly destroyed
|
||
|
// later.
|
||
|
m_hPalLast = hPal;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
case META_OFFSETVIEWPORTORG:
|
||
|
AssertSz(0, "OffsetViewportOrg() in metafile");
|
||
|
return TRUE;
|
||
|
|
||
|
case META_SETVIEWPORTORG:
|
||
|
AssertSz(0, "SetViewportOrg() in metafile");
|
||
|
return TRUE;
|
||
|
|
||
|
case META_SETVIEWPORTEXT:
|
||
|
AssertSz(0, "SetViewportExt() in metafile");
|
||
|
return TRUE;
|
||
|
|
||
|
case META_SETMAPMODE:
|
||
|
AssertSz(lpMFR->rdParm[0] == MM_ANISOTROPIC,
|
||
|
"SetmapMode() in metafile with invalid mapping mode");
|
||
|
return TRUE;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{ // non-metafile DC. (ScreenDC or other DC...)
|
||
|
|
||
|
if (lpMFR->rdFunction == META_SELECTPALETTE)
|
||
|
{
|
||
|
// All selectpalette records are recorded such that the
|
||
|
// palette is rendered in foreground mode. Rather than
|
||
|
// allowing the record to play out in this fashion, we
|
||
|
// grab the handle and select it ourselves, forcing it
|
||
|
// to background (using colors already mapped in the DC)
|
||
|
|
||
|
|
||
|
HPALETTE hPal = UtDupPalette((HPALETTE) lpHTable->objectHandle[lpMFR->rdParm[0]]);
|
||
|
|
||
|
HPALETTE hPalOld = SelectPalette(hdc, hPal, TRUE);
|
||
|
|
||
|
if (!m_hPalDCOriginal)
|
||
|
{
|
||
|
m_hPalDCOriginal = hPalOld;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// This case gets hit if we have already stored
|
||
|
// the original palette from the DC. This means
|
||
|
// that hPalOld is a palette we have created using
|
||
|
// UtDupPal above. This means we need to delete
|
||
|
// the old palette and remember the new one.
|
||
|
|
||
|
if(hPalOld)
|
||
|
DeleteObject(hPalOld);
|
||
|
}
|
||
|
|
||
|
m_hPalLast = hPal;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LEVERIFY( PlayMetaFileRecord (hdc, lpHTable, lpMFR, (unsigned) nObj) );
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::SetPictOrg (private)
|
||
|
//
|
||
|
// Synopsis: Sets the hdc's origin via SetWindowOrg
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [hdc] -- the device context
|
||
|
// [xOrg] -- the x origin
|
||
|
// [yOrg] -- the y origin
|
||
|
// [fOffset] -- if TRUE, [xOrg] and [yOrg] are offsets
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: HRESULT
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 29-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes: used by the metafile interpreter
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
INTERNAL_(void) CMfObject::SetPictOrg
|
||
|
(HDC hdc, int xOrg, int yOrg, BOOL fOffset)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
if (fOffset)
|
||
|
{
|
||
|
|
||
|
m_pCurMdc->xMwo += xOrg;
|
||
|
m_pCurMdc->yMwo += yOrg;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_pCurMdc->xMwo = xOrg;
|
||
|
m_pCurMdc->yMwo = yOrg;
|
||
|
}
|
||
|
|
||
|
if (m_pCurMdc->xMwe && m_pCurMdc->yMwe)
|
||
|
{
|
||
|
LEVERIFY ( SetWindowOrg (hdc, // Review (davepl) MEIN GOT!
|
||
|
(m_pCurMdc->xMwo -
|
||
|
MulDiv (m_pMetaInfo->xro, m_pCurMdc->xMwe,
|
||
|
m_pCurMdc->xre)),
|
||
|
(m_pCurMdc->yMwo -
|
||
|
MulDiv (m_pMetaInfo->yro, m_pCurMdc->yMwe,
|
||
|
m_pCurMdc->yre))) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::SetPictExt
|
||
|
//
|
||
|
// Synopsis: Sets teh metafile's extents
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [hdc] -- the device context
|
||
|
// [xExt] -- the X-extent
|
||
|
// [yExt] -- the Y-extent
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: void
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 30-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes: used by the metafile interpreter
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
INTERNAL_(void) CMfObject::SetPictExt (HDC hdc, int xExt, int yExt)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
m_pCurMdc->xMwe = xExt;
|
||
|
m_pCurMdc->yMwe = yExt;
|
||
|
|
||
|
// Assert( m_pCurMdc->xre && m_pCurMdc->yre );
|
||
|
|
||
|
int xNewExt = MulDiv (m_pMetaInfo->xwe, xExt, m_pCurMdc->xre);
|
||
|
int yNewExt = MulDiv (m_pMetaInfo->ywe, yExt, m_pCurMdc->yre);
|
||
|
|
||
|
int xNewOrg = m_pCurMdc->xMwo
|
||
|
- MulDiv (m_pMetaInfo->xro, xExt, m_pCurMdc->xre);
|
||
|
int yNewOrg = m_pCurMdc->yMwo
|
||
|
- MulDiv (m_pMetaInfo->yro, yExt, m_pCurMdc->yre);
|
||
|
|
||
|
LEVERIFY( SetWindowExt (hdc, xNewExt, yNewExt) );
|
||
|
LEVERIFY( SetWindowOrg (hdc, xNewOrg, yNewOrg) );
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::ScalePictExt
|
||
|
//
|
||
|
// Synopsis: Scales the metafile
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [hdc] -- the device context
|
||
|
// [xNum] -- the x numerator
|
||
|
// [xDenom] -- the x demominator
|
||
|
// [yNum] -- the y numberator
|
||
|
// [yDenom] -- the y demoninator
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: void
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 30-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes: used by the metafile interpreter
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
INTERNAL_(void) CMfObject::ScalePictExt (HDC hdc,
|
||
|
int xNum,
|
||
|
int xDenom,
|
||
|
int yNum,
|
||
|
int yDenom)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
Assert( xDenom && yDenom );
|
||
|
|
||
|
int xNewExt = MulDiv (m_pCurMdc->xMwe, xNum, xDenom);
|
||
|
int yNewExt = MulDiv (m_pCurMdc->yMwe, yNum, yDenom);
|
||
|
|
||
|
SetPictExt(hdc, xNewExt, yNewExt);
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::ScaleRectExt
|
||
|
//
|
||
|
// Synopsis: scales the viewport
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [hdc] -- the device context
|
||
|
// [xNum] -- the x numerator
|
||
|
// [xDenom] -- the x demominator
|
||
|
// [yNum] -- the y numberator
|
||
|
// [yDenom] -- the y demoninator
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: void
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 30-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes: Used by the metafile interpreter
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
INTERNAL_(void) CMfObject::ScaleRectExt(HDC hdc,
|
||
|
int xNum,
|
||
|
int xDenom,
|
||
|
int yNum,
|
||
|
int yDenom)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
AssertSz( xDenom, "Denominator is 0 for x-rect scaling");
|
||
|
AssertSz( yDenom, "Denominator is 0 for y-rect scaling");
|
||
|
|
||
|
m_pCurMdc->xre = MulDiv (m_pCurMdc->xre, xNum, xDenom);
|
||
|
m_pCurMdc->yre = MulDiv (m_pCurMdc->yre, yNum, yDenom);
|
||
|
|
||
|
SetPictExt (hdc, m_pCurMdc->xMwe, m_pCurMdc->yMwe);
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::PushDC
|
||
|
//
|
||
|
// Synopsis: pushes metafile info onto a stack
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: void
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: BOOL -- TRUE if successful, FALSE otherwise
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 30-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes: Used by the metafile interpreter engine.
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
INTERNAL_(BOOL) CMfObject::PushDc (void)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
LPMETADC pNode = NULL;
|
||
|
|
||
|
pNode = (LPMETADC) PrivMemAlloc(sizeof(METADC));
|
||
|
|
||
|
if (pNode)
|
||
|
{
|
||
|
*pNode = *m_pCurMdc;
|
||
|
m_pCurMdc->pNext = pNode;
|
||
|
pNode->pNext = NULL;
|
||
|
m_pCurMdc = pNode;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
m_error = ResultFromScode(E_OUTOFMEMORY);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::PopDC
|
||
|
//
|
||
|
// Synopsis: pops metafile info from the metafile info stack
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: void
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: BOOL -- TRUE if successful, FALSE otherwise (more pops
|
||
|
// than pushes)
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 30-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes: used in the metafile interpreter
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
INTERNAL_(BOOL) CMfObject::PopDc (void)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
LPMETADC pPrev = (LPMETADC) (m_pMetaInfo);
|
||
|
LPMETADC pCur = ((LPMETADC) (m_pMetaInfo))->pNext;
|
||
|
|
||
|
if (NULL == pCur)
|
||
|
{
|
||
|
LEWARN( NULL == pCur, "More pops than pushes from DC stack" );
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
while (pCur->pNext)
|
||
|
{
|
||
|
pPrev = pCur;
|
||
|
pCur = pCur->pNext;
|
||
|
}
|
||
|
|
||
|
if (pCur)
|
||
|
{
|
||
|
PrivMemFree(pCur);
|
||
|
}
|
||
|
|
||
|
pPrev->pNext = NULL;
|
||
|
m_pCurMdc = pPrev;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::CleanStack
|
||
|
//
|
||
|
// Synopsis: Deletes the stack of metafile info
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: void
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: void
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 30-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes: used in the metafile interpreter
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
INTERNAL_(void) CMfObject::CleanStack (void)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
LPMETADC pCur;
|
||
|
|
||
|
while (NULL != (pCur = ((LPMETADC) (m_pMetaInfo))->pNext))
|
||
|
{
|
||
|
((LPMETADC) (m_pMetaInfo))->pNext = pCur->pNext;
|
||
|
PrivMemFree(pCur);
|
||
|
}
|
||
|
|
||
|
PrivMemFree(m_pMetaInfo);
|
||
|
|
||
|
m_pCurMdc = NULL;
|
||
|
m_pMetaInfo = NULL;
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: QD2GDI
|
||
|
//
|
||
|
// Synopsis: Converts macintosh pictures to Win32 GDI metafiles
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [hBits] -- handle to the mac picture bits
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: HMETAFILE
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Algorithm: Loads ole2conv.dll and calls QD2GDI in that dll
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 30-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
FARINTERNAL_(HMETAFILE) QD2GDI (HANDLE hBits)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
USERPREFS userPrefs =
|
||
|
{
|
||
|
{'Q','D','2','G','D','I'}, //signature
|
||
|
2, //structure version number
|
||
|
sizeof(USERPREFS), //structure size
|
||
|
NULL, //source filename
|
||
|
NULL, //or source handle
|
||
|
NULL, //returned memory-based
|
||
|
//metafile
|
||
|
3, //simulated pattern lines
|
||
|
5, //use max dimension
|
||
|
//non-squarer pen
|
||
|
1, //arithmetic transfer
|
||
|
1, //create opaque text
|
||
|
1, //simulate non-rectangular
|
||
|
//regions
|
||
|
0, //don't optimize for PowerPoint
|
||
|
{0,0,0,0,0,0} //reserved
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
HINSTANCE hinstFilter;
|
||
|
void (FAR PASCAL *qd2gdiPtr)( USERPREFS FAR *, PICTINFO FAR *);
|
||
|
PICTINFO pictinfo;
|
||
|
|
||
|
hinstFilter = LoadLibrary(OLESTR("OLECNV32.DLL"));
|
||
|
|
||
|
#if 0
|
||
|
//REVIEW:CHICAGO
|
||
|
|
||
|
//HINSTANCE_ERROR not defined in chicago
|
||
|
|
||
|
if (hinstFilter < (HINSTANCE)HINSTANCE_ERROR)
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (hinstFilter == NULL)
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
*((FARPROC*)&qd2gdiPtr) = GetProcAddress(hinstFilter, "QD2GDI");
|
||
|
|
||
|
userPrefs.sourceFilename = NULL;
|
||
|
userPrefs.sourceHandle = hBits;
|
||
|
pictinfo.hmf = NULL;
|
||
|
|
||
|
if (qd2gdiPtr == NULL)
|
||
|
{
|
||
|
goto errRtn;
|
||
|
}
|
||
|
|
||
|
(*qd2gdiPtr)( (USERPREFS FAR *)&userPrefs, (PICTINFO FAR *)&pictinfo);
|
||
|
|
||
|
errRtn:
|
||
|
LEVERIFY( FreeLibrary(hinstFilter) );
|
||
|
return (HMETAFILE)pictinfo.hmf;
|
||
|
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: MfGetSize
|
||
|
//
|
||
|
// Synopsis: Returns the size of a metafile
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [lphmf] -- pointer to the metafile handle
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: DWORD -- the size of the metafile
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 30-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
INTERNAL_(DWORD) MfGetSize (LPHANDLE lphmf)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
return GetMetaFileBitsEx((HMETAFILE)*lphmf,0,NULL);
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: OleIsDcMeta
|
||
|
//
|
||
|
// Synopsis: Returns whether a device context is really a metafile
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [hdc] -- the device context
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: BOOL (TRUE if a metafile)
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 30-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
STDAPI_(BOOL) OleIsDcMeta (HDC hdc)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
return (GetDeviceCaps (hdc, TECHNOLOGY) == DT_METAFILE);
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::Load
|
||
|
//
|
||
|
// Synopsis: Loads an metafile object from the given stream
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [lpstream] -- the stream from which to load
|
||
|
// [fReadHeaderOnly] -- if TRUE, then only the header is
|
||
|
// read
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: HRESULT
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation: IOlePresObj
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 30-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP CMfObject::Load(LPSTREAM lpstream, BOOL fReadHeaderOnly)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
DWORD dwBuf[4];
|
||
|
HRESULT error;
|
||
|
|
||
|
/* read dwCompression, width, height, size of data */
|
||
|
error = StRead(lpstream, dwBuf, 4*sizeof(DWORD));
|
||
|
if (error)
|
||
|
{
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
AssertSz (dwBuf[0] == 0, "Picture compression factor is non-zero");
|
||
|
|
||
|
m_lWidth = (LONG) dwBuf[1];
|
||
|
m_lHeight = (LONG) dwBuf[2];
|
||
|
m_dwSize = dwBuf[3];
|
||
|
|
||
|
if (!m_dwSize || fReadHeaderOnly)
|
||
|
{
|
||
|
return NOERROR;
|
||
|
}
|
||
|
|
||
|
return UtGetHMFFromMFStm(lpstream, m_dwSize, m_fConvert,
|
||
|
(LPLPVOID) &m_hPres);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::Save
|
||
|
//
|
||
|
// Synopsis: Saves the metafile to the given stream
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [lpstream] -- the stream to save to
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: HRESULT
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation: IOlePresObj
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 30-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP CMfObject::Save(LPSTREAM lpstream)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
HRESULT error;
|
||
|
DWORD dwBuf[4];
|
||
|
|
||
|
/* write dwCompression, width, height, size of data */
|
||
|
|
||
|
dwBuf[0] = 0L;
|
||
|
dwBuf[1] = (DWORD) m_lWidth;
|
||
|
dwBuf[2] = (DWORD) m_lHeight;
|
||
|
dwBuf[3] = m_dwSize;
|
||
|
|
||
|
error = StWrite(lpstream, dwBuf, sizeof(dwBuf));
|
||
|
if (error)
|
||
|
{
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
|
||
|
// if blank object, don't write any more; no error.
|
||
|
if (IsBlank() || m_hPres == NULL)
|
||
|
{
|
||
|
StSetSize(lpstream, 0, TRUE);
|
||
|
return NOERROR;
|
||
|
}
|
||
|
|
||
|
return UtHMFToMFStm((LPLPVOID)&m_hPres, m_dwSize, lpstream);
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::GetExtent
|
||
|
//
|
||
|
// Synopsis: Retrieves the extents of the metafile
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [dwDrawAspect] -- the drawing aspect we're interested in
|
||
|
// (must match the aspect of the current
|
||
|
// metafile)
|
||
|
// [lpsizel] -- where to put the extent info
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: NOERROR, DV_E_DVASPECT, OLE_E_BLANK
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation: IOlePresObj
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 30-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP CMfObject::GetExtent(DWORD dwDrawAspect, LPSIZEL lpsizel)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
if (0 == (dwDrawAspect & m_dwAspect))
|
||
|
{
|
||
|
return ResultFromScode(DV_E_DVASPECT);
|
||
|
}
|
||
|
|
||
|
if (IsBlank())
|
||
|
{
|
||
|
return ResultFromScode(OLE_E_BLANK);
|
||
|
}
|
||
|
|
||
|
lpsizel->cx = m_lWidth;
|
||
|
lpsizel->cy = m_lHeight;
|
||
|
return NOERROR;
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::IsBlank
|
||
|
//
|
||
|
// Synopsis: Returns whether or not the metafile is blank
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: void
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: TRUE/FALSE
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation: IOlePresObj
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 30-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP_(BOOL) CMfObject::IsBlank(void)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
return (m_dwSize ? FALSE : TRUE);
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::LoadHPRES (private)
|
||
|
//
|
||
|
// Synopsis: Loads the presentation from the cache's stream and returns
|
||
|
// a handle to it
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: void
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: HANDLE to the metafile
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 30-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
INTERNAL_(HANDLE) CMfObject::LoadHPRES(void)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
LPSTREAM pstm;
|
||
|
|
||
|
pstm = m_pCacheNode->GetStm(TRUE /*fSeekToPresBits*/, STGM_READ);
|
||
|
if (pstm)
|
||
|
{
|
||
|
LEVERIFY( SUCCEEDED(Load(pstm)));
|
||
|
pstm->Release();
|
||
|
}
|
||
|
|
||
|
return m_hPres;
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::DiscardHPRES
|
||
|
//
|
||
|
// Synopsis: deletes the stored metafile
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: void
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: void
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation: IOlePresObj
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 30-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP_(void) CMfObject::DiscardHPRES(void)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
if (m_hPres)
|
||
|
{
|
||
|
LEVERIFY( DeleteMetaFile (m_hPres) );
|
||
|
m_hPres = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::GetCopyOfHPRES (private)
|
||
|
//
|
||
|
// Synopsis: makes a copy of the metafile (if one is present), otherwise
|
||
|
// just load it from the stream (but don't store it in [this]
|
||
|
// object)
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: void
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: HANDLE to the metafile
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Derivation:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 30-Nov-93 alexgo 32bit port
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
INTERNAL_(HANDLE) CMfObject::GetCopyOfHPRES(void)
|
||
|
{
|
||
|
VDATEHEAP();
|
||
|
|
||
|
HANDLE hPres;
|
||
|
|
||
|
// Make a copy if the presentation data is already loaded
|
||
|
if (m_hPres)
|
||
|
{
|
||
|
return CopyMetaFile(m_hPres, NULL);
|
||
|
}
|
||
|
|
||
|
// Load the presentation data now and return the same handle.
|
||
|
// No need to copy the data. If the caller wants the m_hPres to be
|
||
|
// set he would call LoadHPRES() directly.
|
||
|
|
||
|
hPres = LoadHPRES();
|
||
|
m_hPres = NULL; // NULL this, LoadHPRES set it.
|
||
|
return hPres;
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CMfObject::Dump, public (_DEBUG only)
|
||
|
//
|
||
|
// Synopsis: return a string containing the contents of the data members
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [ppszDump] - an out pointer to a null terminated character array
|
||
|
// [ulFlag] - flag determining prefix of all newlines of the
|
||
|
// out character array (default is 0 - no prefix)
|
||
|
// [nIndentLevel] - will add a indent prefix after the other prefix
|
||
|
// for ALL newlines (including those with no prefix)
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: HRESULT
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies: [ppszDump] - argument
|
||
|
//
|
||
|
// Derivation:
|
||
|
//
|
||
|
// Algorithm: use dbgstream to create a string containing information on the
|
||
|
// content of data structures
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 01-Feb-95 t-ScottH author
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
|
||
|
HRESULT CMfObject::Dump(char **ppszDump, ULONG ulFlag, int nIndentLevel)
|
||
|
{
|
||
|
int i;
|
||
|
char *pszPrefix;
|
||
|
char *pszHRESULT;
|
||
|
char *pszDVASPECT;
|
||
|
dbgstream dstrPrefix;
|
||
|
dbgstream dstrDump(500);
|
||
|
|
||
|
// determine prefix of newlines
|
||
|
if ( ulFlag & DEB_VERBOSE )
|
||
|
{
|
||
|
dstrPrefix << this << " _VB ";
|
||
|
}
|
||
|
|
||
|
// determine indentation prefix for all newlines
|
||
|
for (i = 0; i < nIndentLevel; i++)
|
||
|
{
|
||
|
dstrPrefix << DUMPTAB;
|
||
|
}
|
||
|
|
||
|
pszPrefix = dstrPrefix.str();
|
||
|
|
||
|
// put data members in stream
|
||
|
dstrDump << pszPrefix << "No. of References = " << m_ulRefs << endl;
|
||
|
|
||
|
dstrDump << pszPrefix << "pMETAINFO (Metafile information) = " << m_pMetaInfo << endl;
|
||
|
|
||
|
dstrDump << pszPrefix << "pMETADC (current device context) = " << m_pCurMdc << endl;
|
||
|
|
||
|
dstrDump << pszPrefix << "IsMetaDeviceContext? = ";
|
||
|
if (m_fMetaDC == TRUE)
|
||
|
{
|
||
|
dstrDump << "TRUE" << endl;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dstrDump << "FALSE" << endl;
|
||
|
}
|
||
|
|
||
|
dstrDump << pszPrefix << "No. of Records in Metafile = " << m_nRecord << endl;
|
||
|
|
||
|
pszHRESULT = DumpHRESULT(m_error);
|
||
|
dstrDump << pszPrefix << "Error code = " << pszHRESULT << endl;
|
||
|
CoTaskMemFree(pszHRESULT);
|
||
|
|
||
|
dstrDump << pszPrefix << "pLOGPALETTE (Color set palette) = " << m_pColorSet << endl;
|
||
|
|
||
|
dstrDump << pszPrefix << "ConvertFromMac? = ";
|
||
|
if (m_fConvert == TRUE)
|
||
|
{
|
||
|
dstrDump << "TRUE" << endl;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dstrDump << "FALSE" << endl;
|
||
|
}
|
||
|
|
||
|
dstrDump << pszPrefix << "Continue = " << ((ULONG) m_dwContinue) << endl;
|
||
|
|
||
|
dstrDump << pszPrefix << "fp Continue = " << m_pfnContinue<< endl;
|
||
|
|
||
|
pszDVASPECT = DumpDVASPECTFlags(m_dwAspect);
|
||
|
dstrDump << pszPrefix << "Aspect flags = " << pszDVASPECT << endl;
|
||
|
CoTaskMemFree(pszDVASPECT);
|
||
|
|
||
|
dstrDump << pszPrefix << "Size = " << m_dwSize << endl;
|
||
|
|
||
|
dstrDump << pszPrefix << "Width = " << m_lWidth << endl;
|
||
|
|
||
|
dstrDump << pszPrefix << "Height = " << m_lHeight << endl;
|
||
|
|
||
|
dstrDump << pszPrefix << "pCacheNode = " << m_pCacheNode << endl;
|
||
|
|
||
|
// cleanup and provide pointer to character array
|
||
|
*ppszDump = dstrDump.str();
|
||
|
|
||
|
if (*ppszDump == NULL)
|
||
|
{
|
||
|
*ppszDump = UtDupStringA(szDumpErrorMessage);
|
||
|
}
|
||
|
|
||
|
CoTaskMemFree(pszPrefix);
|
||
|
|
||
|
return NOERROR;
|
||
|
}
|
||
|
|
||
|
#endif // _DEBUG
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: DumpCMfObject, public (_DEBUG only)
|
||
|
//
|
||
|
// Synopsis: calls the CMfObject::Dump method, takes care of errors and
|
||
|
// returns the zero terminated string
|
||
|
//
|
||
|
// Effects:
|
||
|
//
|
||
|
// Arguments: [pMFO] - pointer to CMfObject
|
||
|
// [ulFlag] - flag determining prefix of all newlines of the
|
||
|
// out character array (default is 0 - no prefix)
|
||
|
// [nIndentLevel] - will add a indent prefix after the other prefix
|
||
|
// for ALL newlines (including those with no prefix)
|
||
|
//
|
||
|
// Requires:
|
||
|
//
|
||
|
// Returns: character array of structure dump or error (null terminated)
|
||
|
//
|
||
|
// Signals:
|
||
|
//
|
||
|
// Modifies:
|
||
|
//
|
||
|
// Algorithm:
|
||
|
//
|
||
|
// History: dd-mmm-yy Author Comment
|
||
|
// 01-Feb-95 t-ScottH author
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
|
||
|
char *DumpCMfObject(CMfObject *pMFO, ULONG ulFlag, int nIndentLevel)
|
||
|
{
|
||
|
HRESULT hresult;
|
||
|
char *pszDump;
|
||
|
|
||
|
if (pMFO == NULL)
|
||
|
{
|
||
|
return UtDupStringA(szDumpBadPtr);
|
||
|
}
|
||
|
|
||
|
hresult = pMFO->Dump(&pszDump, ulFlag, nIndentLevel);
|
||
|
|
||
|
if (hresult != NOERROR)
|
||
|
{
|
||
|
CoTaskMemFree(pszDump);
|
||
|
|
||
|
return DumpHRESULT(hresult);
|
||
|
}
|
||
|
|
||
|
return pszDump;
|
||
|
}
|
||
|
|
||
|
#endif // _DEBUG
|
||
|
|