1852 lines
50 KiB
C
1852 lines
50 KiB
C
/************************************************************/
|
||
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
|
||
/************************************************************/
|
||
|
||
#include "windows.h"
|
||
#include "mw.h"
|
||
#include "winddefs.h"
|
||
#include "docdefs.h"
|
||
#include "propdefs.h"
|
||
#include "editdefs.h"
|
||
#include "filedefs.h"
|
||
#include "cmddefs.h"
|
||
#include "obj.h"
|
||
#include "str.h"
|
||
#include "objreg.h"
|
||
#include <commdlg.h>
|
||
#include <stdlib.h> // for strtoul()
|
||
|
||
extern struct CHP vchpNormal;
|
||
extern struct DOD (**hpdocdod)[];
|
||
extern BOOL ferror;
|
||
extern struct PAP vpapAbs;
|
||
extern struct PAP vpapPrevIns;
|
||
extern struct PAP *vppapNormal;
|
||
extern int vdocParaCache;
|
||
extern struct UAB vuab;
|
||
extern int vfOutOfMemory,vfSysFull;
|
||
extern int docUndo;
|
||
extern struct FCB (**hpfnfcb)[];
|
||
extern HCURSOR vhcArrow;
|
||
|
||
/* intercepted stream functions work with this buffer */
|
||
static typeCP cpObjectDataCurLoc=cp0, cpObjectDataBase=cp0;
|
||
static DWORD cObjectData=0L,dwDataMax;
|
||
static int docStream;
|
||
static struct CHP *pchpStream;
|
||
static struct PAP *ppapStream;
|
||
|
||
static OPENFILENAME OFN;
|
||
|
||
static void GetChp(struct CHP *pchp, typeCP cp, int doc);
|
||
static BOOL ObjParaDup(int doc, typeCP cpFirst, typeCP cpLim);
|
||
static BOOL bUniqueData(int doc, typeCP cpFirst, typeCP cpLim);
|
||
static ObjOpenStreamIO(typeCP cpParaStart, int doc, struct CHP *pchp, struct PAP *ppapGraph, DWORD dwObjectSize);
|
||
static void ObjCloseStreamIO(void);
|
||
static typeCP ObjWriteDataToDoc( LPOLEOBJECT lpObject);
|
||
static HANDLE OfnGetNewLinkName(HWND hwnd, HANDLE hData);
|
||
static void Normalize(LPSTR lpstrFile) ;
|
||
static HANDLE ObjMakeNewLinkName(HANDLE hData, ATOM atom) ;
|
||
static char szCustFilterSpec[CBFILTERMAX];
|
||
static char szFileName[CBPATHMAX];
|
||
//static char szFilterSpec[CBFILTERMAX];
|
||
//static char szLastDir[CBPATHMAX];
|
||
static char szLinkCaption[cchMaxSz];
|
||
static char szTemplateName[CBPATHMAX];
|
||
static BOOL fUpdateAll = FALSE;
|
||
static BOOL ObjStop=FALSE;
|
||
static BOOL vbChangeOther;
|
||
BOOL bNoEol=FALSE;
|
||
|
||
#define ulmin(a,b) ((DWORD)(a) < (DWORD)(b) ? \
|
||
(WORD)(a) : (WORD)(b))
|
||
|
||
|
||
/****************************************************************/
|
||
/**************** OLE ENUMERATION FUNCTIONS *********************/
|
||
/****************************************************************/
|
||
|
||
#if 0 // good, just not used
|
||
int
|
||
ObjEnumInAllDocs(cpFARPROC lpFunc)
|
||
{
|
||
int doc,count=0;
|
||
for (doc = 0; doc < docMac; doc++)
|
||
{
|
||
int nRetval;
|
||
|
||
nRetval = ObjEnumInDoc(doc, lpFunc);
|
||
|
||
if (nRetval < 0)
|
||
return -1;
|
||
else
|
||
count += nRetval;
|
||
}
|
||
return count;
|
||
}
|
||
#endif
|
||
|
||
int
|
||
ObjEnumInDoc(int doc, cpFARPROC lpFunc)
|
||
{
|
||
typeCP cpMac = (**hpdocdod) [doc].cpMac;
|
||
|
||
return ObjEnumInRange(doc, cp0, cpMac, lpFunc);
|
||
}
|
||
|
||
|
||
int
|
||
ObjEnumInRange(int doc, typeCP cpStart, typeCP cpEnd, cpFARPROC lpFunc)
|
||
/* Call lpFunc for each OLE object.
|
||
lpFunc takes the following args:
|
||
a far pointer to a PICINFOX struct (can be NULL).
|
||
an int for the doc we're operating on.
|
||
a typeCP that gives the cp position of the PICINFOX struct.
|
||
lpFunc returns the cp of the paragraph following the PICINFO struct
|
||
if OK, or cp0 if error.
|
||
Enumeration quits if error returned from FARPROC.
|
||
Return number of objects operated on, or -1 if error.
|
||
*/
|
||
{
|
||
typeCP cpNow, cpLimPara;
|
||
int count;
|
||
|
||
/* Loop on paras */
|
||
|
||
for ( count = 0, cpNow = cpStart; cpNow < cpEnd; cpNow = cpLimPara )
|
||
{
|
||
|
||
Assert(cpEnd <= (**hpdocdod) [doc].cpMac);
|
||
|
||
/* this shouldn't happen */
|
||
if (cpEnd > (**hpdocdod) [doc].cpMac)
|
||
goto done;
|
||
|
||
ObjCachePara( doc, cpNow );
|
||
|
||
if (vpapAbs.fGraphics)
|
||
{
|
||
/* get PICINFO struct and see if its an object */
|
||
OBJPICINFO picInfo;
|
||
GetPicInfo(vcpFirstParaCache,vcpFirstParaCache + cchPICINFOX, doc, &picInfo);
|
||
if (bOBJ_QUERY_IS_OBJECT(&picInfo))
|
||
{
|
||
typeCP cpOldLimPara = vcpLimParaCache;
|
||
|
||
if (!lpFunc)
|
||
cpLimPara = vcpLimParaCache;
|
||
else
|
||
if ((cpLimPara = (*lpFunc)(&picInfo,doc,vcpFirstParaCache)) == 0)
|
||
goto error;
|
||
|
||
++count;
|
||
|
||
/* amount para has grown ( < 0 if shrunk, 0 if none )*/
|
||
cpEnd += cpLimPara - cpOldLimPara;
|
||
|
||
continue;
|
||
}
|
||
}
|
||
|
||
cpLimPara = vcpLimParaCache;
|
||
}
|
||
|
||
/* success */
|
||
goto done;
|
||
|
||
error:
|
||
count = -1;
|
||
|
||
done:
|
||
|
||
return count;
|
||
}
|
||
|
||
ObjPicEnumInRange(OBJPICINFO *pPicInfo,int doc, typeCP cpFirst, typeCP cpLim, typeCP *cpCur)
|
||
/*
|
||
Enumerate over PicInfos between cpFirst and cpLim in doc. If
|
||
cpCur == cpNil, then start at cpFirst, else start at *cpCur.
|
||
Return 0 if done, 1 otherwise.
|
||
Calls ObjCachePara() at picInfo.
|
||
*/
|
||
{
|
||
/* static typeCP cpCur;
|
||
used to use static, but that prevented being able to recursively
|
||
call this function, and its almost impossible to prevent with
|
||
asynchronicity rampant.
|
||
*/
|
||
|
||
typeCP cpMac = (**hpdocdod) [doc].cpMac;
|
||
|
||
if (cpFirst >= cpMac)
|
||
return 0;
|
||
|
||
if (cpLim > cpMac)
|
||
cpLim = cpMac;
|
||
|
||
/* initialize cpCur */
|
||
if (*cpCur == cpNil)
|
||
/* then starting afresh */
|
||
*cpCur = cpFirst;
|
||
else
|
||
{
|
||
ObjCachePara(doc,*cpCur); // cache the previous para
|
||
*cpCur = vcpLimParaCache; // get next para
|
||
}
|
||
|
||
/* pull in next para */
|
||
do
|
||
{
|
||
if (*cpCur >= cpLim)
|
||
{
|
||
/* all done */
|
||
*cpCur = vcpFirstParaCache; // we want to point to last para hit
|
||
return 0;
|
||
}
|
||
|
||
ObjCachePara(doc,*cpCur);
|
||
|
||
if (vpapAbs.fGraphics)
|
||
{
|
||
GetPicInfo(*cpCur,*cpCur + cchPICINFOX, doc, pPicInfo);
|
||
if (bOBJ_QUERY_IS_OBJECT(pPicInfo))
|
||
return 1;
|
||
}
|
||
*cpCur = vcpLimParaCache;
|
||
}
|
||
while (1);
|
||
}
|
||
|
||
typeCP ObjSaveObjectToDoc(OBJPICINFO *pPicInfo,int doc,typeCP cpParaStart)
|
||
/*
|
||
Assumes para is cached.
|
||
In some cases we only write the picinfo. In others we write the
|
||
object data after the picinfo. We assume that the latter case
|
||
only occurs when the file is being saved.
|
||
*/
|
||
{
|
||
typeCP cpRetval; // cp of next byte in doc after what we just wrote
|
||
static BOOL bMyRecurse=FALSE;
|
||
DWORD dwObjectSize;
|
||
OLESTATUS olestat;
|
||
struct CHP chp;
|
||
struct PAP papGraph;
|
||
|
||
if (lpOBJ_QUERY_INFO(pPicInfo) == NULL)
|
||
return(cp0);
|
||
|
||
if (lpOBJ_QUERY_OBJECT(pPicInfo) == NULL)
|
||
return(vcpLimParaCache);
|
||
|
||
/* we don't save nothing if it ain't dirty and has data */
|
||
if (!fOBJ_QUERY_DIRTY_OBJECT(pPicInfo) &&
|
||
dwOBJ_QUERY_DATA_SIZE(pPicInfo) != 0L)
|
||
return(vcpLimParaCache);
|
||
|
||
if (vfOutOfMemory || vfSysFull /*|| ObjStop*/)
|
||
return cp0;
|
||
|
||
olestat = OleQuerySize(lpOBJ_QUERY_OBJECT(pPicInfo),&dwObjectSize);
|
||
|
||
if (olestat == OLE_ERROR_BLANK)
|
||
dwObjectSize = 0L;
|
||
else if (ObjError(olestat))
|
||
return cp0;
|
||
|
||
/** don't let this function recurse (in CallBack) **/
|
||
if (bMyRecurse)
|
||
{
|
||
Assert(0); // this has never happened yet (8.21.91) v-dougk
|
||
return cp0;
|
||
}
|
||
bMyRecurse = TRUE;
|
||
|
||
fOBJ_QUERY_DIRTY_OBJECT(pPicInfo) = FALSE;
|
||
|
||
/**
|
||
If docUndo will want to undo some region that contains this
|
||
object, and if saving the object changes the size of that
|
||
region, then vuab will become obsolete.
|
||
**/
|
||
|
||
ObjWriteClearState(doc);
|
||
|
||
GetChp(&chp, cpParaStart, doc);
|
||
|
||
if (dwOBJ_QUERY_DATA_SIZE(pPicInfo) != 0xFFFFFFFF)
|
||
/* then has been saved before */
|
||
{
|
||
/* zap the entire existing object */
|
||
papGraph = vpapAbs;
|
||
Replace(doc, cpParaStart, (vcpLimParaCache - vcpFirstParaCache), fnNil, fc0, fc0);
|
||
}
|
||
else // new object
|
||
{
|
||
ObjCachePara(doc,cpParaStart-1); // use previous PAP
|
||
papGraph = vpapAbs;
|
||
papGraph.fGraphics = TRUE;
|
||
ObjCachePara(doc,cpParaStart);
|
||
}
|
||
|
||
if (otOBJ_QUERY_TYPE(pPicInfo) == NONE)
|
||
{
|
||
if (dwObjectSize)
|
||
/*
|
||
Insert New has culminated in a new baby object!
|
||
*/
|
||
{
|
||
otOBJ_QUERY_TYPE(pPicInfo) = EMBEDDED; // do this first
|
||
if (!FComputePictSize(pPicInfo, &(pPicInfo->dxaSize), &(pPicInfo->dyaSize)))
|
||
{
|
||
cpRetval = cp0;
|
||
goto end;
|
||
}
|
||
#if 0
|
||
DeleteAtom(aOBJ_QUERY_SERVER_CLASS(pPicInfo));
|
||
aOBJ_QUERY_SERVER_CLASS(pPicInfo) = NULL;
|
||
#endif
|
||
}
|
||
else // don't save empty object
|
||
{
|
||
Assert(0);
|
||
goto end;
|
||
}
|
||
}
|
||
|
||
#ifdef DEBUG
|
||
OutputDebugString( (LPSTR) "Saving object\n\r");
|
||
#endif
|
||
|
||
/*
|
||
Insert PICINFO struct. There is a problem here which is a
|
||
bug in Write (CheckGraphic()). EOL gets inserted when we are
|
||
replacing an object which is immediately in front of
|
||
another object. Kludge is to set this flag to inhibit.
|
||
*/
|
||
bNoEol = TRUE;
|
||
|
||
if (bOBJ_QUERY_DONT_SAVE_DATA(pPicInfo))
|
||
/* only save picinfo until user does File.Save */
|
||
{
|
||
ObjUpdateFromObjInfo(pPicInfo);
|
||
|
||
bOBJ_QUERY_DONT_SAVE_DATA(pPicInfo) = FALSE;
|
||
dwOBJ_QUERY_DATA_SIZE(pPicInfo) = 0L;
|
||
|
||
pPicInfo->mm |= MM_EXTENDED; /* Extended file format */
|
||
InsertRgch( doc, cpParaStart, pPicInfo, sizeof(OBJPICINFO), &chp, &papGraph);
|
||
pPicInfo->mm &= ~MM_EXTENDED;
|
||
|
||
ObjCachePara(doc,cpParaStart);
|
||
cpRetval = vcpLimParaCache;
|
||
}
|
||
else
|
||
{
|
||
dwOBJ_QUERY_DATA_SIZE(pPicInfo) = dwObjectSize;
|
||
ObjUpdateFromObjInfo(pPicInfo);
|
||
|
||
pPicInfo->mm |= MM_EXTENDED; /* Extended file format */
|
||
InsertRgch( doc, cpParaStart, pPicInfo, sizeof(OBJPICINFO), &chp, NULL );
|
||
pPicInfo->mm &= ~MM_EXTENDED;
|
||
|
||
/* insert object data into doc */
|
||
ObjOpenStreamIO(cpParaStart + cchPICINFOX, doc, &chp, &papGraph, dwObjectSize);
|
||
cpRetval = ObjWriteDataToDoc(lpOBJ_QUERY_OBJECT(pPicInfo));
|
||
ObjCloseStreamIO();
|
||
}
|
||
|
||
bNoEol = FALSE;
|
||
|
||
end:
|
||
|
||
ObjCachePara(doc,cpParaStart);
|
||
|
||
bMyRecurse = FALSE;
|
||
return ((cpRetval == cp0) ? cp0 : vcpLimParaCache);
|
||
}
|
||
|
||
typeCP ObjLoadObjectInDoc(OBJPICINFO *pPicInfo,int doc,typeCP cpParaStart)
|
||
/*
|
||
Do an OleLoad from object data in doc. Set lpobject in PICINFO struct.
|
||
Assumes para is cached.
|
||
This is a *synchronous* function.
|
||
*/
|
||
{
|
||
typeCP cpRetval = vcpLimParaCache;
|
||
szOBJNAME szObjName;
|
||
|
||
if (lpOBJ_QUERY_INFO(pPicInfo) == NULL)
|
||
{
|
||
if (ObjAllocObjInfo(pPicInfo,cpParaStart,pPicInfo->objectType,FALSE,NULL))
|
||
return(cp0);
|
||
|
||
if (ObjSetPicInfo(pPicInfo, doc, cpParaStart))
|
||
return(cp0);
|
||
}
|
||
|
||
else if (lpOBJ_QUERY_OBJECT(pPicInfo)) // already loaded
|
||
return(vcpLimParaCache);
|
||
|
||
if (otOBJ_QUERY_TYPE(pPicInfo) == NONE)
|
||
return(vcpLimParaCache);
|
||
|
||
if (bOBJ_QUERY_TOO_BIG(pPicInfo)) // ObjLoadObject previously failed
|
||
return(cp0);
|
||
|
||
if ((dwOBJ_QUERY_DATA_SIZE(pPicInfo) == 0L) ||
|
||
(dwOBJ_QUERY_DATA_SIZE(pPicInfo) == 0xFFFFFFFFL))
|
||
/* then has no data */
|
||
return(cp0);
|
||
|
||
if (vfOutOfMemory || vfSysFull /*|| ObjStop*/)
|
||
return cp0;
|
||
|
||
StartLongOp();
|
||
|
||
ObjGetObjectName(lpOBJ_QUERY_INFO(pPicInfo),szObjName);
|
||
|
||
Assert(szObjName[0]);
|
||
|
||
ObjOpenStreamIO(cpParaStart + cchPICINFOX, doc, NULL, NULL, 0L);
|
||
|
||
#ifdef DEBUG
|
||
OutputDebugString( (LPSTR) "Loading object\n\r");
|
||
#endif
|
||
|
||
if (ObjError(OleLoadFromStream(lpStream,
|
||
otOBJ_QUERY_TYPE(pPicInfo) == STATIC ? SPROTOCOL : PROTOCOL,
|
||
(LPOLECLIENT)lpOBJ_QUERY_INFO(pPicInfo),
|
||
lhClientDoc,szObjName,&lpOBJ_QUERY_OBJECT(pPicInfo))))
|
||
{
|
||
/* mark as unloadable to prevent infinite LoadObject loops */
|
||
bOBJ_QUERY_TOO_BIG(pPicInfo) = TRUE;
|
||
lpOBJ_QUERY_OBJECT(pPicInfo) = NULL; // just in case (OLE ain't good about this)
|
||
ferror = FALSE; // be sure to issue this message
|
||
Error(IDPMTFailedToLoadObject);
|
||
cpRetval = cp0;
|
||
goto end;
|
||
}
|
||
|
||
if (ObjInitServerInfo(lpOBJ_QUERY_INFO(pPicInfo)))
|
||
{
|
||
ferror = FALSE; // be sure to issue this message
|
||
Error(IDPMTOLEError);
|
||
goto end;
|
||
}
|
||
|
||
if (ObjUpdatePicSize(pPicInfo,cpParaStart))
|
||
if (ObjSetPicInfo(pPicInfo, doc, cpParaStart))
|
||
goto end;
|
||
|
||
ObjCachePara(doc,cpParaStart); // just in case
|
||
|
||
cpRetval = vcpLimParaCache;
|
||
|
||
end:
|
||
ObjCloseStreamIO();
|
||
EndLongOp(vhcArrow);
|
||
return cpRetval;
|
||
}
|
||
|
||
typeCP ObjEditObjectInDoc(OBJPICINFO *pPicInfo, int doc, typeCP cpParaStart)
|
||
{
|
||
typeCP cpRetval;
|
||
OBJ_PLAYEDIT = OLEVERB_PRIMARY+1;
|
||
cpRetval = ObjPlayObjectInDoc(pPicInfo, doc, cpParaStart);
|
||
OBJ_PLAYEDIT = OLEVERB_PRIMARY; // the default
|
||
return cpRetval;
|
||
}
|
||
|
||
typeCP ObjPlayObjectInDoc(OBJPICINFO *pPicInfo, int doc, typeCP cpParaStart)
|
||
{
|
||
OLESTATUS olestat;
|
||
LPOBJINFO lpOInfo=lpOBJ_QUERY_INFO(pPicInfo);
|
||
|
||
if ((otOBJ_QUERY_TYPE(pPicInfo) == STATIC) ||
|
||
(otOBJ_QUERY_TYPE(pPicInfo) == NONE))
|
||
return(vcpLimParaCache);
|
||
|
||
if (ObjMakeObjectReady(pPicInfo,doc,cpParaStart))
|
||
goto err;
|
||
|
||
fOBJ_QUERY_PLAY(pPicInfo) = OBJ_PLAYEDIT;
|
||
|
||
do
|
||
{
|
||
#ifdef DEBUG
|
||
OutputDebugString( "Opening Object\n\r");
|
||
#endif
|
||
|
||
StartLongOp();
|
||
olestat = OleActivate(lpOBJ_QUERY_OBJECT(pPicInfo),
|
||
OBJ_PLAYEDIT,
|
||
TRUE,
|
||
TRUE,
|
||
hDOCWINDOW,
|
||
NULL);
|
||
EndLongOp(vhcArrow);
|
||
|
||
switch (olestat)
|
||
{
|
||
/* check for bad link */
|
||
case OLE_ERROR_OPEN:
|
||
case OLE_ERROR_ADVISE_NATIVE:
|
||
case OLE_ERROR_ADVISE_PICT:
|
||
case OLE_ERROR_REQUEST_NATIVE:
|
||
case OLE_ERROR_REQUEST_PICT:
|
||
|
||
fOBJ_BADLINK(pPicInfo) = TRUE;
|
||
if (bLinkProps)
|
||
{
|
||
Error(IDPMTLinkUnavailable);
|
||
goto err;
|
||
}
|
||
else
|
||
{
|
||
ObjCachePara(doc,cpParaStart);
|
||
if (!FixInvalidLink(pPicInfo,doc,cpParaStart))
|
||
goto err;
|
||
olestat = OLE_OK;
|
||
lpOInfo->fCompleteAsync = TRUE; // cancel OleSetData (FixInvalid) as well
|
||
if (ObjWaitForObject(lpOInfo,TRUE))
|
||
goto err;
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (ObjError(olestat))
|
||
goto err;
|
||
else
|
||
break;
|
||
}
|
||
while (1);
|
||
|
||
fOBJ_BADLINK(pPicInfo) = FALSE; // can't be bad if succeeded
|
||
//(**hpdocdod) [doc].fDirty = TRUE; // assume dirty is opened.
|
||
ObjCachePara(doc,cpParaStart); // just in case
|
||
return(vcpLimParaCache);
|
||
|
||
err:
|
||
Error(IDPMTFailedToActivate);
|
||
return cp0;
|
||
}
|
||
|
||
typeCP ObjUpdateObjectInDoc(OBJPICINFO *pPicInfo, int doc, typeCP cpParaStart)
|
||
{
|
||
int xSize,ySize;
|
||
BOOL bUpdate = FALSE;
|
||
OLESTATUS olestat;
|
||
|
||
if (lpOBJ_QUERY_INFO(pPicInfo) == NULL)
|
||
return(cp0);
|
||
|
||
if ((otOBJ_QUERY_TYPE(pPicInfo) == STATIC) ||
|
||
(otOBJ_QUERY_TYPE(pPicInfo) == NONE))
|
||
return(vcpLimParaCache);
|
||
|
||
if (bLinkProps && bOBJ_WAS_UPDATED(pPicInfo))
|
||
return(vcpLimParaCache);
|
||
|
||
if (ObjMakeObjectReady(pPicInfo,doc,cpParaStart))
|
||
goto err;
|
||
|
||
do
|
||
{
|
||
#ifdef DEBUG
|
||
OutputDebugString( "Updating Object\n\r");
|
||
#endif
|
||
|
||
StartLongOp();
|
||
olestat = OleUpdate(lpOBJ_QUERY_OBJECT(pPicInfo));
|
||
EndLongOp(vhcArrow);
|
||
|
||
switch (olestat)
|
||
{
|
||
/* check for bad link */
|
||
case OLE_ERROR_OPEN:
|
||
case OLE_ERROR_ADVISE_NATIVE:
|
||
case OLE_ERROR_ADVISE_PICT:
|
||
case OLE_ERROR_REQUEST_NATIVE:
|
||
case OLE_ERROR_REQUEST_PICT:
|
||
|
||
fOBJ_BADLINK(pPicInfo) = TRUE;
|
||
if (bLinkProps)
|
||
{
|
||
Error(IDPMTLinkUnavailable);
|
||
goto err;
|
||
}
|
||
else
|
||
{
|
||
ObjCachePara(doc,cpParaStart);
|
||
if (!FixInvalidLink(pPicInfo,doc,cpParaStart))
|
||
goto err;
|
||
olestat = OLE_OK;
|
||
lpOBJ_QUERY_INFO(pPicInfo)->fCompleteAsync = TRUE; // cancel OleSetData (FixInvalid) as well
|
||
if (ObjWaitForObject(lpOBJ_QUERY_INFO(pPicInfo),TRUE))
|
||
goto err;
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (ObjError(olestat))
|
||
goto err;
|
||
else
|
||
break;
|
||
}
|
||
while (1);
|
||
|
||
ObjCachePara(doc,cpParaStart); // just in case
|
||
|
||
fOBJ_BADLINK(pPicInfo) = FALSE; // can't be bad if succeeded
|
||
|
||
if (bLinkProps)
|
||
{
|
||
bOBJ_WAS_UPDATED(pPicInfo) = TRUE;
|
||
}
|
||
|
||
return(vcpLimParaCache);
|
||
|
||
err:
|
||
Error(IDPMTFailedToUpdate);
|
||
return cp0;
|
||
}
|
||
|
||
typeCP ObjFreezeObjectInDoc(OBJPICINFO *pPicInfo,int doc,typeCP cpParaStart)
|
||
{
|
||
szOBJNAME szObjName;
|
||
OBJPICINFO NewPicInfo = *pPicInfo;
|
||
|
||
if ((otOBJ_QUERY_TYPE(pPicInfo) == STATIC) ||
|
||
(otOBJ_QUERY_TYPE(pPicInfo) == NONE))
|
||
return(vcpLimParaCache);
|
||
|
||
if (ObjMakeObjectReady(pPicInfo,doc,cpParaStart))
|
||
goto err;
|
||
|
||
#ifdef DEBUG
|
||
OutputDebugString( (LPSTR) "Freezing object\n\r");
|
||
#endif
|
||
|
||
if (ObjCloneObjInfo(&NewPicInfo, cpParaStart, szObjName))
|
||
return cp0;
|
||
|
||
/* Make the object static. Note side effect of changing lpObject!! */
|
||
if (ObjError(OleObjectConvert(lpOBJ_QUERY_OBJECT(pPicInfo), SPROTOCOL,
|
||
(LPOLECLIENT)lpOBJ_QUERY_INFO(&NewPicInfo),
|
||
lhClientDoc, szObjName,
|
||
&lpOBJ_QUERY_OBJECT(&NewPicInfo))))
|
||
goto err;
|
||
|
||
/* now delete original */
|
||
ObjDeleteObject(lpOBJ_QUERY_INFO(pPicInfo),TRUE);
|
||
|
||
*pPicInfo = NewPicInfo;
|
||
fOBJ_QUERY_DIRTY_OBJECT(pPicInfo) = TRUE;
|
||
otOBJ_QUERY_TYPE(pPicInfo) = STATIC;
|
||
|
||
/* we got a new name to save */
|
||
if (ObjSetPicInfo(pPicInfo, doc, cpParaStart))
|
||
goto err;
|
||
|
||
return(vcpLimParaCache);
|
||
|
||
err:
|
||
ObjDeleteObjInfo(lpOBJ_QUERY_INFO(&NewPicInfo));
|
||
Error(IDPMTFailedToFreeze);
|
||
return cp0;
|
||
}
|
||
|
||
typeCP ObjCloneObjectInDoc(OBJPICINFO *pPicInfo,int doc,typeCP cpParaStart)
|
||
/* note we are *not* deleting the cloned object! Note side effect that
|
||
*pPicInfo gets altered to new clone values. */
|
||
{
|
||
BOOL fDirty;
|
||
szOBJNAME szObjName;
|
||
OBJPICINFO NewPicInfo = *pPicInfo;
|
||
LPOLEOBJECT lpObject;
|
||
|
||
if (lpOBJ_QUERY_INFO(pPicInfo) == NULL)
|
||
return(cp0);
|
||
|
||
if (bOBJ_REUSE_ME(pPicInfo))
|
||
/* assume that the original picInfo will be deleted!!! */
|
||
{
|
||
|
||
#ifdef DEBUG
|
||
OutputDebugString( (LPSTR) "Reusing object\n\r");
|
||
#endif
|
||
bOBJ_REUSE_ME(pPicInfo) = FALSE;
|
||
return(vcpLimParaCache);
|
||
}
|
||
|
||
if (ObjMakeObjectReady(pPicInfo,doc,cpParaStart))
|
||
goto err;
|
||
|
||
lpObject = lpOBJ_QUERY_OBJECT(pPicInfo);
|
||
|
||
/* clone it. This assumes the one we're cloning from is still in use
|
||
(shouldn't be deleted). */
|
||
|
||
#ifdef DEBUG
|
||
OutputDebugString( (LPSTR) "Cloning object\n\r");
|
||
#endif
|
||
|
||
if (ObjCloneObjInfo(&NewPicInfo, cpParaStart, szObjName))
|
||
return cp0;
|
||
|
||
if (ObjError(OleClone(lpObject,
|
||
(LPOLECLIENT)lpOBJ_QUERY_INFO(&NewPicInfo),
|
||
lhClientDoc,szObjName,
|
||
&lpOBJ_QUERY_OBJECT(&NewPicInfo))))
|
||
goto err;
|
||
|
||
|
||
lpOBJ_QUERY_INFO(&NewPicInfo)->fCompleteAsync = TRUE;
|
||
if (ObjWaitForObject(lpOBJ_QUERY_INFO(&NewPicInfo),TRUE))
|
||
goto err;
|
||
|
||
if (lpOBJ_QUERY_INFO(&NewPicInfo)->fDeleteMe)
|
||
/* this is how we know it failed asynchronously */
|
||
goto err;
|
||
|
||
/**
|
||
Save object name and objinfo that we just got.
|
||
**/
|
||
*pPicInfo = NewPicInfo;
|
||
|
||
if (ObjSetPicInfo(pPicInfo, doc, cpParaStart))
|
||
goto err;
|
||
|
||
return(vcpLimParaCache);
|
||
|
||
err:
|
||
ObjDeleteObjInfo(lpOBJ_QUERY_INFO(&NewPicInfo));
|
||
Error(IDPMTFailedToCreateObject);
|
||
return cp0;
|
||
}
|
||
|
||
typeCP ObjToCloneInDoc(OBJPICINFO *pPicInfo,int doc,typeCP cpParaStart)
|
||
{
|
||
if (lpOBJ_QUERY_INFO(pPicInfo) == NULL)
|
||
return(cp0);
|
||
|
||
#ifdef DEBUG
|
||
OutputDebugString( (LPSTR) "Marking object reusable\n\r");
|
||
#endif
|
||
|
||
bOBJ_REUSE_ME(pPicInfo) = TRUE;
|
||
|
||
return(vcpLimParaCache);
|
||
}
|
||
|
||
typeCP ObjFromCloneInDoc(OBJPICINFO *pPicInfo,int doc,typeCP cpParaStart)
|
||
{
|
||
if (lpOBJ_QUERY_INFO(pPicInfo) == NULL)
|
||
return(cp0);
|
||
|
||
#ifdef DEBUG
|
||
OutputDebugString( (LPSTR) "Marking object not reusable\n\r");
|
||
#endif
|
||
|
||
bOBJ_REUSE_ME(pPicInfo) = FALSE;
|
||
|
||
return(vcpLimParaCache);
|
||
}
|
||
|
||
typeCP ObjBackupInDoc(OBJPICINFO *pPicInfo,int doc,typeCP cpParaStart)
|
||
/* !!! used by link properties only !!!. Object guaranteed loaded */
|
||
{
|
||
szOBJNAME szObjName;
|
||
LPOBJINFO lpCloneInfo=NULL;
|
||
|
||
if (lpOBJ_QUERY_CLONE(pPicInfo) == NULL) // then clone it
|
||
{
|
||
#ifdef DEBUG
|
||
OutputDebugString( (LPSTR) "Backing up object\n\r");
|
||
#endif
|
||
|
||
if (ObjWaitForObject(lpOBJ_QUERY_INFO(pPicInfo),TRUE))
|
||
return cp0;
|
||
|
||
if (ObjCopyObjInfo(lpOBJ_QUERY_INFO(pPicInfo),
|
||
&lpOBJ_QUERY_CLONE(pPicInfo),
|
||
szObjName))
|
||
return(cp0);
|
||
|
||
if (ObjError(OleClone(lpOBJ_QUERY_OBJECT(pPicInfo),
|
||
(LPOLECLIENT)lpOBJ_QUERY_CLONE(pPicInfo),
|
||
lhClientDoc,szObjName,&(lpOBJ_QUERY_CLONE(pPicInfo)->lpobject))))
|
||
return cp0;
|
||
}
|
||
|
||
return(vcpLimParaCache);
|
||
}
|
||
|
||
typeCP ObjClearCloneInDoc(OBJPICINFO *pPicInfo,int doc,typeCP cpParaStart)
|
||
/* !!! used by link properties only !!! Object guaranteed loaded */
|
||
/* delete clone, don't use it */
|
||
{
|
||
if (lpOBJ_QUERY_CLONE(pPicInfo))
|
||
{
|
||
#ifdef DEBUG
|
||
OutputDebugString( (LPSTR) "Deleting clone\n\r");
|
||
#endif
|
||
ObjDeleteObject(lpOBJ_QUERY_CLONE(pPicInfo),TRUE);
|
||
lpOBJ_QUERY_CLONE(pPicInfo) = NULL;
|
||
}
|
||
|
||
return(vcpLimParaCache);
|
||
}
|
||
|
||
typeCP ObjUseCloneInDoc(OBJPICINFO *pPicInfo,int doc,typeCP cpParaStart)
|
||
/* !!! used by link properties only !!! */
|
||
{
|
||
szOBJNAME szObjName;
|
||
|
||
if (lpOBJ_QUERY_INFO(pPicInfo) == NULL)
|
||
return(cp0);
|
||
|
||
if (lpOBJ_QUERY_CLONE(pPicInfo))
|
||
{
|
||
extern int FAR _cdecl sscanf(const char FAR *, const char FAR *, ...);
|
||
LPOBJINFO lpClone = lpOBJ_QUERY_CLONE(pPicInfo);
|
||
|
||
#ifdef DEBUG
|
||
OutputDebugString( (LPSTR) "using clone\n\r");
|
||
#endif
|
||
|
||
ObjDeleteObject(lpOBJ_QUERY_INFO(pPicInfo),TRUE);
|
||
|
||
lpOBJ_QUERY_INFO(pPicInfo) = lpClone;
|
||
lpOBJ_QUERY_CLONE(pPicInfo) = NULL;
|
||
fOBJ_QUERY_DIRTY_OBJECT(pPicInfo) = TRUE; // wanna save clone information
|
||
// just in case
|
||
|
||
/* might've been frozen, used by LoadObject (this is what is unique
|
||
in the context of link properties) */
|
||
otOBJ_QUERY_TYPE(pPicInfo) = LINK;
|
||
|
||
if (ObjSetPicInfo(pPicInfo, doc, cpParaStart))
|
||
return cp0;
|
||
}
|
||
|
||
return(vcpLimParaCache);
|
||
}
|
||
|
||
|
||
typeCP ObjSetNoUpdate(OBJPICINFO *pPicInfo,int doc,typeCP cpParaStart)
|
||
{
|
||
if (lpOBJ_QUERY_INFO(pPicInfo) == NULL)
|
||
return(cp0);
|
||
|
||
#ifdef DEBUG
|
||
OutputDebugString( (LPSTR) "Set no update for object\n\r");
|
||
#endif
|
||
|
||
if (otOBJ_QUERY_TYPE(pPicInfo) == LINK)
|
||
{
|
||
bOBJ_WAS_UPDATED(pPicInfo) = FALSE;
|
||
}
|
||
|
||
return(vcpLimParaCache);
|
||
}
|
||
|
||
|
||
typeCP ObjCheckObjectTypes(OBJPICINFO *pPicInfo,int doc,typeCP cpParaStart)
|
||
{
|
||
#ifdef DEBUG
|
||
//OutputDebugString( (LPSTR) "Checking Object Type\n\r");
|
||
#endif
|
||
|
||
/* Result returned in OBJ_SELECTIONTYPE is highest object type which
|
||
exists at cpParaStart relative to current value of OBJ_SELECTIONTYPE.
|
||
*/
|
||
switch(otOBJ_QUERY_TYPE(pPicInfo))
|
||
{
|
||
case STATIC:
|
||
if (OBJ_SELECTIONTYPE < STATIC)
|
||
OBJ_SELECTIONTYPE = STATIC;
|
||
//OBJ_CEMBEDS = 0;
|
||
return(vcpLimParaCache);
|
||
|
||
case LINK:
|
||
OBJ_SELECTIONTYPE = LINK;
|
||
//OBJ_CEMBEDS = 0;
|
||
return(vcpLimParaCache);
|
||
|
||
case NONE:
|
||
if (OBJ_SELECTIONTYPE < NONE)
|
||
OBJ_SELECTIONTYPE = NONE;
|
||
//OBJ_CEMBEDS = 0;
|
||
return(vcpLimParaCache);
|
||
|
||
case EMBEDDED:
|
||
if (OBJ_SELECTIONTYPE < EMBEDDED)
|
||
OBJ_SELECTIONTYPE = EMBEDDED;
|
||
//++OBJ_CEMBEDS;
|
||
return(vcpLimParaCache);
|
||
|
||
default:
|
||
Assert(0);
|
||
return cp0;
|
||
}
|
||
}
|
||
|
||
typeCP ObjSetHostNameInDoc(OBJPICINFO *pPicInfo,int doc,typeCP cpParaStart)
|
||
{
|
||
if (lpOBJ_QUERY_INFO(pPicInfo) == NULL)
|
||
return(cp0);
|
||
|
||
if (lpOBJ_QUERY_OBJECT(pPicInfo) == NULL)
|
||
return(vcpLimParaCache); // dont care if not loaded
|
||
|
||
if ((otOBJ_QUERY_TYPE(pPicInfo) != EMBEDDED) &&
|
||
(otOBJ_QUERY_TYPE(pPicInfo) != NONE))
|
||
return(vcpLimParaCache);
|
||
|
||
//if (OleQueryOpen(lpOBJ_QUERY_OBJECT(pPicInfo)) != OLE_OK)
|
||
//return(vcpLimParaCache);
|
||
|
||
if (ObjWaitForObject(lpOBJ_QUERY_INFO(pPicInfo),TRUE))
|
||
return cp0;
|
||
|
||
if (ObjSetHostName(lpOBJ_QUERY_INFO(pPicInfo),doc))
|
||
return(cp0);
|
||
|
||
return(vcpLimParaCache);
|
||
}
|
||
|
||
typeCP ObjChangeLinkInDoc(OBJPICINFO *pPicInfo,int doc,typeCP cpParaStart)
|
||
/* assumes aNewName is set */
|
||
{
|
||
HANDLE hData,hNewData=NULL;
|
||
typeCP cpRetval=cp0;
|
||
OLESTATUS olestat=OLE_OK;
|
||
|
||
if (otOBJ_QUERY_TYPE(pPicInfo) != LINK)
|
||
return(vcpLimParaCache);
|
||
|
||
if (ObjMakeObjectReady(pPicInfo,doc,cpParaStart))
|
||
return cp0;
|
||
|
||
/* Change the link information */
|
||
/* if theres a newname, then use it. Else get a new name from user */
|
||
olestat = ObjGetData(lpOBJ_QUERY_INFO(pPicInfo), vcfLink, &hData);
|
||
|
||
if ((olestat == OLE_WARN_DELETE_DATA) || (olestat == OLE_OK))
|
||
{
|
||
if (!(hNewData = ObjMakeNewLinkName(hData, aNewName))
|
||
|| !ObjSetData(pPicInfo, vcfLink, hNewData))
|
||
goto end;
|
||
|
||
if (olestat == OLE_WARN_DELETE_DATA)
|
||
GlobalFree(hData);
|
||
|
||
/* this may not be necessary any more, check carefully. */
|
||
if (ObjUpdateObjectInDoc(pPicInfo,doc,cpParaStart) == cp0)
|
||
goto end;
|
||
|
||
fOBJ_QUERY_DIRTY_OBJECT(pPicInfo) = TRUE;
|
||
fOBJ_BADLINK(pPicInfo) = FALSE;
|
||
|
||
cpRetval = vcpLimParaCache;
|
||
}
|
||
|
||
end:
|
||
if (hNewData)
|
||
GlobalFree(hNewData);
|
||
return cpRetval;
|
||
}
|
||
|
||
typeCP ObjUpdateLinkInDoc(OBJPICINFO *pPicInfo,int doc,typeCP cpParaStart)
|
||
/**
|
||
Change or update link to aNewName if == aOldName. Assumes vbChangeOther
|
||
has been initialized.
|
||
**/
|
||
{
|
||
HANDLE hData;
|
||
char szRename[cchMaxSz];
|
||
|
||
if (otOBJ_QUERY_TYPE(pPicInfo) != LINK)
|
||
return(vcpLimParaCache);
|
||
|
||
if (aOBJ_QUERY_DOCUMENT_LINK(pPicInfo) == aOldName)
|
||
/* Change the link information */
|
||
{
|
||
if (bLinkProps && bOBJ_WAS_UPDATED(pPicInfo))
|
||
return(vcpLimParaCache);
|
||
|
||
if (!fUpdateAll)
|
||
{
|
||
char szTmp[sizeof(szRename) + 90];
|
||
char szLink[30],szDocName[30];
|
||
CHAR szDocPath[ cchMaxFile ];
|
||
CHAR szFullPath[ cchMaxFile ];
|
||
|
||
SplitSzFilename( (**((**hpdocdod)[doc].hszFile)), szDocPath, szDocName );
|
||
|
||
GetAtomName(aOBJ_QUERY_DOCUMENT_LINK(pPicInfo),szFullPath,sizeof(szFullPath));
|
||
SplitSzFilename( szFullPath, szDocPath, szLink );
|
||
|
||
if (!szDocName[0])
|
||
LoadString(hINSTANCE, IDSTRUntitledDef, szDocName, sizeof(szDocName));
|
||
|
||
/* Ask the user if they want to update the links */
|
||
if (vbChangeOther)
|
||
LoadString(hINSTANCE, IDSTRRename, szRename, sizeof(szRename));
|
||
else // update other
|
||
LoadString(hINSTANCE, IDSTRUpdate, szRename, sizeof(szRename));
|
||
|
||
/* cast cause compiler is screwing up */
|
||
wsprintf((LPSTR)szTmp,(LPSTR)szRename,(LPSTR)szLink,(LPSTR)szDocName,(LPSTR)szLink);
|
||
|
||
if (MessageBox(hPARENTWINDOW, szTmp, szAppName,
|
||
MB_YESNO|MB_ICONEXCLAMATION) == IDNO)
|
||
return cp0;
|
||
|
||
ObjCachePara(doc,cpParaStart); // MessageBox screws things up
|
||
fUpdateAll = TRUE;
|
||
}
|
||
|
||
if (vbChangeOther)
|
||
{
|
||
if (ObjBackupInDoc(pPicInfo,doc,cpParaStart))
|
||
return ObjChangeLinkInDoc(pPicInfo,doc,cpParaStart);
|
||
}
|
||
else
|
||
{
|
||
if (ObjBackupInDoc(pPicInfo,doc,cpParaStart))
|
||
return ObjUpdateObjectInDoc(pPicInfo,doc,cpParaStart);
|
||
}
|
||
}
|
||
|
||
return(vcpLimParaCache);
|
||
}
|
||
|
||
|
||
typeCP ObjCloseObjectInDoc(OBJPICINFO *pPicInfo, int doc, typeCP cpParaStart)
|
||
{
|
||
if (lpOBJ_QUERY_INFO(pPicInfo) == NULL)
|
||
return(cp0);
|
||
|
||
if (lpOBJ_QUERY_OBJECT(pPicInfo) == NULL)
|
||
return(vcpLimParaCache);
|
||
|
||
if (otOBJ_QUERY_TYPE(pPicInfo) == STATIC) // nothing to close
|
||
return(vcpLimParaCache);
|
||
|
||
if (ObjWaitForObject(lpOBJ_QUERY_INFO(pPicInfo),TRUE))
|
||
return cp0;
|
||
|
||
/*
|
||
Note that if this is an unfinished object, then the OLE_CLOSE
|
||
(whenever it happens to arrive) will cause the picinfo to be
|
||
deleted.
|
||
*/
|
||
if (ObjError(OleClose(lpOBJ_QUERY_OBJECT(pPicInfo))))
|
||
return(cp0);
|
||
|
||
return(vcpLimParaCache);
|
||
}
|
||
|
||
/****************************************************************/
|
||
/****************** OLE OBJECT DATA I/O *************************/
|
||
/****************************************************************/
|
||
static typeCP ObjWriteDataToDoc(LPOLEOBJECT lpObject)
|
||
/*
|
||
Return cp after end of paragraph we've created or 0 if error.
|
||
Assume ObjStream is initialized.
|
||
*/
|
||
{
|
||
BOOL fSaveError = ferror;
|
||
|
||
if (vfOutOfMemory || vfSysFull /*|| ObjStop*/)
|
||
return cp0;
|
||
|
||
Assert(!ferror);
|
||
|
||
ferror = FALSE; /* so we can still call Replace(). */
|
||
|
||
if (ObjError(OleSaveToStream(lpObject,lpStream)))
|
||
{
|
||
if (ferror)
|
||
/* uh oh, hope we can clean up enough to look clean */
|
||
{
|
||
/* delete what we inserted if possible */
|
||
ferror = FALSE;
|
||
Replace(docStream, cpObjectDataBase - cchPICINFOX, cpObjectDataCurLoc - cpObjectDataBase + cchPICINFOX, fnNil, fc0, fc0);
|
||
ferror = TRUE;
|
||
return cp0;
|
||
}
|
||
}
|
||
|
||
/* is this call necessary? Important to do if InsertRgch doesn't. */
|
||
ObjCachePara(docStream,cpObjectDataBase - cchPICINFOX);
|
||
|
||
ferror = fSaveError || ferror;
|
||
|
||
return vcpLimParaCache; // cp after para we just inserted
|
||
}
|
||
|
||
|
||
/****************************************************************/
|
||
/******************** OLE STREAM I/O ****************************/
|
||
/****************************************************************/
|
||
|
||
static
|
||
ObjOpenStreamIO(typeCP cpParaStart, int doc, struct CHP *pchp, struct PAP *ppapGraph, DWORD dwObjectSize)
|
||
{
|
||
if (cpObjectDataCurLoc)
|
||
ObjCloseStreamIO();
|
||
|
||
cpObjectDataBase = cpObjectDataCurLoc = cpParaStart;
|
||
cObjectData = 0L;
|
||
dwDataMax = dwObjectSize;
|
||
docStream = doc;
|
||
pchpStream = pchp;
|
||
ppapStream = ppapGraph;
|
||
}
|
||
|
||
static void
|
||
ObjCloseStreamIO(void)
|
||
{
|
||
cpObjectDataBase = cpObjectDataCurLoc = cp0;
|
||
}
|
||
|
||
LONG FAR PASCAL BufReadStream(LPOLESTREAM lpStream, char huge *lpstr, DWORD cb)
|
||
{
|
||
DWORD dwRetval;
|
||
typeCP cpMac = vcpLimParaCache;
|
||
int cchRun;
|
||
|
||
if ((cb + cpObjectDataCurLoc) > cpMac) // reading past end of para
|
||
{
|
||
Assert(0);
|
||
return 0L;
|
||
}
|
||
|
||
for ( dwRetval = 0L;
|
||
cb;
|
||
cb -= cchRun,
|
||
cObjectData += cchRun,
|
||
cpObjectDataCurLoc += (typeCP) cchRun,
|
||
dwRetval += cchRun)
|
||
{
|
||
CHAR rgch[ 255 ];
|
||
register char *chT;
|
||
register unsigned cchT;
|
||
unsigned cch = ulmin(cb, 255L);
|
||
|
||
FetchRgch( &cchRun, rgch, docStream, cpObjectDataCurLoc, cpMac, cch);
|
||
|
||
if (ferror)
|
||
return -dwRetval;
|
||
|
||
for(chT = rgch,cchT=cchRun; cchT--; )
|
||
*lpstr++ = *chT++;
|
||
}
|
||
|
||
return dwRetval;
|
||
}
|
||
|
||
|
||
LONG FAR PASCAL BufWriteStream(LPOLESTREAM lpStream, char huge *lpstr, DWORD cb)
|
||
{
|
||
DWORD dwRetval;
|
||
char *chT;
|
||
unsigned cchT;
|
||
CHAR rgch[255];
|
||
unsigned cch;
|
||
struct PAP *ppap=NULL;
|
||
|
||
for ( dwRetval = 0L;
|
||
dwRetval < cb;
|
||
cpObjectDataCurLoc += (typeCP) cch,
|
||
cObjectData += cch,
|
||
dwRetval += cch)
|
||
{
|
||
cch = ulmin(cb - dwRetval, 255L);
|
||
|
||
for(chT = rgch,cchT=cch; cchT--;)
|
||
*chT++ = *lpstr++;
|
||
|
||
if ((cObjectData + cch) == dwDataMax)
|
||
ppap = ppapStream;
|
||
|
||
InsertRgch( docStream, cpObjectDataCurLoc, rgch, cch, pchpStream, ppap);
|
||
|
||
if (ferror)
|
||
return 0L;
|
||
}
|
||
|
||
return dwRetval;
|
||
}
|
||
|
||
ObjGetPicInfo(LPOLEOBJECT lpObject, int doc, OBJPICINFO *pPicInfo, typeCP *pcpParaStart)
|
||
/* get picInfo that has lpObject */
|
||
/* !!! since writing this it has occurred to me that a quicker way to do
|
||
this would be to keep a list of pieces that point to objects. Pieces
|
||
never */
|
||
{
|
||
OBJPICINFO picInfoT;
|
||
typeCP cpStart,cpMac= CpMacText(doc);
|
||
|
||
for (cpStart = cpNil; ObjPicEnumInRange(&picInfoT,doc,cp0,cpMac,&cpStart); )
|
||
{
|
||
if (lpOBJ_QUERY_INFO(&picInfoT) == NULL)
|
||
continue;
|
||
|
||
if (lpOBJ_QUERY_OBJECT(&picInfoT) == lpObject) // bingo
|
||
{
|
||
if (pPicInfo)
|
||
*pPicInfo = picInfoT;
|
||
if (pcpParaStart)
|
||
*pcpParaStart = cpStart;
|
||
return TRUE;
|
||
}
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
BOOL vfObjDisplaying=FALSE;
|
||
BOOL ObjSetPicInfo(OBJPICINFO *pSrcPicInfo, int doc, typeCP cpParaStart)
|
||
{
|
||
/*
|
||
NOTE that you only gotta call this when you change the OBJPICINFO fields:
|
||
mm,
|
||
objecttype,
|
||
dwDataSize,
|
||
dwObjNum, or
|
||
lpObjInfo.
|
||
*/
|
||
BOOL bError = FALSE;
|
||
typeFC fcT;
|
||
extern BOOL vfInvalid;
|
||
BOOL vfSaveInvalid = vfInvalid;
|
||
BOOL docDirty = (**hpdocdod) [doc].fDirty;
|
||
|
||
ObjPushParms(doc);
|
||
|
||
ObjCachePara(doc,cpParaStart);
|
||
|
||
if (vfObjDisplaying)
|
||
vfInvalid = FALSE; // this'll suppress things that mess up UpdateWw()
|
||
bNoEol = TRUE;
|
||
|
||
if (dwOBJ_QUERY_DATA_SIZE(pSrcPicInfo) == 0L)
|
||
/* is this ever executed? */
|
||
{
|
||
struct CHP chp;
|
||
|
||
/* problem is to retain graphics property of picinfo structure */
|
||
GetChp(&chp, cpParaStart, doc); // calls CachePara
|
||
NewChpIns(&chp);
|
||
ObjUpdateFromObjInfo(pSrcPicInfo);
|
||
pSrcPicInfo->mm |= MM_EXTENDED;
|
||
InsertRgch( doc, cpParaStart + (typeCP)cchPICINFOX, pSrcPicInfo,
|
||
(unsigned)cchPICINFOX, &chp, &vpapAbs );
|
||
pSrcPicInfo->mm &= ~MM_EXTENDED;
|
||
|
||
if (ferror)
|
||
return TRUE;
|
||
|
||
/* delete old pieces (in front) that pointed to duped data */
|
||
Replace(doc, cpParaStart, (typeCP)cchPICINFOX, fnNil, fc0, fc0);
|
||
}
|
||
else
|
||
{
|
||
ObjUpdateFromObjInfo(pSrcPicInfo);
|
||
pSrcPicInfo->mm |= MM_EXTENDED;
|
||
fcT = FcWScratch( pSrcPicInfo, cchPICINFOX );
|
||
pSrcPicInfo->mm &= ~MM_EXTENDED;
|
||
|
||
if (ferror)
|
||
return TRUE;
|
||
Replace( doc, cpParaStart, (typeCP)cchPICINFOX,
|
||
fnScratch, fcT, (typeFC)cchPICINFOX);
|
||
}
|
||
|
||
if (ferror)
|
||
return TRUE;
|
||
|
||
bNoEol = FALSE;
|
||
if (vfObjDisplaying)
|
||
vfInvalid = vfSaveInvalid;
|
||
|
||
/* don't want this to affect docDirty flag */
|
||
(**hpdocdod) [doc].fDirty = docDirty;
|
||
|
||
ObjPopParms(TRUE);
|
||
|
||
return bError;
|
||
}
|
||
|
||
|
||
void ChangeOtherLinks(int doc, BOOL bChange, BOOL bPrompt)
|
||
/** For any items == aOldName, set to aNewName. Query user if OK first.
|
||
Assumes aOldName and aNewName are set. (See FixInvalidLink() and
|
||
ObjChangeLinkInDoc()).
|
||
bChange is TRUE if ChangeLink, FALSE if UpdateObject.
|
||
bPrompt is TRUe if prompt user for change.
|
||
**/
|
||
{
|
||
fUpdateAll = !bPrompt;
|
||
|
||
vbChangeOther = bChange; // TRUE to change links, FALSE to update links
|
||
ObjEnumInDoc(doc,ObjUpdateLinkInDoc);
|
||
|
||
}
|
||
|
||
BOOL ObjQueryNewLinkName(OBJPICINFO *pPicInfo,int doc,typeCP cpParaStart)
|
||
/** Return whether obtained new link name from user. Set aOldName
|
||
and aNewName. **/
|
||
{
|
||
HANDLE hData,hNewData=NULL;
|
||
LPSTR lpdata=NULL;
|
||
BOOL bRetval = FALSE;
|
||
OLESTATUS olestat=OLE_OK;
|
||
|
||
if (lpOBJ_QUERY_INFO(pPicInfo) == NULL)
|
||
return(FALSE);
|
||
|
||
if (otOBJ_QUERY_TYPE(pPicInfo) != LINK)
|
||
return(FALSE);
|
||
|
||
if (ObjMakeObjectReady(pPicInfo,doc,cpParaStart))
|
||
return(FALSE);
|
||
|
||
/* query user for new name */
|
||
olestat = ObjGetData(lpOBJ_QUERY_INFO(pPicInfo), vcfLink, &hData);
|
||
if ((olestat == OLE_WARN_DELETE_DATA) || (olestat == OLE_OK))
|
||
if (!(hNewData = OfnGetNewLinkName(hPARENTWINDOW, hData)))
|
||
goto end;
|
||
|
||
if (olestat == OLE_WARN_DELETE_DATA)
|
||
GlobalFree(hData);
|
||
|
||
aOldName = aOBJ_QUERY_DOCUMENT_LINK(pPicInfo);
|
||
|
||
lpdata=MAKELP(hNewData,0);
|
||
|
||
while (*lpdata++);
|
||
|
||
aNewName = AddAtom(lpdata);
|
||
|
||
bRetval = TRUE;
|
||
|
||
end:
|
||
if (olestat == OLE_WARN_DELETE_DATA)
|
||
GlobalFree(hData);
|
||
|
||
if (hNewData)
|
||
GlobalFree(hNewData);
|
||
|
||
return bRetval;
|
||
}
|
||
|
||
FixInvalidLink(OBJPICINFO far *lpPicInfo, int doc, typeCP cpParaStart)
|
||
/* returns FALSE if couldn't or wouldn't do anything, RETRY if reset link */
|
||
{
|
||
|
||
fOBJ_BADLINK(lpPicInfo) = TRUE;
|
||
if (DialogBox(hINSTANCE, "DTINVALIDLINK",
|
||
hPARENTWINDOW, lpfnInvalidLink) == IDD_CHANGE)
|
||
#if !defined(SMALL_OLE_UI)
|
||
fnObjProperties();
|
||
#else
|
||
ObjChangeLinkInDoc(lpPicInfo,doc,cpParaStart);
|
||
#endif
|
||
return FALSE;
|
||
}
|
||
|
||
/* ObjMakeNewLinkName() - Constructs a new link name from an atom.
|
||
*/
|
||
static HANDLE ObjMakeNewLinkName(HANDLE hData, ATOM atom)
|
||
{
|
||
BOOL fSuccess = FALSE;
|
||
HANDLE hData2 = NULL;
|
||
HANDLE hData3 = NULL;
|
||
LPSTR lpstrData = NULL;
|
||
LPSTR lpstrLink = NULL;
|
||
LPSTR lpstrTemp;
|
||
char szFile[CBPATHMAX];
|
||
|
||
if (!GetAtomName(atom, szFile, CBPATHMAX)
|
||
|| !(lpstrData = (LPSTR)GlobalLock(hData))
|
||
|| !(hData2 = GlobalAlloc(GMEM_DDESHARE | GMEM_ZEROINIT, CBPATHMAX * 2))
|
||
|| !(lpstrLink = lpstrTemp = (LPSTR)GlobalLock(hData2)))
|
||
goto Error;
|
||
|
||
/* ... copy the server name */
|
||
while (*lpstrTemp++ = *lpstrData++);
|
||
|
||
/* ... copy the document name */
|
||
lstrcpy(lpstrTemp, szFile);
|
||
lpstrTemp += lstrlen(lpstrTemp) + 1;
|
||
lpstrData += lstrlen(lpstrData) + 1;
|
||
|
||
/* ... copy the item name */
|
||
while (*lpstrTemp++ = *lpstrData++);
|
||
*lpstrTemp = 0;
|
||
|
||
/* ... and compress the memory block to minimal size */
|
||
GlobalUnlock(hData2);
|
||
hData3 = GlobalReAlloc(hData2, (DWORD)(lpstrTemp - lpstrLink + 1), 0);
|
||
|
||
if (!hData3)
|
||
hData3 = hData2;
|
||
|
||
fSuccess = TRUE;
|
||
|
||
Error:
|
||
if (!fSuccess) {
|
||
if (lpstrLink)
|
||
GlobalUnlock(hData2);
|
||
if (hData2)
|
||
GlobalFree(hData2);
|
||
hData3 = NULL;
|
||
}
|
||
|
||
if (lpstrData)
|
||
GlobalUnlock(hData);
|
||
|
||
return hData3;
|
||
}
|
||
|
||
char *ObjGetServerName(LPOLEOBJECT lpObject, char *szServerName)
|
||
{
|
||
LPSTR lpstrData;
|
||
HANDLE hData;
|
||
LONG otobject;
|
||
OLESTATUS olestat;
|
||
|
||
/** NOTE: OleGetData can return OLE_BUSY. Because of how
|
||
ObjGetServerName is used, we're not going to wait for the
|
||
object here, we'll just return if its busy **/
|
||
|
||
if (OleQueryReleaseStatus(lpObject) == OLE_BUSY)
|
||
return NULL;
|
||
|
||
if (ObjError(OleQueryType(lpObject,&otobject)))
|
||
return NULL;
|
||
|
||
olestat = OleGetData(lpObject,
|
||
otobject == OT_LINK ? vcfLink : vcfOwnerLink,
|
||
&hData);
|
||
|
||
if ((olestat != OLE_WARN_DELETE_DATA) && (olestat != OLE_OK))
|
||
{
|
||
ObjError(olestat);
|
||
return NULL;
|
||
}
|
||
|
||
lpstrData = MAKELP(hData,0);
|
||
RegGetClassId(szServerName, lpstrData);
|
||
if (olestat == OLE_WARN_DELETE_DATA)
|
||
GlobalFree(hData);
|
||
|
||
return szServerName;
|
||
}
|
||
|
||
/* OfnInit() - Initializes the standard file dialog OFN structure.
|
||
*/
|
||
void OfnInit(HANDLE hInst) {
|
||
LPSTR lpstr;
|
||
|
||
OFN.lStructSize = sizeof(OPENFILENAME);
|
||
OFN.hInstance = hInst;
|
||
OFN.nMaxCustFilter = CBFILTERMAX;
|
||
OFN.nMaxFile = CBPATHMAX;
|
||
OFN.Flags = OFN_HIDEREADONLY;
|
||
OFN.lCustData = NULL;
|
||
OFN.lpfnHook = NULL;
|
||
OFN.lpTemplateName = NULL;
|
||
OFN.lpstrDefExt = NULL;
|
||
OFN.lpstrFileTitle = NULL;
|
||
|
||
LoadString(hInst, IDSTRChangelink, szLinkCaption, sizeof(szLinkCaption));
|
||
}
|
||
|
||
/* OfnGetNewLinkName() - Sets up the "Change Link..." dialog box
|
||
*/
|
||
static HANDLE OfnGetNewLinkName(HWND hwnd, HANDLE hData)
|
||
{
|
||
BOOL fSuccess = FALSE;
|
||
HANDLE hData2 = NULL;
|
||
HANDLE hData3 = NULL;
|
||
LPSTR lpData2 = NULL;
|
||
LPSTR lpstrData = NULL;
|
||
LPSTR lpstrFile = NULL;
|
||
LPSTR lpstrLink = NULL;
|
||
LPSTR lpstrPath = NULL;
|
||
LPSTR lpstrTemp = NULL;
|
||
char szDocFile[CBPATHMAX];
|
||
char szDocPath[CBPATHMAX];
|
||
HANDLE hServerFilter=NULL;
|
||
|
||
/* Get the link information */
|
||
if (!(lpstrData = GlobalLock(hData)))
|
||
goto Error;
|
||
|
||
/* Figure out the link's path name and file name */
|
||
lpstrTemp = lpstrData;
|
||
while (*lpstrTemp++);
|
||
lpstrPath = lpstrFile = lpstrTemp;
|
||
while (*(lpstrTemp = AnsiNext(lpstrTemp)))
|
||
if (*lpstrTemp == '\\')
|
||
lpstrFile = lpstrTemp + 1;
|
||
|
||
/* Copy the document name */
|
||
lstrcpy(szDocFile, lpstrFile);
|
||
*(lpstrFile - 1) = 0;
|
||
|
||
/* Copy the path name */
|
||
lstrcpy(szDocPath, ((lpstrPath != lpstrFile) ? lpstrPath : ""));
|
||
if (lpstrPath != lpstrFile) /* Restore the backslash */
|
||
*(lpstrFile - 1) = '\\';
|
||
while (*lpstrFile != '.' && *lpstrFile) /* Get the extension */
|
||
lpstrFile++;
|
||
|
||
/* Make a filter that respects the link's class name */
|
||
OFN.hwndOwner = hwnd;
|
||
|
||
OFN.nFilterIndex = RegMakeFilterSpec(lpstrData, lpstrFile, &hServerFilter);
|
||
if (OFN.nFilterIndex == -1)
|
||
goto Error;
|
||
OFN.lpstrFilter = (LPSTR)MAKELP(hServerFilter,0);
|
||
|
||
Normalize(szDocFile);
|
||
OFN.lpstrFile = (LPSTR)szDocFile;
|
||
OFN.lpstrInitialDir = (LPSTR)szDocPath;
|
||
OFN.lpstrTitle = (LPSTR)szLinkCaption;
|
||
OFN.lpstrCustomFilter = (LPSTR)szCustFilterSpec;
|
||
|
||
|
||
/* If we get a file... */
|
||
if (GetOpenFileName((LPOPENFILENAME)&OFN))
|
||
{
|
||
if (!(hData2 = GlobalAlloc(GMEM_DDESHARE | GMEM_ZEROINIT, CBPATHMAX * 2))
|
||
|| !(lpstrLink = lpstrTemp = GlobalLock(hData2)))
|
||
goto Error;
|
||
|
||
/* ... copy the server name */
|
||
while (*lpstrTemp++ = *lpstrData++);
|
||
|
||
/* ... copy the document name */
|
||
lstrcpy(lpstrTemp, szDocFile);
|
||
lpstrTemp += lstrlen(lpstrTemp) + 1;
|
||
lpstrData += lstrlen(lpstrData) + 1;
|
||
|
||
/* ... copy the item name */
|
||
while (*lpstrTemp++ = *lpstrData++);
|
||
*lpstrTemp = 0;
|
||
|
||
/* ... and compress the memory block to minimal size */
|
||
GlobalUnlock(hData2);
|
||
hData3 = GlobalReAlloc(hData2, (DWORD)(lpstrTemp - lpstrLink + 1), 0);
|
||
|
||
if (!hData3)
|
||
hData3 = hData2;
|
||
|
||
fSuccess = TRUE;
|
||
}
|
||
|
||
Error:
|
||
if (!fSuccess)
|
||
{
|
||
if (lpstrLink)
|
||
GlobalUnlock(hData2);
|
||
if (hData2)
|
||
GlobalFree(hData2);
|
||
hData3 = NULL;
|
||
}
|
||
|
||
if (lpstrData)
|
||
GlobalUnlock(hData);
|
||
|
||
if (hServerFilter)
|
||
GlobalFree(hServerFilter);
|
||
|
||
return hData3;
|
||
}
|
||
|
||
/* Normalize() - Removes the path specification from the file name.
|
||
*
|
||
* Note: It isn't possible to get "<drive>:<filename>" as input because
|
||
* the path received will always be fully qualified.
|
||
*/
|
||
static void Normalize(LPSTR lpstrFile)
|
||
{
|
||
LPSTR lpstrBackslash = NULL;
|
||
LPSTR lpstrTemp = lpstrFile;
|
||
|
||
while (*lpstrTemp) {
|
||
if (*lpstrTemp == '\\')
|
||
lpstrBackslash = lpstrTemp;
|
||
|
||
lpstrTemp = AnsiNext(lpstrTemp);
|
||
}
|
||
if (lpstrBackslash)
|
||
lstrcpy(lpstrFile, lpstrBackslash + 1);
|
||
}
|
||
|
||
/* ObjSetUpdateOptions() - Sets the update options of the object.
|
||
*
|
||
* Returns: TRUE iff the command completed successfully
|
||
*/
|
||
BOOL ObjSetUpdateOptions(OBJPICINFO *pPicInfo, WORD wParam, int doc, typeCP cpParaStart)
|
||
/* !!! Used by Link Properties only!!! Object guaranteed loaded */
|
||
{
|
||
if (ObjWaitForObject(lpOBJ_QUERY_INFO(pPicInfo),TRUE))
|
||
{
|
||
Error(IDPMTFailedToUpdateLink);
|
||
return FALSE;
|
||
}
|
||
|
||
if (ObjError(OleSetLinkUpdateOptions(lpOBJ_QUERY_OBJECT(pPicInfo),
|
||
(wParam == IDD_AUTO) ? oleupdate_always : oleupdate_oncall)))
|
||
{
|
||
Error(IDPMTFailedToUpdateLink);
|
||
return FALSE;
|
||
}
|
||
|
||
fOBJ_QUERY_DIRTY_OBJECT(pPicInfo) = TRUE;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
/* ObjGetUpdateOptions() - Retrieves the update options of the object.
|
||
*/
|
||
OLEOPT_UPDATE ObjGetUpdateOptions(OBJPICINFO far *lpPicInfo)
|
||
/* !!! Used by Link Properties only!!! Object guaranteed loaded */
|
||
{
|
||
BOOL fSuccess = FALSE;
|
||
OLEOPT_UPDATE fUpdate;
|
||
|
||
if (otOBJ_QUERY_TYPE(lpPicInfo) == LINK)
|
||
{
|
||
if (ObjWaitForObject(lpOBJ_QUERY_INFO(lpPicInfo),TRUE))
|
||
return FALSE;
|
||
|
||
fSuccess = !ObjError(OleGetLinkUpdateOptions(lpOBJ_QUERY_OBJECT(lpPicInfo), &fUpdate));
|
||
}
|
||
return (fSuccess ? fUpdate : oleupdate_onsave);
|
||
}
|
||
|
||
OLESTATUS ObjGetData(LPOBJINFO lpObjInfo, OLECLIPFORMAT cf, HANDLE far *lphData)
|
||
/*
|
||
Return olestat.
|
||
Put handle to data into lphData.
|
||
Assumes object is loaded.
|
||
*/
|
||
{
|
||
HANDLE hData;
|
||
OLESTATUS olestat;
|
||
|
||
if (ObjWaitForObject(lpObjInfo,TRUE))
|
||
return OLE_BUSY;
|
||
|
||
olestat = OleGetData(lpObjInfo->lpobject, cf, lphData);
|
||
if ((olestat != OLE_WARN_DELETE_DATA) && (olestat != OLE_OK))
|
||
ObjError(olestat);
|
||
return olestat;
|
||
}
|
||
|
||
/* ObjSetData() - Set the object's (link) information
|
||
Sets DOCUMENT_LINK ATOM in pPicInfo
|
||
*/
|
||
BOOL ObjSetData(OBJPICINFO far *lpPicInfo, OLECLIPFORMAT cf, HANDLE hData)
|
||
/* assumes object is loaded */
|
||
{
|
||
HANDLE hitem;
|
||
LPSTR lpdata;
|
||
|
||
if (ObjWaitForObject(lpOBJ_QUERY_INFO(lpPicInfo),TRUE))
|
||
return FALSE;
|
||
|
||
if (ObjError(OleSetData(lpOBJ_QUERY_OBJECT(lpPicInfo), cf, hData)))
|
||
return FALSE;
|
||
|
||
/* If we have a link, update the document name */
|
||
if (cf == vcfLink && (lpdata = GlobalLock(hData)))
|
||
{
|
||
ATOM aSaveOld = aOBJ_QUERY_DOCUMENT_LINK(lpPicInfo);
|
||
|
||
while (*lpdata++);
|
||
|
||
aOBJ_QUERY_DOCUMENT_LINK(lpPicInfo) = AddAtom(lpdata);
|
||
|
||
if (aSaveOld)
|
||
DeleteAtom(aSaveOld);
|
||
|
||
GlobalUnlock(hData);
|
||
}
|
||
else
|
||
return FALSE;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
int ObjSetSelectionType(int doc, typeCP cpFirst, typeCP cpLim)
|
||
{
|
||
/* set whether link or emb selected */
|
||
OBJ_SELECTIONTYPE = NONE; // this'll be set by ObjCheckObjectTypes()
|
||
//OBJ_CEMBEDS = 0; // this'll be set by ObjCheckObjectTypes()
|
||
return ObjEnumInRange(doc,cpFirst,cpLim,ObjCheckObjectTypes);
|
||
}
|
||
|
||
BOOL ObjQueryCpIsObject(int doc,typeCP cpFirst)
|
||
{
|
||
OBJPICINFO picInfo;
|
||
|
||
/* assume its cached already! */
|
||
//ObjCachePara(doc,cpFirst); /* NOTE side effect of caching */
|
||
|
||
if (!vpapAbs.fGraphics)
|
||
return FALSE;
|
||
|
||
if (cpFirst >= CpMacText(doc))
|
||
return FALSE;
|
||
|
||
GetPicInfo(cpFirst,cpFirst + cchPICINFOX, doc, &picInfo);
|
||
return bOBJ_QUERY_IS_OBJECT(&picInfo);
|
||
}
|
||
|
||
|
||
ATOM MakeLinkAtom(LPOBJINFO lpObjInfo)
|
||
{
|
||
HANDLE hData;
|
||
LPSTR lpdata;
|
||
ATOM aRetval=NULL;
|
||
OLESTATUS olestat=OLE_OK;
|
||
|
||
olestat = ObjGetData(lpObjInfo, vcfLink, &hData);
|
||
|
||
if ((olestat == OLE_WARN_DELETE_DATA) || (olestat == OLE_OK))
|
||
{
|
||
lpdata = MAKELP(hData,0);
|
||
while (*lpdata++);
|
||
aRetval = AddAtom(lpdata);
|
||
|
||
if (olestat == OLE_WARN_DELETE_DATA)
|
||
GlobalFree(hData);
|
||
}
|
||
return aRetval;
|
||
}
|
||
|
||
#include <time.h>
|
||
void ObjGetObjectName(LPOBJINFO lpObjInfo, szOBJNAME szObjName)
|
||
/* put object name from ObjInfo into szObjName */
|
||
{
|
||
if (szObjName && lpObjInfo)
|
||
GetAtomName(lpObjInfo->aObjName,szObjName,sizeof(szObjName));
|
||
}
|
||
|
||
void ObjMakeObjectName(LPOBJINFO lpObjInfo, LPSTR lpstr)
|
||
{
|
||
szOBJNAME szObjName;
|
||
|
||
time_t lTime;
|
||
time(&lTime);
|
||
wsprintf(szObjName, "%lx", lTime);
|
||
|
||
if (lpObjInfo)
|
||
lpObjInfo->aObjName = AddAtom(szObjName);
|
||
|
||
if (lpstr)
|
||
lstrcpy(lpstr,szObjName);
|
||
}
|
||
|
||
static void GetChp(struct CHP *pchp, typeCP cp, int doc)
|
||
{
|
||
/**
|
||
Return chp at cp in *pchp.
|
||
Resets Cache to cp when done.
|
||
We assume that we're always inserting after an EOL or at beginning of
|
||
document.
|
||
**/
|
||
|
||
extern struct CHP vchpAbs;
|
||
|
||
if (cp == cp0) // beginning of doc
|
||
{
|
||
typeCP cpMac = CpMacText(doc);
|
||
if (cpMac == cp0) // empty doc
|
||
{
|
||
/* force default character properties, font size to be 10 point */
|
||
*pchp = vchpNormal;
|
||
pchp->hps = hpsDefault;
|
||
return;
|
||
}
|
||
else // get next char props
|
||
{
|
||
ObjCachePara(doc,cp+1); // to reset
|
||
FetchCp( doc, cp+1, 0, fcmProps );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ObjCachePara(doc,cp-1); // to reset
|
||
FetchCp( doc, cp-1, 0, fcmProps ); // previous paragraph's chp
|
||
}
|
||
|
||
*pchp = vchpAbs;
|
||
|
||
if (pchp->fSpecial && pchp->hpsPos != 0)
|
||
{ /* if this char is a footnote or page marker, then ignore */
|
||
pchp->hpsPos = 0; /* super/subscript stuff. */
|
||
pchp->hps = HpsAlter(pchp->hps, 1);
|
||
}
|
||
|
||
pchp->fSpecial = fFalse;
|
||
|
||
ObjCachePara(doc,cp); // to reset
|
||
}
|
||
|
||
BOOL ObjSetHostName(LPOBJINFO lpOInfo, int doc)
|
||
/* TRUE if error */
|
||
/* we assume object ain't busy!!! */
|
||
{
|
||
extern CHAR szUntitled[20];
|
||
CHAR *PchStartBaseNameSz(),*szTitle= **((**hpdocdod)[doc].hszFile);
|
||
|
||
if (szTitle[0])
|
||
szTitle = PchStartBaseNameSz(szTitle);
|
||
else
|
||
szTitle = szUntitled;
|
||
|
||
#ifdef DEBUG
|
||
OutputDebugString( (LPSTR) "Setting host name\n\r");
|
||
#endif
|
||
|
||
/*
|
||
Note that OleSetHostNames can return OLE_BUSY!!! So you
|
||
better call ObjWaitForObject() first.
|
||
*/
|
||
|
||
if (ObjError(OleSetHostNames(lpOInfo->lpobject,szAppName,szTitle)))
|
||
return TRUE;
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
BOOL ObjMakeObjectReady(OBJPICINFO *pPicInfo, int doc, typeCP cpParaStart)
|
||
/* Load object, complete async. Return whether an error. */
|
||
{
|
||
if (lpOBJ_QUERY_INFO(pPicInfo) == NULL)
|
||
return TRUE;
|
||
|
||
if (lpOBJ_QUERY_OBJECT(pPicInfo) == NULL)
|
||
{
|
||
if (ObjLoadObjectInDoc(pPicInfo,doc,cpParaStart) == cp0)
|
||
return TRUE;
|
||
}
|
||
else if (ObjWaitForObject(lpOBJ_QUERY_INFO(pPicInfo),TRUE))
|
||
return TRUE;
|
||
|
||
ObjCachePara(doc, cpParaStart);
|
||
|
||
return FALSE;
|
||
}
|
||
|