|
|
/************************************************************/ /* Windows Write, Copyright 1985-1992 Microsoft Corporation */ /************************************************************/
/* Open.c -- WRITE document opening */
#define NOCLIPBOARD
#define NOGDICAPMASKS
#define NOVIRTUALKEYCODES
#define NOWINMESSAGES
#define NOSYSMETRICS
#define NOMENUS
#define NOICON
#define NOKEYSTATE
#define NOSYSCOMMANDS
#define NORASTEROPS
//#define NOATOM
#define NOBITMAP
#define NOPEN
#define NODRAWTEXT
#define NOCOLOR
#define NOCREATESTRUCT
#define NOHDC
#define NOMETAFILE
#define NOMSG
#define NOPOINT
#define NORECT
#define NOREGION
#define NOSCROLL
#define NOWH
#define NOWINOFFSETS
#define NOSOUND
#define NOCOMM
#define NORESOURCE
#include <windows.h>
#include "mw.h"
#include "doslib.h"
#include "dispdefs.h"
#define NOUAC
#include "cmddefs.h"
#include "wwdefs.h"
#include "docdefs.h"
#include "fontdefs.h"
#include "editdefs.h"
#include "filedefs.h"
#include "propdefs.h"
#include "fkpdefs.h"
#define NOSTRUNDO
#define NOSTRMERGE
#include "str.h"
#include "code.h"
#include "prmdefs.h"
#include "obj.h"
#define PAGEONLY
#include "printdef.h" /* printdefs.h */
/*
#include "dlgdefs.h"
*/
/* These defines replace dlgdefs.h to combat compiler heap overflows */ #define idiYes IDOK
#define idiNo 3
#define idiCancel IDCANCEL
/* These defines replace heapdefs.h and heapdata.h for the same
irritating reason */ #define cwSaveAlloc (128)
#define cwHeapMinPerWindow (50)
#define cwHeapSpaceMin (60)
/* E X T E R N A L S */
extern CHAR (**vhrgbSave)[]; extern HANDLE hParentWw; extern HANDLE hMmwModInstance; extern struct WWD rgwwd[]; extern int wwMac; extern struct FCB (**hpfnfcb)[]; extern struct DOD (**hpdocdod)[]; extern int docMac; extern struct WWD *pwwdCur; extern int fnMac; extern CHAR stBuf[]; #if WINVER >= 0x300
extern BOOL fError; #endif
short WCompSzC(); CHAR (**HszCreate())[]; struct FNTB **HfntbCreate(); #ifdef CASHMERE
struct SETB **HsetbCreate(); #else
struct SEP **HsepCreate(); #endif
struct PGTB **HpgtbCreate();
CHAR *PchFromFc( int, typeFC, int * ); CHAR *PchGetPn( int, typePN, int *, int ); typeFC FcMacFromUnformattedFn( int ); int CchReadAtPage( int, typePN, CHAR *, int, int );
struct TBD (**HgtbdCreate(fn))[] int fn; { /* Create a MEMO tab table by reading the properties of the first
para of the passed fn and returning a handle. The handle returned will be 0 if the tab table is not present or null */ struct TBD (**hgtbd)[] = 0; struct PAP pap;
Assert( (fn != fnNil) && (**hpfnfcb)[fn].fFormatted );
bltc((int *)&pap, 0, cwPAP); /* else we will have garbage tabs */ FcParaLim( fn, (typeFC)cfcPage, (**hpfnfcb)[fn].fcMac, &pap ); if (pap.rgtbd[0].dxa && !FNoHeap( hgtbd = (struct TBD (**)[])HAllocate( cwTBD * itbdMax ))) { register struct TBD *ptbd = &pap.rgtbd[0]; pap.rgtbd[itbdMax - 1].dxa = 0; /* just in case a WORD document has more
than 12 tabs */
/* overwrite tabs and leading tab char that WRITE does not support */ for ( ; ptbd->dxa != 0; ptbd++) { ptbd->tlc = tlcWhite; ptbd->opcode = 0; ptbd->chAlign = 0; if (ptbd->jc == jcCenter) ptbd->jc = jcLeft; else if (ptbd->jc == jcRight) ptbd->jc = jcBoth; } blt( &pap.rgtbd[0], *hgtbd, cwTBD * itbdMax ); } return hgtbd; }
struct SEP **HsepCreate(fn) int fn; { /* Given an fn for a formatted file, return a handle to an SEP
giving section properties for the file. Returns NULL if standard properties should be used. If the file has a section table, the properties from the first section in the table are used */ extern struct SEP vsepNormal;
struct SETB *psetbFile; typePN pn; struct SEP **hsep; struct SED *psed; CHAR *pchFprop; int cch;
Assert(fn != fnNil && (**hpfnfcb)[fn].fFormatted);
if ((pn = (**hpfnfcb)[fn].pnSetb) == (**hpfnfcb)[fn].pnBftb) return (struct SEP **) 0; psetbFile = (struct SETB *) PchGetPn(fn, pn, &cch, false); if (psetbFile->csed == 0) return (struct SEP **)0;
/* File has a section table; copy properties from first SEP */ hsep = (struct SEP **) HAllocate( cwSEP ); if (FNoHeap( hsep )) return (struct SEP **) hOverflow; blt( &vsepNormal, *hsep, cwSEP ); psed = &psetbFile->rgsed [0]; if (psed->fc == fcNil) return (struct SEP **)0; pchFprop = PchFromFc( fn, psed->fc, &cch ); if (*pchFprop != 0) { struct SEP *psep = *hsep;
bltbyte( pchFprop+1, psep, *pchFprop );
#ifndef FIXED_PAGE
/* Some of the section properties must be adjusted to the current page size
(stored in vsepNormal). */ if (psep->xaMac != vsepNormal.xaMac) { int dxa = vsepNormal.xaMac - psep->xaMac;
psep->xaMac += dxa; psep->dxaText = max(psep->dxaText + dxa, dxaMinUseful); psep->xaPgn += dxa; } if (psep->yaMac != vsepNormal.yaMac) { int dya = vsepNormal.yaMac - psep->yaMac;
psep->yaMac += dya; psep->dyaText = max(psep->dyaText + dya, dyaMinUseful); psep->yaRH2 += dya; } #endif /* not FIXED_PAGE */
} return hsep; } /* end of H s e p C r e a t e */
struct PGTB **HpgtbCreate(fn) int fn; { /* Create a page table from a formatted file */ struct PGTB *ppgtbFile; typePN pn; int cchT; int cpgd; struct PGTB **hpgtb; int *pwPgtb; int cw;
Assert(fn != fnNil && (**hpfnfcb)[fn].fFormatted);
if ((pn = (**hpfnfcb)[fn].pnBftb) == (**hpfnfcb)[fn].pnFfntb) return (struct PGTB **)0; ppgtbFile = (struct PGTB *) PchGetPn(fn, pn, &cchT, false); if ((cpgd = ppgtbFile->cpgd) == 0) return (struct PGTB **)0;
hpgtb = (struct PGTB **) HAllocate(cw = cwPgtbBase + cpgd * cwPGD); if (FNoHeap(hpgtb)) return (struct PGTB **)hOverflow;
pwPgtb = (int *) *hpgtb;
blt(ppgtbFile, pwPgtb, min(cwSector, cw));
while ((cw -= cwSector) > 0) { /* Copy the pgd's to heap */ blt(PchGetPn(fn, ++pn, &cchT, false), pwPgtb += cwSector, min(cwSector, cw)); }
(*hpgtb)->cpgdMax = cpgd; return hpgtb; } /* end of H p g t b C r e a t e */
int FnFromSz( sz ) /* filename is expected as ANSI */ CHAR *sz; { int fn; struct FCB *pfcb;
if (sz[0] == 0) return fnNil;
/* Mod for Sand: Only return fn if it is on the "current" volume (disk) */ for (fn = 0; fn < fnMac; fn++) if ((pfcb = &(**hpfnfcb)[fn])->rfn != rfnFree && (WCompSzC((PCH)sz, (PCH)**pfcb->hszFile) == 0) #ifdef SAND
&& (pfcb->vref == vrefFile) #endif /* SAND */
) return fn; return fnNil; } /* end of F n F r o m S z */
int FnOpenSz( szT, dty, fSearchPath ) /* filename is expected as ANSI */ CHAR *szT; int dty; int fSearchPath; { /* Open an existing file. Returns fnNil if not found */ int fn; struct FIB fib;
struct FCB *pfcb; CHAR (**hsz)[];
CHAR sz[cchMaxFile];
bltsz( szT, sz ); sz[cchMaxFile - 1] = 0;
#ifdef DFILE
CommSzSz("FnOpenSz: sz presumed ANSI = ",sz); #endif
if (sz[0]=='\0') return fnNil;
if ((fn = FnFromSz(sz)) != fnNil) { /* File is already open -- re-open it, in case it was changed by
another app */ FreeFn( fn ); }
if ((fn = FnAlloc()) == fnNil) return fnNil;
if (FNoHeap((hsz = HszCreate((PCH)sz)))) return fnNil;
pfcb = &(**hpfnfcb)[fn]; Assert( !pfcb->fSearchPath ); if (fSearchPath) pfcb->fSearchPath = TRUE; pfcb->mdFile = mdBinary; /* Try R/W first, will be smashed to RO if needed */ pfcb->dty = pfcb->mdExt = (dty == dtyNormNoExt) ? dtyNormal : dty; pfcb->hszFile = hsz;
{ OFSTRUCT of; SetErrorMode(1); if (OpenFile(sz, (LPOFSTRUCT) &of, OF_EXIST) == -1) /* this is much cleaner than FAccessFn() for check existance */ { char szMsg[cchMaxSz]; extern int vfInitializing; int fT = vfInitializing;
vfInitializing = FALSE; /* Report this err, even during inz */ MergeStrings ((of.nErrCode == dosxSharing) ? IDPMTCantShare:IDPMTCantOpen, sz, szMsg); IdPromptBoxSz(vhWndMsgBoxParent ? vhWndMsgBoxParent : hParentWw, szMsg, MB_OK|MB_ICONEXCLAMATION); vfInitializing = fT; FreeH( (**hpfnfcb) [fn].hszFile); return fnNil; } }
/* dtyNormNoExt is directed at this call */ if (!FAccessFn( fn, dty )) /* HM if error */ { FreeH( (**hpfnfcb) [fn].hszFile); return fnNil; }
/* kludge management (6.21.91) v-dougk */ dty = (dty == dtyNormNoExt) ? dtyNormal : dty;
Assert( (sizeof (struct FIB) == cfcPage) && (cfcPage == cbSector) ); Assert( pfcb == &(**hpfnfcb) [fn] ); /* No HM if FAccessFn succeeds */
if ( (CchReadAtPage( fn, (typePN) 0, (CHAR *) &fib, cbSector, TRUE ) != cbSector) || (fib.wTool != wMagicTool) ) { /* Not a formatted file */ typeFC fcMac = fc0; int cfc;
if (dty != dtyNormal) { char szMsg[cchMaxSz]; PchFillPchId( szMsg, IDPMTBadFile, sizeof(szMsg) ); if (MessageBox(hPARENTWINDOW, (LPSTR)szMsg, (LPSTR)szAppName, MB_ICONEXCLAMATION|MB_YESNO|MB_DEFBUTTON2) == IDNO) goto ErrRet; } pfcb->fFormatted = false;
/* Obtain file size by seeking to end-of-file */ if ((pfcb->fcMac = fcMac = FcMacFromUnformattedFn( fn )) == (typeFC) -1) /* Serious error while seeking to file's end */ goto ErrRet; pfcb->pnMac = (fcMac + cfcPage - 1) / cfcPage; } else { /* File is formatted; use stored fcMac, create run table */
if ((((fib.wIdent != wMagic) && (fib.wIdent != wOleMagic)) || (fib.dty != dty)) || // some bigwig media guy sent us a Write file whose fcMac was
// trashed (all else was OK). We gotta try to detect this obsure
// potentiality.
(fib.fcMac >= (typeFC)fib.pnPara*128 ) || (fib.fcMac > FcMacFromUnformattedFn( fn )) ) { /* Wrong type of file or corrupted file */ char szMsg[cchMaxSz]; PchFillPchId( szMsg, IDPMTBadFile, sizeof(szMsg) ); if (MessageBox(hPARENTWINDOW, (LPSTR)szMsg, (LPSTR)szAppName, MB_ICONEXCLAMATION|MB_YESNO|MB_DEFBUTTON2) == IDNO) goto ErrRet; }
if ((fib.wIdent == wOleMagic) && !fOleEnabled) Error(IDPMTFileContainsObjects);
if (fib.pnMac == (typePN)0) /* KLUDGE to load word files, which don't have ffntb entries. */ fib.pnMac = fib.pnFfntb;
pfcb->fFormatted = true; pfcb->fcMac = fib.fcMac; #ifdef p2bSector
pfcb->pnChar = (fib.fcMac + cfcPage - 1) / cfcPage; #else
pfcb->pnChar = (fib.fcMac + cfcPage - 1) / cfcPage; #endif
pfcb->pnPara = fib.pnPara; pfcb->pnFntb = fib.pnFntb; pfcb->pnSep = fib.pnSep;
pfcb->pnSetb = fib.pnSetb; pfcb->pnBftb = fib.pnBftb; pfcb->pnFfntb = fib.pnFfntb; pfcb->pnMac = fib.pnMac; if (dty != dtyPrd) { if (FNoHeap(hsz = HszCreate((PCH)fib.szSsht))) goto ErrRet; (**hpfnfcb)[fn].hszSsht = hsz; if (!FMakeRunTables(fn)) goto ErrRet; } }
return fn;
ErrRet: (pfcb = &(**hpfnfcb)[fn])->rfn = rfnFree; FreeH(pfcb->hszFile); return fnNil; } /* end of F n O p e n S z */
/*---------------------------------------------------------------------------
-- Routine: WCompSzC(psz1,psz2) -- Description and Usage: Alphabetically compares the two null-terminated strings psz1 and psz2. Upper case alpha characters are mapped to lower case. Comparison of non-alpha characters is by ascii code. Returns 0 if they are equal, a negative number if psz1 precedes psz2, and a non-zero positive number if psz2 precedes psz1. -- Arguments: psz1, psz2 - pointers to two null-terminated strings to compare -- Returns: a short - 0 if strings are equal, negative number if psz1 precedes psz2, and non-zero positive number if psz2 precedes psz1. -- Side-effects: none -- Bugs: -- History: 3/14/83 - created (tsr) ----------------------------------------------------------------------------*/ short WCompSzC(psz1,psz2) PCH psz1; PCH psz2; { int ch1; int ch2;
for(ch1=ChLowerC(*psz1++),ch2=ChLowerC(*psz2++); ch1==ch2; ch1=ChLowerC(*psz1++),ch2=ChLowerC(*psz2++)) { if(ch1 == '\0') return(0); } return(ch1-ch2); } /* end of W C o m p S z C */
/*---------------------------------------------------------------------------
-- Routine: ChLowerC(ch) -- Description and Usage: Converts its argument to lower case iff its argument is upper case. Returns the de-capitalized character or the initial char if it wasn't caps. -- Arguments: ch - character to be de-capitalized -- Returns: a character - initial character, de-capitalized if needed. -- Side-effects: -- Bugs: -- History: 3/14/83 - created (tsr) ----------------------------------------------------------------------------*/ int ChLowerC(ch) register CHAR ch; { if(isupper(ch)) return(ch + ('a' - 'A')); /* foreign is taken care of */ else return ch; } /* end of C h L o w e r C */
#ifdef JAPAN
// Compare ch with halfsize-KANA code range, then return whether it is or not.
BOOL IsKanaInDBCS(int ch) { ch &= 0x00ff; if(ch>=0xA1 && ch <= 0xDF) return TRUE; else return FALSE; } #endif
typeFC (**HgfcCollect(fn, pnFirst, pnLim))[] typePN pnFirst, pnLim; { /* Create a table indexing fc's by fkp number */ typeFC fcMac; typePN pn; int ifcMac, ifc; typeFC (**hgfc)[];
struct FKP fkp;
fcMac = (**hpfnfcb)[fn].fcMac; pn = pnFirst + 1; ifcMac = ifcMacInit; /* Length of table */ hgfc = (typeFC (**)[])HAllocate((ifcMacInit * sizeof(typeFC)) / sizeof(int)); if (FNoHeap(hgfc)) return (typeFC (**)[])hOverflow;
for (ifc = 0; ; ++ifc, ++pn) { /* Put first fcLim of each fkp in table */ if (ifc >= ifcMac) { /* Must grow table */ int cw = ((ifcMac += ifcMacInit) * sizeof (typeFC)) / sizeof(int); if (!FChngSizeH(hgfc, cw, false)) { LHFGCErrRet: FreeH(hgfc); return (typeFC (**)[])hOverflow; } } if (pn < pnLim) { /* Get fcLimFkb from fcFirst of next page */ int cch;
cch = CchReadAtPage( fn, pn, (CHAR *) &fkp, cbSector, TRUE ); if (cch != cfcPage) goto LHFGCErrRet; (**hgfc)[ifc] = fkp.fcFirst; } else { /* fcLimFkb is fcMac + 1 */ (**hgfc)[ifc] = fcMac + 1; if (!FChngSizeH(hgfc, ((ifc + 1) * sizeof(typeFC)) / sizeof(int), true)) { /* Previously ignored bad return value here ..pault 11/3/89 */ goto LHFGCErrRet; } return hgfc; } } } /* end of H g f c C o l l e c t */
/* F M A K E R U N T A B L E S */ int FMakeRunTables(fn) { /* Create two tables of fc-dpn pairs, one for chr's and one for par's */ typeFC (**hgfc)[];
if (FNoHeap(hgfc = HgfcCollect(fn, (**hpfnfcb)[fn].pnChar, (**hpfnfcb)[fn].pnPara))) return false; (**hpfnfcb)[fn].hgfcChp = hgfc; if (FNoHeap(hgfc = HgfcCollect(fn, (**hpfnfcb)[fn].pnPara, (**hpfnfcb)[fn].pnFntb))) { FreeH( (**hpfnfcb) [fn].hgfcChp ); return false; } (**hpfnfcb)[fn].hgfcPap = hgfc; return true; } /* end of F M a k e R u n T a b l e */
FApplyOldWordSprm(doc) /* applies a sprm to this doc which causes all "old word" fonts to be remapped
into new windows ones */ { CHAR rgbSprm[7]; extern int vfSysFull;
/* set up the OldFtc sprm mapping */ rgbSprm[0] = sprmCOldFtc; rgbSprm[1] = 5;
rgbSprm[2 + iftcModern] = FtcScanDocFfn(doc, PffnDefault(FF_MODERN)); rgbSprm[2 + iftcRoman] = FtcScanDocFfn(doc, PffnDefault(FF_ROMAN)); rgbSprm[2 + iftcScript] = FtcScanDocFfn(doc, PffnDefault(FF_SCRIPT)); rgbSprm[2 + iftcDecorative] = FtcScanDocFfn(doc, PffnDefault(FF_DECORATIVE)); rgbSprm[2 + iftcSwiss] = FtcScanDocFfn(doc, PffnDefault(FF_SWISS));
AddSprmCps(rgbSprm, doc, (typeCP)0, (**hpdocdod)[doc].cpMac); return(vfSysFull == 0); }
|