Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1728 lines
48 KiB

////////////////////////////////////////////////////////////////////////////////
//
// DocSum.c
//
// Notes:
// To make this file useful for OLE objects, define OLE_PROPS.
//
// The macro lpDocObj must be used for all methods to access the
// object data to ensure that this will compile with OLE_PROPS defined.
//
// Change history:
//
// Date Who What
// --------------------------------------------------------------------------
// 06/01/94 B. Wentz Created file
// 06/25/94 B. Wentz Converted to lean & mean API's
// 07/26/94 B. Wentz Added code to merge DocumentSummary and UserDefined streams.
// 08/03/94 B. Wentz Added Manager & Company Properties
//
////////////////////////////////////////////////////////////////////////////////
#include "priv.h"
#pragma hdrstop
#ifndef WINNT
#ifndef INC_OLE2
#define INC_OLE2
#endif // INC_OLE2
//#include <string.h>
#include "nocrt.h"
#include <windows.h>
// REVIEW: Fix the INITGUID stuff to not use pre-compiled headers.....
#include "office.h"
#define INITGUID
#include <objbase.h>
#include <initguid.h>
#include <objerror.h>
#include "proptype.h"
#include "internal.h"
#include "propmisc.h"
#include "debug.h"
#endif
// Table mapping string id's to Property Id's
static LONG rglSIDtoPID [] =
{
PID_CATEGORY, // DSI_CATEGORY
PID_PRESFORMAT, // DSI_FORMAT
PID_MANAGER, // DSI_MANAGER
PID_COMPANY // DSI_COMPANY
}; // rglSIDtoPID
// Table mapping integer statistic id's to Property Id's
static LONG rglIIDtoPID [] =
{
PID_BYTECOUNT, // DSI_BYTES
PID_LINECOUNT, // DSI_LINES
PID_PARACOUNT, // DSI_PARAS
PID_SLIDECOUNT, // DSI_SLIDES
PID_NOTECOUNT, // DSI_NOTES
PID_HIDDENCOUNT, // DSI_HIDDENSLIDES
PID_MMCLIPCOUNT // DSI_MMCLIPS
}; // rglIIDtoPID
// Internal prototypes
static void PASCAL FreeData (LPDSIOBJ lpDSIObj);
static BOOL FFreeHeadPart(LPPLXHEADPART lpplxheadpart, SHORT iPlex);
static SHORT ILookupHeading(LPPLXHEADPART lpplxheadpart, LPSTR lpsz);
static SHORT IMapHeadingIndex(DWORD idwHeading, LPPLXHEADPART lpplxheadpart);
static SHORT IGetHeadingIndex(DWORD idwHeading, LPSTR lpszHeading, LPDSIOBJ lpDSIObj);
static SHORT IGetHeadingInsertIndex(DWORD idwHeading, LPDSIOBJ lpDSIObj);
#ifdef KEEP_FOR_LATER
static SHORT ILookupDocPart(LPPLXHEADPART lpplxheadpart, LPSTR lpsz);
static SHORT IMapDocPartIndex(DWORD idwDocPart, LPPLXHEADPART lpplxheadpart);
#endif
#ifdef OLE_PROPS
// Access to the object must be cast up to a LPDOCSUMINFO for OLE objects
#define lpDocObj ((LPDOCSUMINFO) lpDSIObj)
#define lpData ((LPDSINFO) ((LPDOCSUMINFO) lpDSIObj)->m_lpData)
////////////////////////////////////////////////////////////////////////////////
//
// HrPropExDocSumInfoQueryInterface
// (IUnknown::QueryInterface)
//
// Purpose:
// IUnknown method to query interfaces available.
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT HRESULT
HrDocSumQueryInterface
(IUnknown FAR *lpUnk, // Pointer to the object
REFIID riid, // Pointer to interface Id
LPVOID FAR* ppvObj) // Interface to return.
{
*ppvObj = NULL;
return E_NOTIMPL;
} // HrPropExDsiQueryInterface
////////////////////////////////////////////////////////////////////////////////
//
// UlPropExDsiAddRef
// (IUnknown::AddRef)
//
// Purpose:
// Increments object reference count.
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT ULONG
UlDocSumAddRef
(IUnknown FAR *lpUnk) // Pointer to the object
{
return 0;
} // UlPropExDsiAddRef
////////////////////////////////////////////////////////////////////////////////
//
// UlPropExDsiRelease
// (IUnknown::Release)
//
// Purpose:
// Decrements reference count, possibly freeing object.
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT ULONG
UlDocSumRelease
(IUnkown FAR *lpUnk) // Pointer to object
{
return 0;
} // UlPropExDocSumInfoRelease
#else // !OLE_PROPS
// Do nothing for non-OLE code....
#define lpDocObj lpDSIObj
#define lpData ((LPDSINFO) lpDSIObj->m_lpData)
#endif // OLE_PROPS
////////////////////////////////////////////////////////////////////////////////
//
// OfficeDirtyDSIObj
//
// Purpose:
// Sets object state to dirty or clean.
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT VOID OfficeDirtyDSIObj
(LPDSIOBJ lpDSIObj, // The object
BOOL fDirty) // Flag indicating if the object is dirty.
{
Assert(lpDSIObj != NULL);
lpDocObj->m_fObjChanged = fDirty;
} // OfficeDirtyDSIObj
////////////////////////////////////////////////////////////////////////////////
//
// FDocSumCreate
//
// Purpose:
// Create the object and return it.
//
////////////////////////////////////////////////////////////////////////////////
BOOL
FDocSumCreate
(LPDSIOBJ FAR *lplpDSIObj, // Pointer to pointer to object
void *prglpfn[]) // Pointer to function array
{
LPDSIOBJ lpDSIObj; // Hack - a temp, must call it "lpDSIObj" for macros to work!
if (lplpDSIObj == NULL)
return(TRUE);
// Make sure we get valid args before we start alloc'ing
if ((prglpfn == NULL) || (prglpfn[ifnCPConvert] == NULL))
return FALSE;
if ((*lplpDSIObj = (LPDSIOBJ) PvMemAlloc(sizeof (DOCSUMINFO))) == NULL)
{
// REVIEW: Add alert
return FALSE;
}
lpDSIObj = *lplpDSIObj; // Save us some indirecting & let us use the "LP" macros
// If alloc fails, free the original object too.
if ((lpData =
PvMemAlloc(sizeof (DSINFO))) == NULL)
{
// REVIEW: Add alert
VFreeMemP(*lplpDSIObj, sizeof(DOCSUMINFO));
return FALSE;
}
FillBuf ((void *) lpData, (int) 0, (sizeof (DSINFO) - ifnDSIMax*(sizeof (void *))));
// Save the fnc's for Code Page conversions
lpData->lpfnFCPConvert = (BOOL (*)(LPSTR, DWORD, DWORD, BOOL)) prglpfn[ifnCPConvert];
OfficeDirtyDSIObj (*lplpDSIObj, FALSE);
return TRUE;
} // FDocSumCreate
////////////////////////////////////////////////////////////////////////////////
//
// FDocSumDestroy
//
// Purpose:
// Destroy the given object.
//
////////////////////////////////////////////////////////////////////////////////
BOOL
FDocSumDestroy
(LPDSIOBJ FAR *lplpDSIObj) // Pointer to pointer to object
{
if ((lplpDSIObj == NULL) ||
(*lplpDSIObj == NULL))
return TRUE;
if (((LPDSIOBJ) *lplpDSIObj)->m_lpData != NULL)
{
FreeData (*lplpDSIObj);
// Invalidate any OLE Automation DocumentProperty objects we might have
InvalidateVBAObjects(NULL, *lplpDSIObj, NULL);
VFreeMemP((*lplpDSIObj)->m_lpData, sizeof(DSINFO));
}
VFreeMemP(*lplpDSIObj, sizeof(DOCSUMINFO));
*lplpDSIObj = NULL;
return TRUE;
} // FDocSumDestroy
////////////////////////////////////////////////////////////////////////////////
//
// FreeData
//
// Purpose:
// Deallocates all the member data for the object
//
// Note:
// Assumes object is valid.
//
////////////////////////////////////////////////////////////////////////////////
static void PASCAL
FreeData
(LPDSIOBJ lpDSIObj) // Pointer to valid object
{
DWORD irg;
for (irg = 0; irg < cDSIStringsMax; irg++)
{
if (lpData->rglpstz[irg] != NULL)
VFreeMemP((void *) lpData->rglpstz[irg],CBBUF(lpData->rglpstz[irg]));
}
if (lpData->cbUnkMac > 0)
FreeRglpUnk(lpData->rglpUnk, lpData->cbUnkMac);
if (lpData->rglpUnk != NULL)
VFreeMemP(lpData->rglpUnk, lpData->cbUnkMac*sizeof(PROPIDTYPELP));
if (lpData->rglpFIdOffData != NULL)
{
for (irg = 0; irg < lpData->cSect; ++irg)
{
if (lpData->rglpFIdOffData[irg] != NULL)
VFreeMemP(lpData->rglpFIdOffData[irg], lpData->rglpSect[irg].cb-sizeof(SECTION));
}
VFreeMemP(lpData->rglpFIdOffData,lpData->cSect*sizeof(LPVOID));
}
if (lpData->rglpFIdOff != NULL)
VFreeMemP(lpData->rglpFIdOff, lpData->cSect*sizeof(IDOFFSET));
if (lpData->rglpSect != NULL)
VFreeMemP(lpData->rglpSect, lpData->cSect*sizeof(SECTION));
if (lpData->lpplxheadpart != NULL)
FreeHeadPartPlex(lpDSIObj);
} // FreeData
////////////////////////////////////////////////////////////////////////////////
//
// FreeHeadPartPlex
//
////////////////////////////////////////////////////////////////////////////////
VOID PASCAL
FreeHeadPartPlex
(LPDSIOBJ lpDSIObj) // A doc part linked list node
{
SHORT i;
if ((lpDocObj == NULL) || (lpData == NULL) ||
(lpData->lpplxheadpart == NULL))
return;
for (i = 0; i < lpData->lpplxheadpart->ixheadpartMac; ++i)
VFreeMemP(lpData->lpplxheadpart->rgxheadpart[i].lpstz,CBBUF(lpData->lpplxheadpart->rgxheadpart[i].lpstz));
FreePpl(lpData->lpplxheadpart);
lpData->lpplxheadpart = NULL;
lpData->dwcTotParts = 0;
lpData->dwcTotHead = 0;
} // FreeHeadPartPlex
////////////////////////////////////////////////////////////////////////////////
//
// FFreeHeadPart
//
// Frees a single element from the plex
//
/////////////////////////////////////////////////////////////////////////////////
BOOL FFreeHeadPart(LPPLXHEADPART lpplxheadpart, SHORT iPlex)
{
VFreeMemP(lpplxheadpart->rgxheadpart[iPlex].lpstz,CBBUF(lpplxheadpart->rgxheadpart[iPlex].lpstz));
return(RemovePl(lpplxheadpart, iPlex));
}
////////////////////////////////////////////////////////////////////////////////
//
// FDocSumClear
//
// Purpose:
// Clear the data stored in the object, but do not destroy the object
//
////////////////////////////////////////////////////////////////////////////////
BOOL
FDocSumClear
(LPDSIOBJ lpDSIObj) // Pointer to object
{
if ((lpDocObj == NULL) ||
(lpData == NULL))
return TRUE;
FreeData (lpDocObj);
// Invalidate any OLE Automation DocumentProperty objects we might have
InvalidateVBAObjects(NULL, lpDSIObj, NULL);
// Clear the data, don't blt over the fn's stored at the end.
FillBuf ((void *) lpData, (int) 0, (sizeof (DSINFO) - ifnDSIMax*(sizeof (void *))));
OfficeDirtyDSIObj (lpDSIObj, TRUE);
return TRUE;
} // FDocSumClear
////////////////////////////////////////////////////////////////////////////////
//
// FCreateDocSumPIdTable
//
// Purpose:
// Calculate the Property Id-offset table for the Document Summary object
//
////////////////////////////////////////////////////////////////////////////////
BOOL
FCreateDocSumPIdTable
(LPDSIOBJ lpDSIObj, // Pointer to object
LPPIDOFFSET *lprgPO, // Table fo PId-offsets
DWORD *lpirgPOMac, // Number of elements in lprgPO
DWORD *pcb) // Size of section
{
DWORD dwOffset;
DWORD irgPO;
DWORD irg;
if ((lpDocObj == NULL) ||
(lpData == NULL) ||
(lpirgPOMac == NULL) ||
(lprgPO == NULL) ||
(pcb == NULL))
return FALSE;
// Create the biggest PropId-offset table we might need.
*lprgPO = PvMemAlloc(sizeof(PIDOFFSET)*(cDSIPIDS+lpData->cbUnkMac+1));
if (*lprgPO == NULL)
{
// REVIEW: add alert
return FALSE;
}
// Zip through all of our properties and put the valid ones in the
// property id-offset table, filling in the offsets as we go. Remember
// that all offsets for type-value pairs must be aligned on 32-bit
// boundaries, so adjust offsets accordingly....
// All offsets need have a DWORD added to them to account for
// the space that the property type field will have.
// Start the offsets at 0. They need to be adjusted after
// the table is completed. This is done when the table is
// written out.
// Add in the codepage for this file
(*lprgPO)[0].Id = PID_CODEPAGE;
(*lprgPO)[0].dwOffset = 0;
irgPO = 1;
dwOffset = 2*sizeof(DWORD);
// VT_LPSTR
for (irg = 0; irg < cDSIStringsMax; irg++)
{
if (lpData->rglpstz[irg] != NULL)
{
(*lprgPO)[irgPO].Id = irg;
(*lprgPO)[irgPO].dwOffset = dwOffset;
dwOffset += 2*sizeof(DWORD) + CBSTR (lpData->rglpstz[irg]);
dwOffset += CBALIGN32 (dwOffset);
irgPO++;
}
}
// VT_I4
for (irg = PID_BYTECOUNT; irg < cdwDSIMax; irg++)
{
// Only write out int prop's that are not 0
if (FDocSumInfoPropBitIsSet(irg, lpData->bPropSet))
{
(*lprgPO)[irgPO].Id = irg;
(*lprgPO)[irgPO].dwOffset = dwOffset;
dwOffset += 2*sizeof(DWORD); // Should naturally align on 32-bit bound
irgPO++;
}
}
// VT_BOOL
(*lprgPO)[irgPO].Id = PID_SCALE;
(*lprgPO)[irgPO].dwOffset = dwOffset;
dwOffset += 2*sizeof(DWORD);
irgPO++;
(*lprgPO)[irgPO].Id = PID_LINKSDIRTY;
(*lprgPO)[irgPO].dwOffset = dwOffset;
dwOffset += 2*sizeof(DWORD);
irgPO++;
// VT_VECTOR | VT_LPSTR (PID_DOCPARTS)
if (lpData->dwcTotParts)
{
Assert(lpData->lpplxheadpart != NULL);
(*lprgPO)[irgPO].Id = PID_DOCPARTS;
(*lprgPO)[irgPO].dwOffset = dwOffset;
irgPO++;
dwOffset += 2*sizeof(DWORD); // The DWORD count of elements in vector
// and the type indicator
irg = 0;
while (irg < lpData->dwcTotParts + lpData->dwcTotHead)
{
// Size of string + dword that tells the size of the string
if (!(lpData->lpplxheadpart->rgxheadpart[irg].fHeading)) // Check it's a document part
dwOffset += CBSTR (lpData->lpplxheadpart->rgxheadpart[irg].lpstz) + sizeof(DWORD);
++irg;
} // while
#ifdef NOT_IMPL
dwOffset += CBALIGN32 (dwOffset);
#endif
}
// VT_VECTOR | VT_VARIANT (PID_HEADINGPAIR)
if (lpData->dwcTotHead)
{
(*lprgPO)[irgPO].Id = PID_HEADINGPAIR;
(*lprgPO)[irgPO].dwOffset = dwOffset;
irgPO++;
dwOffset += 2*sizeof(DWORD); // The DWORD type and DWORD count of
// elements in vector
irg = 0;
while (irg < lpData->dwcTotParts + lpData->dwcTotHead)
{
if (lpData->lpplxheadpart->rgxheadpart[irg].fHeading) // Check it's a heading
{
// Size of string + DWORD that tells the size of the string +
// DWORD for the type + 2 DWORD's for the type and VT_I4 value
dwOffset += CBSTR (lpData->lpplxheadpart->rgxheadpart[irg].lpstz) + 4*sizeof(DWORD);
}
++irg;
} // while
#ifdef NOT_IMPL
dwOffset += CBALIGN32 (dwOffset);
#endif
}
// Now do all the ones we didn't understand.
for (irg = 0; irg < lpData->cbUnkMac; irg++)
{
(*lprgPO)[irgPO].Id = lpData->rglpUnk[irg].dwId;
(*lprgPO)[irgPO].dwOffset = dwOffset;
dwOffset += lpData->rglpUnk[irg].dwSize + sizeof (DWORD);
dwOffset += CBALIGN32 (dwOffset);
irgPO++;
}
*pcb = dwOffset;
*lpirgPOMac = irgPO;
return TRUE;
} // FCreateDocSumPIdTable
////////////////////////////////////////////////////////////////////////////////
//
// FDocSumShouldSave
//
// Purpose:
// Indicates if the data has changed, meaning a write is needed.
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL
FDocSumShouldSave
(LPDSIOBJ lpDSIObj) // Pointer to object
{
if ((lpDocObj == NULL) ||
(lpData == NULL))
return FALSE;
return lpDocObj->m_fObjChanged;
} // FDocSumShouldSave
#ifdef UNUSED
////////////////////////////////////////////////////////////////////////////////
//
// FDocSumIsEmpty
//
// Purpose:
// Indicates that the object is empty.
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL
FDocSumIsEmpty
(LPDSIOBJ lpDSIObj) // Pointer to object
{
if ((lpDocObj == NULL) ||
(lpData == NULL))
return FALSE;
return lpDocObj->m_fObjEmpty;
} // FDocSumIsEmpty
#endif
////////////////////////////////////////////////////////////////////////////////
//
// FCbDocSumString
//
// Purpose:
// Determine the size of the given string.
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL
FCbDocSumString
(LPDSIOBJ lpDSIObj, // Pointer to object
WORD iw, // Index of string to get bytecount of
DWORD *pdw) // Pointer to dword
{
if ((lpDocObj == NULL) ||
(lpData == NULL) ||
(iw < 0) ||
(iw > DSI_STRINGLAST ) ||
(lpData->rglpstz[rglSIDtoPID[iw]] == NULL))
return FALSE;
*pdw = (CBSTR (lpData->rglpstz[rglSIDtoPID[iw]]));
return TRUE;
} // FCbDocSumString
////////////////////////////////////////////////////////////////////////////////
//
// LpszDocSumGetString
//
// Purpose:
// Get the string property.
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT LPSTR
LpszDocSumGetString
(LPDSIOBJ lpDSIObj, // Pointer to object
WORD iw, // Index of string to get
DWORD cbMax, // Max size of the buffer.
LPSTR lpsz) // Pointer to buffer for Category string
{
DWORD cb;
if ((lpDocObj == NULL) ||
(lpData == NULL) ||
(iw < 0) ||
((iw & ~PTRWIZARD) > DSI_STRINGLAST) ||
(lpData->rglpstz[rglSIDtoPID[iw & ~PTRWIZARD]] == NULL) ||
((lpsz == NULL) && (!(iw & PTRWIZARD))))
return NULL;
if (iw & PTRWIZARD)
{
if (CBSTR(lpData->rglpstz[rglSIDtoPID[iw & ~PTRWIZARD]]) == 0)
return(NULL);
return PSTR (lpData->rglpstz[rglSIDtoPID[iw & ~PTRWIZARD]]);
}
cb = min(CBSTR(lpData->rglpstz[rglSIDtoPID[iw]]),cbMax-1);
if (cb > 0)
PbSzNCopy (lpsz, PSTR (lpData->rglpstz[rglSIDtoPID[iw]]), cb);
lpsz[cb] = '\0';
return lpsz;
} // LpszDocSumGetString
////////////////////////////////////////////////////////////////////////////////
//
// FDocSumSetString
//
// Purpose:
// Set the string property.
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL
FDocSumSetString
(LPDSIOBJ lpDSIObj, // Pointer to object
WORD iw, // Index of string to set
LPSTR lpsz) // New category string
{
if ((lpDocObj == NULL) ||
(lpData == NULL) ||
(iw < 0) ||
(iw > DSI_STRINGLAST) ||
(lpsz == NULL))
return FALSE;
lpData->rglpstz[rglSIDtoPID[iw]] =
LpstzUpdateString (&(lpData->rglpstz[rglSIDtoPID[iw]]), lpsz, FALSE);
OfficeDirtyDSIObj (lpDSIObj, TRUE);
return (lpData->rglpstz[rglSIDtoPID[iw]] != NULL);
} // FDocSumSetString
////////////////////////////////////////////////////////////////////////////////
//
// ILookupHeading
//
// Purpose: To lookup a heading in the headpart plex given a lpsz to match.
//
// Returns: The index if found, -1 otherwise.
//
////////////////////////////////////////////////////////////////////////////////
SHORT ILookupHeading(LPPLXHEADPART lpplxheadpart, // the plex
LPSTR lpsz) // the string
{
SHORT i;
if ((lpplxheadpart == NULL) || (lpsz == NULL))
return -1;
for (i = 0; i < lpplxheadpart->ixheadpartMac; ++i)
{
if ((lpplxheadpart->rgxheadpart[i].fHeading) &&
(lstrcmpi(lpsz, PSTR(lpplxheadpart->rgxheadpart[i].lpstz)) == 0))
return(i); // found it!!
}
return(-1);
}
#ifdef KEEP_FOR_LATER
////////////////////////////////////////////////////////////////////////////////
//
// ILookupDocPart
//
// Purpose: To lookup a docpart in the headpart plex given a lpsz to match.
//
// Returns: The index if found, -1 otherwise.
//
////////////////////////////////////////////////////////////////////////////////
SHORT ILookupDocPart(LPPLXHEADPART lpplxheadpart, // the plex
LPSTR lpsz) // the string
{
SHORT i;
if ((lpplxheadpart == NULL) || (lpsz == NULL))
return -1;
for (i = 0; i < lpplxheadpart->ixheadpartMac; ++i)
{
if ((!(lpplxheadpart->rgxheadpart[i].fHeading)) &&
(lstrcmpi(lpsz, PSTR(lpplxheadpart->rgxheadpart[i].lpstz)) == 0))
return(i); // found it!!
}
return(-1);
}
#endif
///////////////////////////////////////////////////////////////////////////
//
// IMapHeadingIndex
//
// Take a heading index and map it to the corresponding index in the plex
//
///////////////////////////////////////////////////////////////////////////
SHORT IMapHeadingIndex(DWORD idwHeading, // Index from user
LPPLXHEADPART lpplxheadpart) // plex
{
SHORT i;
DWORD cHeading=0;
for (i = 0; i < lpplxheadpart->ixheadpartMac; ++i)
{
if (lpplxheadpart->rgxheadpart[i].fHeading)
{
++cHeading;
if (cHeading == idwHeading)
return(i);
}
}
Assert(FALSE); // We should've found it
return(0);
}
#ifdef KEEP_FOR_LATER
///////////////////////////////////////////////////////////////////////////
//
// IMapDocPartIndex
//
// Take a heading index and map it to the corresponding index in the plex
//
///////////////////////////////////////////////////////////////////////////
SHORT IMapDocPartIndex(DWORD idwDocPart, // Index from user
LPPLXHEADPART lpplxheadpart) // plex
{
SHORT i;
DWORD cDocPart=0;
for (i = 0; i < lpplxheadpart->ixheadpartMac; ++i)
{
if (!(lpplxheadpart->rgxheadpart[i].fHeading))
{
++cDocPart;
if (cDocPart == idwDocPart)
return(i);
}
}
Assert(FALSE); // We should've found it
return(0);
}
#endif
////////////////////////////////////////////////////////////////////////////////
//
// IGetHeadingIndex
//
// Given either an index or an lpsz, return the index of the heading in the plex
//
// idwHeading is 1-based!!
//
////////////////////////////////////////////////////////////////////////////////
SHORT IGetHeadingIndex(idwHeading, lpszHeading, lpDSIObj)
DWORD idwHeading;
LPSTR lpszHeading;
LPDSIOBJ lpDSIObj;
{
if (lpszHeading == NULL)
{
if ((idwHeading < 1) || (idwHeading > lpData->dwcTotHead))
return (-1);
return(IMapHeadingIndex(idwHeading, lpData->lpplxheadpart));
}
return(ILookupHeading(lpData->lpplxheadpart, lpszHeading));
}
////////////////////////////////////////////////////////////////////////////////
//
// IGetHeadingInsertIndex
//
// Given an index return the index of where to insert the heading in the plex
//
// idwHeading is 1-based!!
//
////////////////////////////////////////////////////////////////////////////////
SHORT IGetHeadingInsertIndex(idwHeading, lpDSIObj)
DWORD idwHeading;
LPDSIOBJ lpDSIObj;
{
SHORT i;
DWORD cHeading=0;
if ((idwHeading < 1) || (idwHeading > lpData->dwcTotHead+1))
return(-1);
if (lpData->dwcTotHead == 0)
return(0);
if (idwHeading == lpData->dwcTotHead+1)
return((SHORT)(lpData->dwcTotHead+lpData->dwcTotParts));
for (i = 0; i < lpData->lpplxheadpart->ixheadpartMac; ++i)
{
if (lpData->lpplxheadpart->rgxheadpart[i].fHeading)
{
++cHeading;
if (cHeading == idwHeading)
return(i);
}
}
Assert (FALSE); // We should have found it
return(-1);
}
////////////////////////////////////////////////////////////////////////////////
//
// FCDocSumDocParts
//
// Purpose:
// Determine how many document parts there are
//
// Note: idwPart is interpreted as an absolute position into the list of parts.
// See figure 3 above.
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL
FCDocSumDocParts
(LPDSIOBJ lpDSIObj, // Pointer to object
DWORD *pdw) // Pointer to dword
{
if ((lpDocObj == NULL) ||
(lpData == NULL))
return FALSE;
*pdw = lpData->dwcTotParts;
return TRUE;
} // FCDocSumCDocParts
// Determine how many Document Parts there are for a given heading.
//
// Parameters:
//
// lpDSIObj - pointer to Document Summary Info object
// idwHeading - 1-based index of Heading
// lpszHeading - name of Heading
// pdw - pointer to dword, will contain the count on return
//
// If lpszHeading is non-null, this value will be used to look up
// the heading. Otherwise idwHeading will be used.
//
// Return value:
//
// The function returns TRUE on success, FALSE on error.
//
DLLEXPORT BOOL FCDocSumDocPartsByHeading (LPDSIOBJ lpDSIObj,
DWORD idwHeading,
LPSTR lpszHeading,
DWORD *pdw)
{
SHORT iHeading;
if ((lpDocObj == NULL) ||
(lpData == NULL) || (lpData->lpplxheadpart == NULL))
return FALSE;
iHeading = IGetHeadingIndex(idwHeading, lpszHeading, lpDSIObj);
if (iHeading == -1)
return(FALSE);
*pdw = lpData->lpplxheadpart->rgxheadpart[iHeading].dwParts;
return(TRUE);
}
// Determine the size of a specific (one) Document Part
// for a given heading.
//
// Parameters:
//
// lpDSIObj - pointer to Document Summary Info object.
// idwPart - 1-based index of Document part.
// idwHeading - 1-based index of Heading
// lpszHeading - name of Heading
// pdw - pointer to dword, will contain cb
//
// If lpszHeading is non-null, this value will be used to look up
// the heading. Otherwise idwHeading will be used.
//
// Return value:
//
// The function returns TRUE on success, FALSE on error
// (including non-existing Heading).
//
// Note: idwPart is interpreted as a relative position for a given heading.
// See figure 1 above.
DLLEXPORT BOOL FCbDocSumDocPart (LPDSIOBJ lpDSIObj, DWORD idwPart, DWORD idwHeading,
LPSTR lpszHeading, DWORD *pdw)
{
DWORD iHeading;
if ((lpDocObj == NULL) ||
(lpData == NULL) || (lpData->lpplxheadpart == NULL))
return FALSE;
iHeading = IGetHeadingIndex(idwHeading, lpszHeading, lpDSIObj);
if (iHeading == -1)
return(FALSE);
if ((idwPart < 1) || (idwPart > lpData->lpplxheadpart->rgxheadpart[iHeading].dwParts))
return (FALSE);
*pdw = CBSTR(lpData->lpplxheadpart->rgxheadpart[iHeading+idwPart].lpstz);
return(TRUE);
}
// Get one of the Document Parts for a given Heading.
//
// Parameters:
//
// lpDSIObj - pointer to Document Summary Info object
// idwPart - 1-based index of Document part
// idwHeading - 1-based index of Heading
// lpszHeading - name of Heading
// cbMax - number of bytes in lpsz
// lpsz - buffer to hold Document part (allocated by caller)
//
// If lpszHeading is non-null, this value will be used to look up
// the heading. Otherwise idwHeading will be used.
//
// Return value:
//
// The function returns lpsz on success.
// The function returns NULL on errors.
//
// Note: idwPart is interpreted as a relative position for a given heading.
// See figure 1 above.
DLLEXPORT LPSTR LpszDocSumGetDocPart (LPDSIOBJ lpDSIObj, DWORD idwPart,
DWORD idwHeading, LPSTR lpszHeading,
DWORD cbMax, LPSTR lpsz)
{
SHORT iHeading;
DWORD cb;
if ((lpDocObj == NULL) ||
(lpData == NULL))
return(NULL);
AssertSz ((PTRWIZARD > lpData->dwcTotParts), "We've got way more doc parts than ever expected!");
AssertSz ((lpData->lpplxheadpart != NULL), "lpData->lpplxheadpart cannot be NULL because lpData->dwcTotParts > 0");
iHeading = IGetHeadingIndex(idwHeading, lpszHeading, lpDSIObj);
if (iHeading == -1)
return(NULL);
if (((idwPart & ~PTRWIZARD) > lpData->lpplxheadpart->rgxheadpart[iHeading].dwParts) ||
((idwPart & ~PTRWIZARD) < 1))
return NULL;
if (idwPart & PTRWIZARD)
return PSTR (lpData->lpplxheadpart->rgxheadpart[iHeading+(idwPart & ~PTRWIZARD)].lpstz);
if (lpsz == NULL)
return(NULL);
cb = min(CBSTR (lpData->lpplxheadpart->rgxheadpart[iHeading+idwPart].lpstz),cbMax-1);
if (cb > 0)
PbSzNCopy (lpsz, PSTR (lpData->lpplxheadpart->rgxheadpart[iHeading+idwPart].lpstz), cb);
lpsz[cb] = '\0';
return lpsz;
}
// Set one (existing) Document Part by heading
//
// Parameters:
//
// lpDSIObj - pointer to Document Summary Info object
// idwPart - 1-based index of Document part
// idwHeading - 1-based index of Heading
// lpszHeading - name of Heading
// lpsz - buffer containing new Document Part
//
// If lpszHeading is non-null, this value will be used to look up
// the heading. Otherwise idwHeading will be used.
//
// Return value:
//
// The function returns TRUE on success.
// The function returns FALSE on error.
//
// Note: idwPart is interpreted as a relative position for a given heading.
// See figure 1 above.
DLLEXPORT BOOL FDocSumSetDocPart (LPDSIOBJ lpDSIObj, DWORD idwPart,
DWORD idwHeading, LPSTR lpszHeading,
LPSTR lpsz)
{
SHORT iHeading;
if ((lpDocObj == NULL) ||
(lpData == NULL))
return(FALSE);
AssertSz ((lpData->lpplxheadpart != NULL), "lpData->lpplxheadpart cannot be NULL because lpData->dwcTotParts > 0");
iHeading = IGetHeadingIndex(idwHeading, lpszHeading, lpDSIObj);
if (iHeading == -1)
return(FALSE);
if ((idwPart < 1) || (idwPart > lpData->lpplxheadpart->rgxheadpart[iHeading].dwParts))
return (FALSE);
if (LpstzUpdateString (&(lpData->lpplxheadpart->rgxheadpart[iHeading+idwPart].lpstz),
lpsz, FALSE) == NULL)
return(FALSE);
OfficeDirtyDSIObj (lpDSIObj, TRUE);
return (TRUE);
}
// Remove one (existing) Document Part by heading.
//
// Parameters:
//
// lpDSIObj - pointer to Document Summary Info object
// idwPart - 1-based index of Document part
// idwHeading - 1-based index of Heading
// lpszHeading - name of Heading
//
// If lpszHeading is non-null, this value will be used to look up
// the heading. Otherwise idwHeading will be used.
//
// Return value:
//
// The function returns TRUE on success.
// The function returns FALSE on error.
//
// Note: idwPart is interpreted as a relative position for a given heading.
// See figure 1 above.
//
// Note: The count for the Heading will be adjusted on success.
DLLEXPORT BOOL FDocSumDeleteDocPart (LPDSIOBJ lpDSIObj, DWORD idwPart,
DWORD idwHeading, LPSTR lpszHeading)
{
SHORT iHeading;
if ((lpDocObj == NULL) ||
(lpData == NULL))
return(FALSE);
AssertSz ((lpData->lpplxheadpart!= NULL), "lpData->lpplxheadpart cannot be NULL because lpData->dwcTotParts > 0");
iHeading = IGetHeadingIndex(idwHeading, lpszHeading, lpDSIObj);
if (iHeading == -1)
return(FALSE);
if ((idwPart < 1) || (idwPart > lpData->lpplxheadpart->rgxheadpart[iHeading].dwParts))
return (FALSE);
if (FFreeHeadPart(lpData->lpplxheadpart,(SHORT)(iHeading+idwPart)))
{
lpData->dwcTotParts--;
lpData->lpplxheadpart->rgxheadpart[iHeading].dwParts -= 1;
OfficeDirtyDSIObj (lpDSIObj, TRUE);
return (TRUE);
}
return (FALSE);
}
// Insert a Document Part at the given location for a given Heading.
//
// Parameters:
//
// lpDSIObj - pointer to Document Summary Info object
// idwPart - 1-based index of Document part to insert at
// 1 <= idwPart <= FCDocSumDocPartsByHeading(...)+1
// idwPart = FCDocSumDocPartsByHeading(...)+1 will append a Document Part
// idwHeading - 1-based index of Heading
// lpszHeading - name of Heading
// lpsz - buffer containing new Document Part
//
// If lpszHeading is non-null, this value will be used to look up
// the heading. Otherwise idwHeading will be used.
//
// Note: If the Heading doesn't exist, the heading will be created and inserted
// at idwHeading. In this case lpszHeading should contain the heading name.
// idwPart will be ignored, and the docpart will be added as the first docpart
// for the heading.
//
// Return value:
//
// The function returns TRUE on success.
// The function returns FALSE on error.
//
// Note: idwPart is interpreted as an absolute position into the list of parts.
// See figure 3 above.
//
// Note: The count for the Heading will be adjusted on success.
//
DLLEXPORT BOOL FDocSumInsertDocPart (LPDSIOBJ lpDSIObj, DWORD idwPart,
DWORD idwHeading, LPSTR lpszHeading,LPSTR lpsz)
{
SHORT iHeading;
XHEADPART xheadpart;
if ((lpDocObj == NULL) ||
(lpData == NULL))
return(FALSE);
iHeading = IGetHeadingIndex(idwHeading, lpszHeading, lpDSIObj);
if (iHeading == -1)
{
// They should give us at least a null-string
if (lpszHeading == NULL)
return(FALSE);
// Find the place where to insert the heading
iHeading = IGetHeadingInsertIndex(idwHeading, lpDSIObj);
if (iHeading == -1)
return(FALSE);
// Create and insert the heading
xheadpart.lpstz = NULL;
xheadpart.lpstz = LpstzUpdateString(&(xheadpart.lpstz), lpszHeading, FALSE);
if (xheadpart.lpstz == NULL)
return(FALSE);
xheadpart.fHeading = TRUE;
xheadpart.dwParts = 1;
xheadpart.iHeading = 0;
if (IAddNewPlPos(&(lpData->lpplxheadpart), &xheadpart, sizeof(XHEADPART), iHeading) == -1)
{
VFreeMemP(xheadpart.lpstz, CBBUF(xheadpart.lpstz));
return FALSE;
}
// Create and insert the document part
xheadpart.lpstz = NULL;
xheadpart.lpstz = LpstzUpdateString(&(xheadpart.lpstz), lpsz, FALSE);
if (xheadpart.lpstz == NULL)
{
Error:
FFreeHeadPart(lpData->lpplxheadpart,iHeading);
return(FALSE);
}
xheadpart.fHeading = FALSE;
xheadpart.dwParts = 0;
xheadpart.iHeading = iHeading;
if (IAddNewPlPos(&(lpData->lpplxheadpart), &xheadpart, sizeof(XHEADPART), iHeading+1) == -1)
{
VFreeMemP(xheadpart.lpstz, CBBUF(xheadpart.lpstz));
goto Error;
}
lpData->dwcTotParts++;
lpData->dwcTotHead++;
return TRUE;
}
// The heading already exists
if ((idwPart < 1) || (idwPart > lpData->lpplxheadpart->rgxheadpart[iHeading].dwParts+1))
return (FALSE);
xheadpart.lpstz = NULL;
xheadpart.lpstz = LpstzUpdateString(&(xheadpart.lpstz),lpsz, FALSE);
if (xheadpart.lpstz == NULL)
return(FALSE);
xheadpart.fHeading = FALSE;
xheadpart.dwParts = 0;
xheadpart.iHeading = iHeading;
if (IAddNewPlPos(&(lpData->lpplxheadpart), &xheadpart, sizeof(XHEADPART), iHeading+idwPart) == -1)
{
VFreeMemP(xheadpart.lpstz, CBBUF(xheadpart.lpstz));
return(FALSE);
}
lpData->dwcTotParts++;
lpData->lpplxheadpart->rgxheadpart[iHeading].dwParts += 1;
OfficeDirtyDSIObj (lpDSIObj, TRUE);
return(TRUE);
}
////////////////////////////////////////////////////////////////////////////////
//
// CDocSumHeadingPairs
//
// Purpose:
// Get the number of heading pairs
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL
FCDocSumHeadingPairs
(LPDSIOBJ lpDSIObj, // Pointer to object
DWORD *pdw)
{
if ((lpDocObj == NULL) ||
(lpData == NULL))
return FALSE;
*pdw = lpData->dwcTotHead;
return TRUE;
} // CDocSumHeadingPairs
////////////////////////////////////////////////////////////////////////////////
//
// CbDocSumHeadingPair
//
// Purpose:
// Get the size of one heading string
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL
FCbDocSumHeadingPair
(LPDSIOBJ lpDSIObj, // Pointer to object
DWORD idwHeading, // Index of heading pair
DWORD *pdw)
{
SHORT iHeading;
if ((lpDocObj == NULL) ||
(lpData == NULL) ||
(idwHeading < 1) ||
(idwHeading > lpData->dwcTotHead))
return FALSE;
AssertSz ((lpData->lpplxheadpart != NULL), "lpData->lpplxheadpart cannot be NULL because lpData->dwcTotHead > 0");
iHeading = IMapHeadingIndex(idwHeading, lpData->lpplxheadpart);
if (iHeading == -1)
return FALSE;
*pdw = CBSTR (lpData->lpplxheadpart->rgxheadpart[iHeading].lpstz);
return TRUE;
} // CbDocSumHeadingPair
////////////////////////////////////////////////////////////////////////////////
//
// LpszDocSumGetHeadingPair
//
// Purpose:
// Get one heading string. dwcParts will be set to the number of parts for the
// heading.
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT LPSTR
LpszDocSumGetHeadingPair
(LPDSIOBJ lpDSIObj, // Pointer to object
DWORD idwHeading, // Index of heading pair
LPSTR lpszHeading, // Name of heading to look up
DWORD cbMax, // Max size of lpsz
LPSTR lpsz, // Buffer to put heading in
DWORD *pdwcParts) // Number of sections for heading
{
SHORT iHeading;
DWORD cb;
if ((lpDocObj == NULL) ||
(lpData == NULL))
return NULL;
iHeading = IGetHeadingIndex(idwHeading & ~PTRWIZARD, lpszHeading, lpDSIObj);
if (iHeading == -1)
return NULL;
AssertSz ((PTRWIZARD > lpData->dwcTotHead), "We've got way more heading parts than ever expected!");
AssertSz ((lpData->lpplxheadpart != NULL), "lpData->lpplxheadpart cannot be NULL because lpData->dwcTotHead > 0");
if (idwHeading & PTRWIZARD)
{
*pdwcParts = lpData->lpplxheadpart->rgxheadpart[iHeading & ~PTRWIZARD].dwParts;
return PSTR (lpData->lpplxheadpart->rgxheadpart[iHeading & ~PTRWIZARD].lpstz);
}
if (lpsz == NULL)
return(NULL);
*pdwcParts = lpData->lpplxheadpart->rgxheadpart[iHeading].dwParts;
cb = min(CBSTR (lpData->lpplxheadpart->rgxheadpart[iHeading].lpstz), cbMax-1);
if (cb > 0)
PbSzNCopy (lpsz, PSTR (lpData->lpplxheadpart->rgxheadpart[iHeading].lpstz), cb);
lpsz[cb] = '\0';
return lpsz;
} // LpszDocSumGetHeadingPair
////////////////////////////////////////////////////////////////////////////////
//
// FDocSumSetHeadingPair
//
// Purpose:
// Set one heading pair
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL
FDocSumSetHeadingPair
(LPDSIOBJ lpDSIObj, // Pointer to object
DWORD idwHeading, // Index of heading pair
LPSTR lpszHeading, // Name of heading to look up
LPSTR lpsz) // The heading
{
SHORT iHeading;
if ((lpDocObj == NULL) ||
(lpData == NULL))
return FALSE;
iHeading = IGetHeadingIndex(idwHeading, lpszHeading, lpDSIObj);
if (iHeading == -1)
return FALSE;
AssertSz ((lpData->lpplxheadpart != NULL), "lpData->lpplxheadpart cannot be NULL because lpData->dwcTotHead > 0");
lpData->lpplxheadpart->rgxheadpart[iHeading].lpstz =
LpstzUpdateString(&(lpData->lpplxheadpart->rgxheadpart[iHeading].lpstz), lpsz, FALSE);
if (lpData->lpplxheadpart->rgxheadpart[iHeading].lpstz == NULL)
return(FALSE);
OfficeDirtyDSIObj (lpDSIObj, TRUE);
return TRUE;
} // FDocSumSetHeadingPair
////////////////////////////////////////////////////////////////////////////////
//
// FDocSumDeleteHeadingPair
//
// Purpose:
// Delete a heading pair
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL
FDocSumDeleteHeadingPair
(LPDSIOBJ lpDSIObj, // Pointer to object
DWORD idwHeading, // Index of heading to delete
LPSTR lpszHeading) // Name of heading to delete
{
SHORT iHeading;
DWORD cParts,i;
if ((lpDocObj == NULL) ||
(lpData == NULL) ||
(lpData->dwcTotHead == 0))
return FALSE;
iHeading = IGetHeadingIndex(idwHeading, lpszHeading, lpDSIObj);
if (iHeading == -1)
return FALSE;
AssertSz ((lpData->lpplxheadpart != NULL), "lpData->lpplxheadpart cannot be NULL because lpData->dwcTotHead > 0");
cParts = lpData->lpplxheadpart->rgxheadpart[iHeading].dwParts;
if (!FFreeHeadPart(lpData->lpplxheadpart, iHeading))
return(FALSE);
for (i = 0; i < cParts; ++i) // Keep passing iHeading, since elements in
FFreeHeadPart(lpData->lpplxheadpart,iHeading); // plex move up as elements are deleted
lpData->dwcTotParts -= cParts;
lpData->dwcTotHead--;
OfficeDirtyDSIObj (lpDSIObj, TRUE);
return TRUE;
} // FDocSumDeleteHeadingPair
////////////////////////////////////////////////////////////////////////////////
//
// Clear the contents data
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL FDocSumDeleteAllHeadingPair (LPDSIOBJ lpDSIObj)
{
if ((lpDocObj == NULL) || (lpData == NULL))
return(FALSE);
if (lpData->lpplxheadpart == NULL)
return(TRUE);
FreeHeadPartPlex(lpDSIObj);
return(TRUE);
}
////////////////////////////////////////////////////////////////////////////////
//
// FDocSumInsertHeadingPair
//
// Purpose:
// Insert a heading pair at the given location
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL
FDocSumInsertHeadingPair
(LPDSIOBJ lpDSIObj, // Pointer to object
DWORD idwHeading, // Index of heading to insert at
LPSTR lpszHeadingBefore, // Name of heading to insert before
LPSTR lpszNewHeading) // Heading string
{
SHORT iHeading;
XHEADPART xheadpart;
if ((lpDocObj == NULL) ||
(lpData == NULL))
return FALSE;
iHeading = IGetHeadingIndex(idwHeading, lpszHeadingBefore, lpDSIObj);
if (iHeading == -1)
{
// They should give us at least a null-string
if (lpszNewHeading == NULL)
return(FALSE);
// Find the place where to insert the heading
iHeading = IGetHeadingInsertIndex(idwHeading, lpDSIObj);
if (iHeading == -1)
return(FALSE);
}
// Create and insert the heading
xheadpart.lpstz = NULL;
xheadpart.lpstz = LpstzUpdateString(&(xheadpart.lpstz), lpszNewHeading, FALSE);
if (xheadpart.lpstz == NULL)
return(FALSE);
xheadpart.fHeading = TRUE;
xheadpart.dwParts = 0;
xheadpart.iHeading = 0;
if (IAddNewPlPos(&(lpData->lpplxheadpart), &xheadpart, sizeof(XHEADPART), iHeading) == -1)
{
VFreeMemP(xheadpart.lpstz, CBBUF(xheadpart.lpstz));
return FALSE;
}
lpData->dwcTotHead++;
OfficeDirtyDSIObj (lpDSIObj, TRUE);
return TRUE;
} // FDocSumInsertHeadingPair
////////////////////////////////////////////////////////////////////////////////
//
// DwDocSumGetInt
//
// Purpose:
// Get the int stat property
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL
FDwDocSumGetInt
(LPDSIOBJ lpDSIObj, // Pointer to object
WORD iw, // Index of int stat to get
DWORD *pdw)
{
if ((lpDocObj == NULL) ||
(lpData == NULL) ||
(iw < DSI_BYTES) ||
(iw > DSI_INTLAST))
return FALSE;
if (!FDocSumInfoPropBitIsSet(rglIIDtoPID[iw], lpData->bPropSet))
return(FALSE);
*pdw = lpData->rgdw[rglIIDtoPID[iw]];
return TRUE;
} // DwDocSumGetInt
////////////////////////////////////////////////////////////////////////////////
//
// FDocSumSetInt
//
// Purpose:
// Set the int stat property
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL
FDocSumSetInt
(LPDSIOBJ lpDSIObj, // Pointer to object
WORD iw, // Index of int stat to set
DWORD dw) // New value
{
if ((lpDocObj == NULL) ||
(lpData == NULL) ||
(iw < DSI_BYTES) ||
(iw > DSI_INTLAST))
return FALSE;
lpData->rgdw[rglIIDtoPID[iw]] = dw;
VDocSumInfoSetPropBit(rglIIDtoPID[iw], &lpData->bPropSet);
OfficeDirtyDSIObj (lpDSIObj, TRUE);
return TRUE;
} // FDocSumSetInt
//
// VDocSumInfoSetPropBit
//
// Set the bit that indicates that a filetime has been set/loaded
//
VOID PASCAL VDocSumInfoSetPropBit(LONG pid, BYTE *pbPropSet)
{
switch (pid)
{
case PID_BYTECOUNT:
*pbPropSet |= bByteCount;
break;
case PID_LINECOUNT:
*pbPropSet |= bLineCount;
break;
case PID_PARACOUNT:
*pbPropSet |= bParCount;
break;
case PID_SLIDECOUNT:
*pbPropSet |= bSlideCount;
break;
case PID_NOTECOUNT:
*pbPropSet |= bNoteCount;
break;
case PID_HIDDENCOUNT:
*pbPropSet |= bHiddenCount;
break;
case PID_MMCLIPCOUNT:
*pbPropSet |= bMMClipCount;
break;
// Can get here from some of the vector stuff
default:
break;
}
}
//
// FDocSumInfoPropBitIsSet
//
// Check the bit that indicates that a filetime has been set/loaded
//
BOOL PASCAL FDocSumInfoPropBitIsSet(LONG pid, BYTE bPropSet)
{
switch (pid)
{
case PID_BYTECOUNT:
return(bPropSet & bByteCount);
break;
case PID_LINECOUNT:
return(bPropSet & bLineCount);
break;
case PID_PARACOUNT:
return(bPropSet & bParCount);
break;
case PID_SLIDECOUNT:
return(bPropSet & bSlideCount);
break;
case PID_NOTECOUNT:
return(bPropSet & bNoteCount);
break;
case PID_HIDDENCOUNT:
return(bPropSet & bHiddenCount);
break;
case PID_MMCLIPCOUNT:
return(bPropSet & bMMClipCount);
break;
default:
return(FALSE);
break;
}
}
////////////////////////////////////////////////////////////////////////////////
//
// FDocSumGetScalability
//
// Purpose:
// Get the "scalability" property, true when scaling, false when cropping
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL
FDocSumGetScalability
(LPDSIOBJ lpDSIObj) // Pointer to object
{
if ((lpDocObj == NULL) ||
(lpData == NULL))
return FALSE;
return (lpData->fScale);
} // FDocSumGetScalability
////////////////////////////////////////////////////////////////////////////////
//
// FDocSumIsScalable
//
// Purpose:
// Determine if the object has the scalable property
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL
FDocSumIsScalable
(LPDSIOBJ lpDSIObj) // Pointer to object
{
if ((lpDocObj == NULL) ||
(lpData == NULL))
return FALSE;
return (lpData->fScale == TRUE);
} // FDocSumIsScalable
////////////////////////////////////////////////////////////////////////////////
//
// FDocSumIsCroppable
//
// Purpose:
// Determine if the object has the croppable property
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL
FDocSumIsCroppable
(LPDSIOBJ lpDSIObj) // Pointer to object
{
if ((lpDocObj == NULL) ||
(lpData == NULL))
return FALSE;
return (lpData->fScale != TRUE);
} // FDocSumIsCroppable
////////////////////////////////////////////////////////////////////////////////
//
// FDocSumSetScalability
//
// Purpose:
// Set the "scalability" property
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL
FDocSumSetScalability
(LPDSIOBJ lpDSIObj, // Pointer to object
BOOL fScalable) // New scalability value
{
if ((lpDocObj == NULL) ||
(lpData == NULL))
return FALSE;
lpData->fScale = fScalable;
OfficeDirtyDSIObj (lpDSIObj, TRUE);
return TRUE;
} // FDocSumSetScalability
////////////////////////////////////////////////////////////////////////////////
//
// FLinkValsChanged
//
// Purpose:
// Determine if the link values changed
//
////////////////////////////////////////////////////////////////////////////////
DLLEXPORT BOOL
FLinkValsChanged
(LPDSIOBJ lpDSIObj) // Pointer to object
{
BOOL f;
if ((lpDocObj == NULL) ||
(lpData == NULL))
return FALSE;
f = lpData->fLinksChanged;
lpData->fLinksChanged = FALSE;
return(f);
} // FLinkValsChanged