|
|
//+----------------------------------------------------------------------------
//
// File:
// ole2util.cpp
//
// Contents:
// Ole internal utility routines
//
// Classes:
//
// Functions:
//
// History:
// 06/01/94 - AlexGo - UtQueryPictFormat now supports
// enhanced metafiles
// 03/18/94 - AlexGo - fixed UtGetPresStreamName (incorrect
// string processing)
// 01/11/94 - ChrisWe - don't reference unlocked handle in
// UtConvertBitmapToDib
// 01/11/94 - alexgo - added VDATEHEAP macro to every function
// 12/07/93 - ChrisWe - removed incorrect uses of (LPOLESTR);
// removed duplicate GetClassFromDataObj function, which
// is the same as UtGetClassID
// 11/30/93 - ChrisWe - continue file cleanup; don't open
// streams in UtRemoveExtraOlePresStreams()
// 11/28/93 - ChrisWe - file cleanup and inspection;
// reformatted many functions
// 11/22/93 - ChrisWe - replace overloaded ==, != with
// IsEqualIID and IsEqualCLSID
// 06/28/93 - SriniK - added UtGetDibExtents
// 11/16/92 - JasonFul - created; moved contents here from util.cpp
//
//-----------------------------------------------------------------------------
#include <le2int.h>
#pragma SEG(ole2util)
NAME_SEG(Ole2Utils) ASSERTDATA
#define WIDTHBYTES(i) ((i+31)/32*4)
#define PALETTESIZE 256 /* Number of entries in the system palette */
// REVIEW, according to the spec, IDataObject::EnumFormatEtc() is only
// required to service one dwDirection DATADIR_ value at a time. This
// function has been asking it to do more than one at a time, and expecting
// return of FORMATETCs that match all the requested directions. Code
// seen in OleRegEnumFormatEtc() checks on creation, and fails if any
// value other than plain DATADIR_GET or plain DATADIR_SET is specified
// so this has clearly never worked for OLE1, or registration database lookups
// since the only caller of UtIsFormatSupported has always asked for both
// at the same time.
#pragma SEG(UtIsFormatSupported)
FARINTERNAL_(BOOL) UtIsFormatSupported(IDataObject FAR* lpDataObj, DWORD dwDirection, CLIPFORMAT cfFormat) { VDATEHEAP();
FORMATETC formatetc; // a place to fetch formats from the enumerator
IEnumFORMATETC FAR* penm; // enumerates the formats of [lpDataObj]
ULONG ulNumFetched; // a count of the number of formats fetched
HRESULT error; // the error state so far
// try to get the enumerator from the data object
error = lpDataObj->EnumFormatEtc(dwDirection, &penm);
if (error != NOERROR) { if (FAILED(error)) return FALSE; else { CLSID clsid;
// Use reg db; this case is primarily for the OLE1
// compatibility code since it may talk to a data
// object from a server in the same process as
// the server.
if (UtGetClassID(lpDataObj, &clsid) != TRUE) return(FALSE);
// synthesize an enumerator
// REVIEW, if the data object is synthesized for
// the OLE1 object, why doesn't that implementation
// go ahead and synthesize this? Why does it have
// to be done like this? What if it's on the clipboard
// and someone wants to use it?
if (OleRegEnumFormatEtc(clsid, dwDirection, &penm) != NOERROR) return FALSE; Assert(penm); } }
// check for the format we're looking for
while(NOERROR == (error = penm->Next(1, &formatetc, &ulNumFetched))) { if ((ulNumFetched == 1) && (formatetc.cfFormat == cfFormat)) break; } // release the enumerator
penm->Release();
// if error isn't S_FALSE, we fetched an item, and broke out of the
// while loop above --> the format was found. Return TRUE indicating
// that the format is supported
return(error == NOERROR ? TRUE : FALSE); }
#pragma SEG(UtDupPalette)
FARINTERNAL_(HPALETTE) UtDupPalette(HPALETTE hpalette) { VDATEHEAP();
WORD cEntries; // holds the number of entries in the palette
HANDLE hLogPal; // ia a handle to a new logical palette
LPLOGPALETTE pLogPal; // is a pointer to the new logical palette
HPALETTE hpaletteNew = NULL; // the new palette we will return
if (0 == GetObject(hpalette, sizeof(cEntries), &cEntries)) return(NULL);
if (NULL == (hLogPal = GlobalAlloc(GMEM_MOVEABLE, sizeof (LOGPALETTE) + cEntries * sizeof (PALETTEENTRY)))) return(NULL);
if (NULL == (pLogPal = (LPLOGPALETTE)GlobalLock(hLogPal))) goto errRtn; if (0 == GetPaletteEntries(hpalette, 0, cEntries, pLogPal->palPalEntry)) goto errRtn;
pLogPal->palVersion = 0x300; pLogPal->palNumEntries = cEntries;
if (NULL == (hpaletteNew = CreatePalette(pLogPal))) goto errRtn;
errRtn: if (pLogPal) GlobalUnlock(hLogPal);
if (hLogPal) GlobalFree(hLogPal);
AssertSz(hpaletteNew, "Warning: UtDupPalette Failed"); return(hpaletteNew); } //+-------------------------------------------------------------------------
//
// Function: UtFormatToTymed
//
// Synopsis: gets the right TYMED for the given rendering format
//
// Effects:
//
// Arguments: [cf] -- the clipboard format
//
// Requires:
//
// Returns: one of the TYMED enumeration
//
// Signals:
//
// Modifies:
//
// Algorithm:
//
// History: dd-mmm-yy Author Comment
// 07-Jul-94 alexgo added EMF's
//
// Notes: This should only be called for formats that we can
// render
//
//--------------------------------------------------------------------------
#pragma SEG(UtFormatToTymed)
FARINTERNAL_(DWORD) UtFormatToTymed(CLIPFORMAT cf) { VDATEHEAP();
if( cf == CF_METAFILEPICT ) { return TYMED_MFPICT; } else if( cf == CF_BITMAP ) { return TYMED_GDI; } else if( cf == CF_DIB ) { return TYMED_HGLOBAL; } else if( cf == CF_ENHMETAFILE ) { return TYMED_ENHMF; } else if( cf == CF_PALETTE ) { LEWARN(1,"Trying to render CF_PALETTE"); return TYMED_GDI; }
LEDebugOut((DEB_WARN, "WARNING: trying to render clipformat (%lx)\n", cf));
return TYMED_HGLOBAL; }
//+-------------------------------------------------------------------------
//
// Function: UtQueryPictFormat
//
// Synopsis: finds our "preferred" drawing formatetc from the given
// data object
//
// Effects:
//
// Arguments: [lpSrcDataObj] -- the source data object
// [lpforetc] -- where to stuff the preferred format
//
// Requires:
//
// Returns:
//
// Signals:
//
// Modifies:
//
// Algorithm:
//
// History: dd-mmm-yy Author Comment
// 01-Jun-94 alexgo rewrite/now supports Enhanced Metafiles
//
// Notes:
//
//--------------------------------------------------------------------------
#pragma SEG(UtQueryPictFormat)
FARINTERNAL_(BOOL) UtQueryPictFormat(LPDATAOBJECT lpSrcDataObj, LPFORMATETC lpforetc) { FORMATETC foretctemp; // local copy of current values of format desc
VDATEHEAP();
LEDebugOut((DEB_ITRACE, "%p _IN UtQueryPictFormat ( %p , %p )\n", NULL, lpSrcDataObj, lpforetc));
// copy format descriptor
foretctemp = *lpforetc;
// set values and query for our preferred formats in order of
// preference
foretctemp.cfFormat = CF_METAFILEPICT; foretctemp.tymed = TYMED_MFPICT; if (lpSrcDataObj->QueryGetData(&foretctemp) == NOERROR) { goto QuerySuccess; }
foretctemp.cfFormat = CF_ENHMETAFILE; foretctemp.tymed = TYMED_ENHMF; if( lpSrcDataObj->QueryGetData(&foretctemp) == NOERROR ) { goto QuerySuccess; } foretctemp.cfFormat = CF_DIB; foretctemp.tymed = TYMED_HGLOBAL; if (lpSrcDataObj->QueryGetData(&foretctemp) == NOERROR) { goto QuerySuccess; } foretctemp.cfFormat = CF_BITMAP; foretctemp.tymed = TYMED_GDI; if (lpSrcDataObj->QueryGetData(&foretctemp) == NOERROR) { goto QuerySuccess; }
LEDebugOut((DEB_ITRACE, "%p OUT UtQueryPictFormat ( %lu )\n", NULL, FALSE));
return FALSE;
QuerySuccess: // data object supports this format; change passed in
// format to match
lpforetc->cfFormat = foretctemp.cfFormat; lpforetc->tymed = foretctemp.tymed;
// return success
LEDebugOut((DEB_ITRACE, "%p OUT UtQueryPictFormat ( %lu )\n", NULL, TRUE));
return(TRUE); }
#pragma SEG(UtConvertDibToBitmap)
FARINTERNAL_(HBITMAP) UtConvertDibToBitmap(HANDLE hDib) { VDATEHEAP();
LPBITMAPINFOHEADER lpbmih; HDC hdc; // the device context to create the bitmap for
size_t uBitsOffset; // the offset to where the image begins in the DIB
HBITMAP hBitmap; // the bitmap we'll return
if (!(lpbmih = (LPBITMAPINFOHEADER)GlobalLock(hDib))) return(NULL);
if (!(hdc = GetDC(NULL))) // Get screen DC.
{ // REVIEW: we may have to use the target device of this
// cache node.
return(NULL); }
uBitsOffset = sizeof(BITMAPINFOHEADER) + (lpbmih->biClrUsed ? lpbmih->biClrUsed : UtPaletteSize(lpbmih)); hBitmap = CreateDIBitmap(hdc, lpbmih, CBM_INIT, ((BYTE *)lpbmih)+uBitsOffset, (LPBITMAPINFO) lpbmih, DIB_RGB_COLORS);
// release the DC
ReleaseDC(NULL, hdc);
return hBitmap; }
//+----------------------------------------------------------------------------
//
// Function:
// UtConvertBitmapToDib, internal
//
// Synopsis:
// Creates a Device Independent Bitmap capturing the content of
// the argument bitmap.
//
// Arguments:
// [hBitmap] -- Handle to the bitmap to convert
// [hpal] -- color palette for the bitmap; may be null for
// default stock palette
//
// Returns:
// Handle to the DIB. May be null if any part of the conversion
// failed.
//
// Notes:
//
// History:
// 11/29/93 - ChrisWe - file inspection and cleanup
// 07/18/94 - DavePl - fixed for 16, 32, bpp bitmaps
//
//-----------------------------------------------------------------------------
FARINTERNAL_(HANDLE) UtConvertBitmapToDib(HBITMAP hBitmap, HPALETTE hpal) { VDATEHEAP();
HDC hScreenDC; BITMAP bm; // bitmap for hBitmap
UINT uBits; // number of color bits for bitmap
size_t uBmiSize; // size of bitmap info for the DIB
size_t biSizeImage; // temp to hold value in the handle memory
HANDLE hBmi; // handle for the new DIB bitmap we'll create
LPBITMAPINFOHEADER lpBmi; // pointer to the actual data area for DIB
HANDLE hDib = NULL; // the DIB we'll return
BOOL fSuccess = FALSE; DWORD dwCompression; BOOL fDeletePalette = FALSE; if (NULL == hBitmap) { return(NULL); }
// if no palette provided, use the default
if (NULL == hpal) { // This block fixes NTBUG #13029. The problem is that on a palette
// device (ie a 256 color video driver), we don't get passed the palette
// that is used by the DDB. So, we build the palette based on what
// is currently selected into the system palette.
// POSTPPC:
//
// We should change the clipboard code that calls this to ask for
// CF_PALETTE from the IDataObject that the DDB was obtained from, that
// way we know we get the colors that the calling app really intended
HDC hDCGlobal = GetDC(NULL); if(!hDCGlobal) return NULL; int iRasterCaps = GetDeviceCaps(hDCGlobal, RASTERCAPS);
ReleaseDC(NULL, hDCGlobal);
if ((iRasterCaps & RC_PALETTE)) { // Based the following code from the win sdk MYPAL example program.
// this creates a palette out of the currently active palette.
HANDLE hLogPal = GlobalAlloc (GHND, (sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * (PALETTESIZE))));
// if we are OOM, return failure now, because we aren't going
// to make it through the allocations later on.
if (!hLogPal) return NULL;
LPLOGPALETTE pLogPal = (LPLOGPALETTE)GlobalLock (hLogPal);
// 0x300 is a magic number required by GDI
pLogPal->palVersion = 0x300; pLogPal->palNumEntries = PALETTESIZE;
// fill in intensities for all palette entry colors
for (int iLoop = 0; iLoop < PALETTESIZE; iLoop++) { *((WORD *) (&pLogPal->palPalEntry[iLoop].peRed)) = (WORD)iLoop; pLogPal->palPalEntry[iLoop].peBlue = 0; pLogPal->palPalEntry[iLoop].peFlags = PC_EXPLICIT; }
// create a logical color palette according the information
// in the LOGPALETTE structure.
hpal = CreatePalette ((LPLOGPALETTE) pLogPal) ;
GlobalUnlock(hLogPal); GlobalFree(hLogPal);
if (!hpal) return NULL;
fDeletePalette = TRUE; } else { hpal = (HPALETTE)GetStockObject(DEFAULT_PALETTE); } } if (NULL == GetObject(hBitmap, sizeof(bm), (LPVOID)&bm)) { return(NULL); }
uBits = bm.bmPlanes * bm.bmBitsPixel;
// Based on the number of bits per pixel, set up the size
// of the color table, and the compression type as per the
// the following table:
//
//
// BPP Palette Size Compression
// ~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~
// 1,2,4,8 2^BPP * sizeof(RGBQUAD) None
// 16, 32 3 * sizeof(DWORD) masks BI_BITFIELDS
// 24 0 None
if (16 == bm.bmBitsPixel || 32 == bm.bmBitsPixel) { uBmiSize = sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD); dwCompression = BI_BITFIELDS; } else if (24 == bm.bmBitsPixel) { uBmiSize = sizeof(BITMAPINFOHEADER); dwCompression = BI_RGB; } else { Assert( bm.bmBitsPixel == 1 || bm.bmBitsPixel == 2 || bm.bmBitsPixel == 4 || bm.bmBitsPixel == 8 );
// VGA and EGA are planar devices on Chicago, so uBits needs
// to be used when determining the size of the bitmap info +
// the size of the color table.
uBmiSize = sizeof(BITMAPINFOHEADER) + (1 << uBits) * sizeof(RGBQUAD); dwCompression = BI_RGB; }
// Allocate enough memory to hold the BITMAPINFOHEADER
hBmi = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, (DWORD)uBmiSize); if (NULL == hBmi) { return NULL; }
lpBmi = (LPBITMAPINFOHEADER) GlobalLock(hBmi); if (NULL == lpBmi) { GlobalFree(hBmi); return NULL; } // Set up any interesting non-zero fields
lpBmi->biSize = (LONG)sizeof(BITMAPINFOHEADER); lpBmi->biWidth = (LONG) bm.bmWidth; lpBmi->biHeight = (LONG) bm.bmHeight; lpBmi->biPlanes = 1; lpBmi->biBitCount = (WORD) uBits; lpBmi->biCompression = dwCompression; // Grab the screen DC and set out palette into it
hScreenDC = GetDC(NULL); if (NULL == hScreenDC) { GlobalUnlock(hBmi); goto errRtn; }
// Call GetDIBits with a NULL lpBits parm, so that it will calculate
// the biSizeImage field for us
GetDIBits(hScreenDC, // DC
hBitmap, // Bitmap handle
0, // First scan line
bm.bmHeight, // Number of scan lines
NULL, // Buffer
(LPBITMAPINFO)lpBmi, // BITMAPINFO
DIB_RGB_COLORS);
// If the driver did not fill in the biSizeImage field, make one up
if (0 == lpBmi->biSizeImage) { LEDebugOut((DEB_WARN, "WARNING: biSizeImage was not computed for us\n")); lpBmi->biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * uBits) * bm.bmHeight; }
// Realloc the buffer to provide space for the bits. Use a new handle so
// that in the failure case we do not lose the exiting handle, which we
// would need to clean up properly.
biSizeImage = lpBmi->biSizeImage; GlobalUnlock(hBmi);
hDib = GlobalReAlloc(hBmi, (uBmiSize + biSizeImage), GMEM_MOVEABLE); if (NULL == hDib) { goto errRtn; }
// If the realloc succeeded, we can get rid of the old handle
hBmi = NULL;
// re-acquire the pointer to the handle
lpBmi = (LPBITMAPINFOHEADER)GlobalLock(hDib); if (NULL == lpBmi) { goto errRtn; }
hpal = SelectPalette(hScreenDC, hpal, FALSE); RealizePalette(hScreenDC);
// Call GetDIBits with a NON-NULL lpBits parm, and get the actual bits
if (GetDIBits(hScreenDC, // DC
hBitmap, // HBITMAP
0, // First scan line
(WORD)lpBmi->biHeight, // Count of scan lines
((BYTE FAR *)lpBmi)+uBmiSize, // Bitmap bits
(LPBITMAPINFO)lpBmi, // BITMAPINFOHEADER
DIB_RGB_COLORS) // Palette style
) { fSuccess = TRUE; }
GlobalUnlock(hDib);
errRtn: if (hScreenDC) { // Select back the old palette into the screen DC
SelectPalette(hScreenDC, hpal, FALSE); ReleaseDC(NULL, hScreenDC); }
if (fDeletePalette) { DeleteObject(hpal); }
// If we failed, we need to free up the header and the DIB
// memory
if (FALSE == fSuccess) { if (hBmi) { GlobalFree(hBmi); } if (hDib) { GlobalFree(hDib); hDib = NULL; } }
return(hDib); }
//+----------------------------------------------------------------------------
//
// Function:
// UtPaletteSize, internal
//
// Synopsis:
// Returns the size of a color table for a palette given the
// number of bits of color desired.
//
// Basically, the number of color table entries is:
//
// 1BPP
// 1<<1 = 2
//
// 4BPP
// if pbmi->biClrUsed is not zero and is less than 16, then use pbmi->biClrUsed,
// otherwise use 1 << 4 = 16
//
// 8BPP
// if pbmi->biClrUsed is not zero and is less than 256, then use pbmi->biClrUsed,
// otherwise use 1 << 8 = 256
//
// 16BPP
// if pbmi->biCompression is BITFIELDS then there are three color entries,
// otherwise no color entries.
//
// 24BPP
// pbmi->biCompression must be BI_RGB, there is no color table.
//
// 32BPP
// if pbmi->biCompression is BITFIELDS then there are three color entries,
// otherwise no color entries.
//
//
// There is never a case with a color table larger than 256 colors.
//
// Arguments:
// [lpHeader] -- ptr to BITMAPINFOHEADER structure
//
// Returns:
// Size in bytes of color information
//
// Notes:
//
// History:
// 11/29/93 - ChrisWe - change bit count argument to unsigned,
// and return value to size_t
//
// 07/18/94 - DavePl - Fixed for 16, 24, 32bpp DIBs
//
//-----------------------------------------------------------------------------
FARINTERNAL_(size_t) UtPaletteSize(BITMAPINFOHEADER * pbmi) { DWORD dwSize; WORD biBitCount = pbmi->biBitCount;
VDATEHEAP();
// Compute size of color table information in a DIB.
if (8 >= biBitCount) { if (pbmi->biClrUsed && (pbmi->biClrUsed <= (DWORD) (1 << biBitCount)) ) { dwSize = pbmi->biClrUsed * sizeof(RGBQUAD); } else { Assert(0 == pbmi->biClrUsed);
dwSize = (1 << biBitCount) * sizeof(RGBQUAD); } } else if (BI_BITFIELDS == pbmi->biCompression) { Assert(24 != biBitCount); // BI_BITFIELDS should never be set for 24 bit.
dwSize = 3 * sizeof(RGBQUAD); } else { dwSize = 0; }
Assert( (dwSize < 65536) && "Palette size overflows WORD");
return dwSize; }
//+-------------------------------------------------------------------------
//
// Function: UtGetDibExtents
//
// Synopsis: Returns the size of the DIB in HIMETRIC units
//
// Effects:
//
// Arguments: [lpbmi] -- the BITMAPINFOHEADER for the DIB
// [plWidth] -- OUT param for width
// [plHeight] -- OUT param for height
//
// Requires:
//
// Returns:
//
// Signals:
//
// Modifies:
//
// Algorithm:
//
// History: dd-mmm-yy Author Comment
// 04-Aug-94 Davepl Corrected logic
//
// Notes:
//
//--------------------------------------------------------------------------
FARINTERNAL_(void) UtGetDibExtents(LPBITMAPINFOHEADER lpbmi, LONG FAR* plWidth, LONG FAR* plHeight) { VDATEHEAP();
#define HIMET_PER_METER 100000L // number of HIMETRIC units / meter
if (!(lpbmi->biXPelsPerMeter && lpbmi->biYPelsPerMeter)) { HDC hdc; hdc = GetDC(NULL); if(!hdc) { *plWidth = 0; *plHeight = 0; return; }
lpbmi->biXPelsPerMeter = MulDiv(GetDeviceCaps(hdc, LOGPIXELSX), 10000, 254); lpbmi->biYPelsPerMeter = MulDiv(GetDeviceCaps(hdc, LOGPIXELSY), 10000, 254);
ReleaseDC(NULL, hdc); }
*plWidth = (lpbmi->biWidth * HIMET_PER_METER / lpbmi->biXPelsPerMeter); *plHeight= (lpbmi->biHeight * HIMET_PER_METER / lpbmi->biYPelsPerMeter);
// no longer need this
#undef HIMET_PER_METER
}
#pragma SEG(UtGetClassID)
FARINTERNAL_(BOOL) UtGetClassID(LPUNKNOWN lpUnk, CLSID FAR* lpClsid) { VDATEHEAP();
LPOLEOBJECT lpOleObj; // IOleObject pointer
LPPERSIST lpPersist; // IPersist pointer
// try to ask it as an object
if (lpUnk->QueryInterface(IID_IOleObject, (LPLPVOID)&lpOleObj) == NOERROR) { lpOleObj->GetUserClassID(lpClsid); lpOleObj->Release(); return(TRUE); } // try to ask it as a persistent object
if (lpUnk->QueryInterface(IID_IPersist, (LPLPVOID)&lpPersist) == NOERROR) { lpPersist->GetClassID(lpClsid); lpPersist->Release(); return(TRUE); } *lpClsid = CLSID_NULL; return(FALSE); }
#pragma SEG(UtGetIconData)
FARINTERNAL UtGetIconData(LPDATAOBJECT lpSrcDataObj, REFCLSID rclsid, LPFORMATETC lpforetc, LPSTGMEDIUM lpstgmed) { VDATEHEAP();
CLSID clsid = rclsid; lpstgmed->tymed = TYMED_NULL; lpstgmed->pUnkForRelease = NULL; lpstgmed->hGlobal = NULL; if (lpSrcDataObj) { if (lpSrcDataObj->GetData(lpforetc, lpstgmed) == NOERROR) return NOERROR; if (IsEqualCLSID(clsid, CLSID_NULL)) UtGetClassID(lpSrcDataObj, &clsid); } // get data from registration database
lpstgmed->hGlobal = OleGetIconOfClass(clsid, NULL, TRUE); if (lpstgmed->hGlobal == NULL) return ResultFromScode(E_OUTOFMEMORY); else lpstgmed->tymed = TYMED_MFPICT;
return NOERROR; }
// Performs operation like COPY, MOVE, REMOVE etc.. on src, dst storages. The
// caller can specifiy which streams to be operated upon through
// grfAllowedStreams parameter.
STDAPI UtDoStreamOperation(LPSTORAGE pstgSrc, LPSTORAGE pstgDst, int iOpCode, DWORD grfAllowedStmTypes) { VDATEHEAP();
HRESULT error; // error status so far
IEnumSTATSTG FAR* penumStg; // used to enumerate the storage elements
ULONG celtFetched; // how many storage elements were fetched
STATSTG statstg; // get an enumerator over the source storage
if (error = pstgSrc->EnumElements(NULL, NULL, NULL, &penumStg)) return error; // repeat for every storage
while(penumStg->Next(1, &statstg, &celtFetched) == NOERROR) { // operate on streams that we're interested in
if (statstg.type == STGTY_STREAM) { DWORD stmType; // find the type of the stream
// REVIEW, we must have constants for these name
// prefixes!!!
switch (statstg.pwcsName[0]) { case '\1': stmType = STREAMTYPE_CONTROL; break; case '\2': stmType = STREAMTYPE_CACHE; break; case '\3': stmType = STREAMTYPE_CONTAINER; break; default: stmType = (DWORD)STREAMTYPE_OTHER; }
// check whether it should be operated upon
if (stmType & grfAllowedStmTypes) { switch(iOpCode) { #ifdef LATER
case OPCODE_COPY: pstgDst->DestroyElement( statstg.pwcsName); error = pstgSrc->MoveElementTo( statstg.pwcsName, pstgDst, statstg.pwcsName, STGMOVE_COPY); break;
case OPCODE_MOVE: pstgDst->DestroyElement( statstg.pwcsName); error = pstgSrc->MoveElementTo( statstg.pwcsName, pstgDst, statstg.pwcsName, STGMOVE_MOVE); break;
case OPCODE_EXCLUDEFROMCOPY: AssertSz(FALSE, "Not yet implemented"); break; #endif // LATER
case OPCODE_REMOVE: error = pstgSrc->DestroyElement( statstg.pwcsName); break; default: AssertSz(FALSE, "Invalid opcode"); break; } } } // if the enumerator allocated a new name string, get rid of it
if (statstg.pwcsName) PubMemFree(statstg.pwcsName);
// quit the enumeration loop if we've hit an error
if (error != NOERROR) break; }
// release the enumerator
penumStg->Release();
// return the error state
return error; }
FARINTERNAL_(void) UtGetPresStreamName(LPOLESTR lpszName, int iStreamNum) { VDATEHEAP(); int i; // counts down the digits of iStreamNum
// count down the last three '0' characters of OLE_PRESENTATION_STREAM
// the -2 backs us up to the last character (remember the NULL
// terminator!)
for(lpszName += sizeof(OLE_PRESENTATION_STREAM)/sizeof(OLECHAR) - 2, i = 3; i; --lpszName, --i) { *lpszName = OLESTR("0123456789")[iStreamNum % 10]; if( iStreamNum > 0 ) { iStreamNum /= 10; } } }
FARINTERNAL_(void) UtRemoveExtraOlePresStreams(LPSTORAGE pstg, int iStart) { VDATEHEAP();
HRESULT hr; // error code from stream deletion
OLECHAR szName[sizeof(OLE_PRESENTATION_STREAM)/sizeof(OLECHAR)]; // space for the stream names
// if the stream number is invalid, do nothing
if ((iStart < 0) || (iStart >= OLE_MAX_PRES_STREAMS)) return; // create presentation stream name
_xstrcpy(szName, OLE_PRESENTATION_STREAM); UtGetPresStreamName(szName, iStart); // for each of these streams that exists, get rid of it
while((hr = pstg->DestroyElement(szName)) == NOERROR) { // if we've gotten to the end of the possible streams, quit
if (++iStart >= OLE_MAX_PRES_STREAMS) break; // Get the next presentation stream name
UtGetPresStreamName(szName, iStart); }
// since the only reason these streams should be open, the first
// failure had better be that the file was not found, and not
// anything else (such as STG_E_ACCESSDENIED)
AssertSz(hr == STG_E_FILENOTFOUND, "UtRemoveExtraOlePresStreams failure"); }
//+-------------------------------------------------------------------------
//
// Function: ConvertPixelsToHIMETRIC
//
// Synopsis: Converts a pixel dimension to HIMETRIC units
//
// Effects:
//
// Arguments: [hdcRef] -- the reference DC
// [ulPels] -- dimension in pixel measurement
// [pulHIMETRIC] -- OUT param of converted HIMETRIC result
// [tDimension] -- indicates XDIMENSION or YDIMENSION of input
//
// Returns: S_OK, E_FAIL
//
// Algorithm: screen_mm * input_pels HIMETRICS/
// ---------------------- * / == HIMETRICS
// screen_pels /mm
//
// History: dd-mmm-yy Author Comment
// 04-Aug-94 Davepl Created
//
// Notes: We need to know whether the input size is in the X or
// Y dimension, since the aspect ratio could vary
//
//--------------------------------------------------------------------------
FARINTERNAL ConvertPixelsToHIMETRIC (HDC hdcRef, ULONG lPels, ULONG * pulHIMETRIC, DIMENSION tDimension) { VDATEHEAP(); VDATEPTROUT(pulHIMETRIC, ULONG *);
// Clear OUT parameter in case of error
*pulHIMETRIC = 0; ULONG scrmm = 0; ULONG scrpel = 0;
const ULONG HIMETRIC_PER_MM = 100;
// If we weren't given a reference DC, use the screen as a default
BOOL fLocalDC = FALSE; if (NULL == hdcRef) { hdcRef = GetDC(NULL); if (hdcRef) { fLocalDC = TRUE; } } if (hdcRef) { Assert(tDimension == XDIMENSION || tDimension == YDIMENSION);
// Get the count of pixels and millimeters for the screen
if (tDimension == XDIMENSION) { scrmm = GetDeviceCaps(hdcRef, HORZSIZE); scrpel = GetDeviceCaps(hdcRef, HORZRES); } else { scrmm = GetDeviceCaps(hdcRef, VERTSIZE); scrpel = GetDeviceCaps(hdcRef, VERTRES); } // If we had to create a temporary DC, it can be released now
if (TRUE == fLocalDC) { ReleaseDC(NULL, hdcRef); } }
// If we successfully obtained the DC's size and resolution,
// we can compute the HIMETRIC value.
if (scrmm && scrpel) { *pulHIMETRIC = (scrmm * lPels * HIMETRIC_PER_MM) / scrpel; return S_OK; }
return E_FAIL;
}
|