Source code of Windows XP (NT5)
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.

1852 lines
49 KiB

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1992 Microsoft Corporation */
  3. /************************************************************/
  4. /* trans3.c: more save routines, moved here from trans2.c because of compiler
  5. heap space errors */
  6. #define NOVIRTUALKEYCODES
  7. #define NOWINSTYLES
  8. #define NOCLIPBOARD
  9. #define NOGDICAPMASKS
  10. #define NOSYSMETRICS
  11. #define NOMENUS
  12. #define NOMSG
  13. #define NOKEYSTATE
  14. #define NOSHOWWINDOW
  15. //#define NOGDI
  16. #define NOFONT
  17. #define NOBRUSH
  18. #define NOBITMAP
  19. //#define NOATOM
  20. #define NOMETAFILE
  21. #define NOPEN
  22. #define NOPOINT
  23. #define NORECT
  24. #define NOREGION
  25. #define NOHRGN
  26. #define NOCOLOR
  27. #define NODRAWTEXT
  28. //#define NOTEXTMETRIC
  29. #define NOWINOFFSETS
  30. #define NOCREATESTRUCT
  31. #define NOWH
  32. #define NOSOUND
  33. #define NOSCROLL
  34. #define NOCOMM
  35. #define NOWNDCLASS
  36. /* need memmgr, mb */
  37. #include <windows.h>
  38. #include "mw.h"
  39. #include "doslib.h"
  40. #include "cmddefs.h"
  41. #include "docdefs.h"
  42. #include "filedefs.h"
  43. #include "editdefs.h"
  44. #include "printdef.h"
  45. #define NOSTRUNDO
  46. #include "str.h"
  47. #include "debug.h"
  48. #include "fontdefs.h"
  49. #include "dlgdefs.h"
  50. #include "winddefs.h"
  51. #include "macro.h"
  52. #include "preload.h"
  53. #include "io.h"
  54. #if defined(OLE)
  55. #include "obj.h"
  56. #endif
  57. #define WRITE_PERMISSION 02 /* flag to access() */
  58. CHAR *index( CHAR *, CHAR );
  59. CHAR *PchGetPn();
  60. CHAR *PchFromFc();
  61. static int fOpenedFormatted = TRUE;
  62. int vfOldWriteFmt=FALSE; /* delete objects before saving */
  63. DoFileOpen( LPSTR );
  64. BOOL CheckEnableButton(HANDLE, HANDLE);
  65. BOOL NEAR PASCAL CanReadEveryFile(char *szFilename);
  66. extern CHAR szExtSearch[]; /* store default search spec */
  67. extern CHAR szWriteProduct[];
  68. extern CHAR szBackup[];
  69. extern int vfTextOnlySave;
  70. extern int vfCursorVisible;
  71. extern int vfDiskError;
  72. extern int vfSysFull;
  73. extern HWND vhWndMsgBoxParent;
  74. extern int vfnWriting;
  75. extern CHAR (**vhrgbSave)[];
  76. extern struct DOD (**hpdocdod)[];
  77. extern int docCur;
  78. extern int docScrap;
  79. extern int docUndo;
  80. extern struct FCB (**hpfnfcb)[];
  81. extern int vfBuffersDirty;
  82. extern int vfDiskFull;
  83. extern typeCP vcpFetch;
  84. extern CHAR *vpchFetch;
  85. extern int vccpFetch;
  86. extern typeCP vcpLimParaCache;
  87. extern int vfDeactByOtherApp;
  88. extern BOOL vfWarnMargins;
  89. #ifdef INTL /* International version */
  90. extern int vWordFmtMode;
  91. #ifdef INEFFLOCKDOWN
  92. extern FARPROC lpDialogWordCvt;
  93. #else
  94. extern BOOL far PASCAL DialogWordCvt(HWND, unsigned, WORD, LONG);
  95. #endif
  96. #endif /* International version */
  97. static unsigned wMerge; /* for message merge code */
  98. extern int vfBackupSave;
  99. extern int ferror;
  100. extern CHAR szExtBackup[];
  101. extern CHAR (**hszTemp)[];
  102. #ifdef INEFFLOCKDOWN
  103. extern FARPROC lpDialogOpen;
  104. extern FARPROC lpDialogSaveAs;
  105. #endif
  106. extern HANDLE hMmwModInstance;
  107. extern HANDLE hParentWw;
  108. extern HCURSOR vhcHourGlass;
  109. extern HCURSOR vhcIBeam;
  110. extern HCURSOR vhcArrow;
  111. /* Used in this module only */
  112. static CHAR *pchSet;
  113. static CHAR szUser[ cchMaxFile ]; /* store whatever is in idiOpenFile (ANSI) */
  114. #define SF_OLDWRITE 0
  115. #define SF_WORD 1
  116. BOOL WannaDeletePictures(int doc, int fWhichFormat);
  117. BOOL DocHasPictures(int doc);
  118. NEAR DlgAddCorrectExtension(CHAR *, int);
  119. BOOL (NEAR FSearchSpec(CHAR *));
  120. BOOL far PASCAL DialogOpen(HWND, unsigned, WORD, LONG);
  121. BOOL far PASCAL DialogSaveAs(HWND, unsigned, WORD, LONG);
  122. #ifdef INTL /* International version */
  123. BOOL FInWordFormat(int);
  124. void ConvertFromWord();
  125. #endif /* International version */
  126. fnOpenFile(LPSTR lpstrFileName) // filename may be NULL
  127. {
  128. extern int vfCloseFilesInDialog;
  129. extern int docCur;
  130. extern HANDLE hMmwModInstance;
  131. extern HANDLE hParentWw;
  132. extern struct SEL selCur;
  133. extern typeCP cpMinDocument;
  134. /* Close all files on removable media for every message we get */
  135. vfCloseFilesInDialog = TRUE;
  136. /* Close all files on removable media so changing disks is safe */
  137. CloseEveryRfn( TRUE );
  138. /* test for dirty file and offer opportunity to save */
  139. if (FConfirmSave())
  140. DoFileOpen(lpstrFileName);
  141. vfCloseFilesInDialog = FALSE;
  142. }
  143. DoFileOpen( LPSTR lpstrFileName ) // filename may be NULL )
  144. {
  145. /* return whether error. Use CommDlg for open dialog (3.8.91) D. Kent */
  146. /* ********* International version changes bz 2/21/86 *************
  147. For files opened in Word format and converted to Write format
  148. the following changes are made:
  149. the vWordFmtMode flag is left set to CONVFROMWORD. The file is
  150. saved, effecting the change to Word format, but the original
  151. Word file in not renamed, so it is left untouched, with no need to
  152. make a backup. On the next save, we ask if the file with that name
  153. (the Word document) should be replaced, so any file with that
  154. name that existed will be protected.
  155. *************************************************************** */
  156. extern int vfDiskError;
  157. int fn=fnNil;
  158. int doc;
  159. CHAR (**hsz)[] = NULL;
  160. int nRetval=FALSE;
  161. CHAR rgch[cchMaxFile];
  162. extern DoOpenFilenameGet(LPSTR);
  163. BOOL bOpened=TRUE, // ObjOpenedDoc has succeeded
  164. bCancelled=FALSE;
  165. #ifdef INTL /* International version */
  166. int fWordDoc;
  167. #endif /* International version */
  168. EnableOtherModeless(FALSE);
  169. /* prevent WM_PAINT from painting a doc that isn't defined */
  170. while(1)
  171. {
  172. bCancelled = FALSE;
  173. if (lpstrFileName)
  174. lstrcpy(rgch,lpstrFileName);
  175. else if (!DoOpenFilenameGet(rgch))
  176. {
  177. bCancelled = TRUE;
  178. goto KeepTrying;
  179. }
  180. else if (rgch[0] == '\0')
  181. {
  182. bCancelled = TRUE;
  183. goto KeepTrying;
  184. }
  185. #if defined(OLE)
  186. if (bOpened)
  187. if (ObjClosingDoc(docCur,rgch))
  188. /*
  189. If this failed, then we could't close this document, much less
  190. open a new one.
  191. */
  192. break; // from while
  193. else
  194. /**
  195. At this point, docCur is OLE-closed!!! Gotta be sure we
  196. open a new one!!!
  197. **/
  198. bOpened = FALSE;
  199. #endif
  200. if ((fn = FnOpenSz( rgch, dtyNormNoExt, FALSE)) == fnNil)
  201. /* this has side effect of setting &(**(**hpfnfcb) [fn].hszFile) [0]
  202. to "normalized" filename. */
  203. {
  204. /* Open failed */
  205. goto KeepTrying;
  206. }
  207. else
  208. { /* Opened file OK */
  209. /* Set caption to "Loading file..." */
  210. extern CHAR szLoadFile[];
  211. extern CHAR szCvtLoadFile[];
  212. #ifdef INTL /* International version */
  213. /* **************************************
  214. * added check for international version to
  215. do Word format conversion. If Word format,
  216. bring up another dialog box.
  217. * ************************************** */
  218. /* TestWordCvt return values:
  219. -1 means dialog box failed (error already sent)
  220. -2 means cancel without conversion.
  221. FALSE means not a word document.
  222. TRUE means convert this word document.
  223. *** as of 2/14/86, we changed the conversion
  224. to not make a backup, but to save the file
  225. in write format without renaming the Word
  226. file, so the word file is effectively
  227. backed up under its original name. See
  228. CleanDoc in trans2.c for explanations.
  229. */
  230. switch ((fWordDoc = TestWordCvt (fn, hParentWw)))
  231. {
  232. case -2: // CANCEL
  233. bCancelled = TRUE;
  234. // fall through..
  235. case -1: // ERROR
  236. /* Release this fn! */
  237. FreeFn(fn);
  238. CloseEveryRfn( TRUE );
  239. goto KeepTrying;
  240. }
  241. /* if true, will convert soon */
  242. if (fWordDoc)
  243. {
  244. SetWindowText(hParentWw, (LPSTR)szCvtLoadFile);
  245. }
  246. else
  247. #endif /* International version */
  248. SetWindowText(hParentWw, (LPSTR)szLoadFile);
  249. StartLongOp();
  250. ReadFilePages( fn );
  251. }
  252. Assert( fn != fnNil );
  253. bltsz( &(**(**hpfnfcb) [fn].hszFile) [0], rgch );
  254. CchCopySz(rgch, szUser);
  255. hsz=NULL;
  256. if ( !FNoHeap(hsz = HszCreate( (PCH) rgch )) )
  257. {
  258. if ((doc = DocCreate( fn, hsz, dtyNormal )) != docNil)
  259. { /* Succeeded in creating document */
  260. KillDoc( docCur );
  261. docCur = doc;
  262. hsz = NULL; // don't free cause used by doc
  263. #ifdef INTL /* International version */
  264. /* if a word document to be converted, save it doing conversion. */
  265. if (fWordDoc)
  266. {
  267. /* save file in write format. */
  268. ConvertFromWord();
  269. vfTextOnlySave = FALSE;
  270. (**hpdocdod)[docCur].fDirty = TRUE;
  271. }
  272. #endif /* International version */
  273. ChangeWwDoc( szUser );
  274. /* Ensure that the margins of this document is right
  275. for the printer. */
  276. vfWarnMargins = TRUE;
  277. SetPageSize();
  278. vfWarnMargins = FALSE;
  279. #if defined(OLE)
  280. if (ObjOpenedDoc(docCur))
  281. /* Couldn't open. Must try to open a new one */
  282. goto KeepTrying;
  283. else
  284. {
  285. bOpened = TRUE;
  286. break; // from while loop 'cause we're done
  287. }
  288. #endif
  289. }
  290. #if defined(JAPAN) || defined(KOREA) // added 10 Jun. 1992 by Hiraisi
  291. else{
  292. bCancelled = TRUE;
  293. goto KeepTrying;
  294. }
  295. #endif
  296. }
  297. KeepTrying:
  298. /* get to here either because error or cancelled */
  299. vfDiskError = ferror = FALSE;
  300. SetTitle( **(**hpdocdod)[ docCur ].hszFile );
  301. if (hsz)
  302. {
  303. FreeH( hsz );
  304. hsz=NULL;
  305. }
  306. CloseEveryRfn( TRUE );
  307. EndLongOp(vhcArrow);
  308. if (bCancelled)
  309. /* can't cancel unless we have an opened document */
  310. {
  311. if (!bOpened) // currently no open doc
  312. {
  313. if (bOpened = !ObjOpenedDoc(docCur)) // returns FALSE if success
  314. break;
  315. }
  316. else
  317. break;
  318. }
  319. } // end of while(1)
  320. #if WINVER >= 0x300
  321. FreeUnreferencedFns();
  322. #endif
  323. EndLongOp(vhcArrow);
  324. EnableOtherModeless(TRUE);
  325. return !bOpened;
  326. } /* end of DoFileOpen */
  327. fnSave()
  328. { /* Entry point for the "Save" command */
  329. extern int vfCloseFilesInDialog;
  330. extern int vfOutOfMemory;
  331. extern HANDLE vhReservedSpace;
  332. struct DOD *pdod = &(**hpdocdod)[docCur];
  333. CHAR *psz = &(**(pdod->hszFile))[0];
  334. if (!CanReadEveryFile(psz))
  335. return;
  336. #if WINVER >= 0x300
  337. if (pdod->fReadOnly)
  338. {
  339. /* Read-only doc: tell the user to save under a different name */
  340. Error( IDPMTReadOnly );
  341. ferror = FALSE; /* Not really an error */
  342. fnSaveAs(); /* May as well take them there now! ..pault 10/20/89 */
  343. }
  344. else if (psz [0] == '\0' || vWordFmtMode == CONVFROMWORD)
  345. /* Any time the user has converted the current Write document
  346. from a Word or Text document, we force them through the
  347. FileSaveAs dlg box when Saving. In this way we remind them
  348. that they might want to change the name -- but if they don't
  349. want to, that's ok and we'll not bother them any more about it
  350. (fnSaveAs dialog box will reset vWordFmtMode) ..pault 9/18/89 */
  351. #else /* old windows */
  352. else if (psz [0] == '\0')
  353. #endif
  354. fnSaveAs();
  355. else
  356. {
  357. if (vfOldWriteFmt || (vWordFmtMode & ~CONVFROMWORD) || vfTextOnlySave)
  358. /* then deleting pictures */
  359. {
  360. if (vfOldWriteFmt || vfTextOnlySave)
  361. vcObjects = ObjEnumInDoc(docCur,NULL);
  362. if (!WannaDeletePictures(docCur,vfOldWriteFmt ? SF_OLDWRITE : SF_WORD))
  363. return;
  364. }
  365. vfCloseFilesInDialog = TRUE;
  366. /* Close all files on removable media so changing disks is safe */
  367. CloseEveryRfn( TRUE );
  368. /* Free the reserved block, to give us memory for the save dialog box
  369. and for CmdXfSave */
  370. if (vhReservedSpace != NULL)
  371. {
  372. LocalFree(vhReservedSpace);
  373. vhReservedSpace = NULL;
  374. }
  375. PreloadSaveSegs(); /* Advance loading of code to avoid disk swaps */
  376. CmdXfSave(psz, pdod->fFormatted, pdod->fBackup, vhcIBeam);
  377. if (vfDiskFull || vfSysFull)
  378. ferror = FALSE;
  379. #if defined(OLE)
  380. else
  381. ObjSavedDoc();
  382. #endif
  383. if ((vhReservedSpace = LocalAlloc( LHND, cbReserve )) == NULL)
  384. /* we were unable to re-establish our block of reserved space. */
  385. Error(IDPMTNoMemory);
  386. vfCloseFilesInDialog = FALSE;
  387. }
  388. }
  389. fnSaveAs()
  390. { /* Entry point for the "Save As..." command */
  391. extern int vfCloseFilesInDialog;
  392. extern int vfOutOfMemory;
  393. extern HANDLE vhReservedSpace;
  394. if (!CanReadEveryFile((**((**hpdocdod)[docCur].hszFile))))
  395. return;
  396. vfCloseFilesInDialog = TRUE;
  397. /* Close all files on removable media so changing disks is safe */
  398. CloseEveryRfn( TRUE );
  399. /* Free the reserved block, to give us memory for the save dialog box
  400. and for CmdXfSave */
  401. if (vhReservedSpace != NULL)
  402. {
  403. LocalFree(vhReservedSpace);
  404. vhReservedSpace = NULL;
  405. }
  406. PreloadSaveSegs(); /* Advance loading of code to avoid disk swaps */
  407. DoFileSaveAs();
  408. if ((vhReservedSpace = LocalAlloc( LHND, cbReserve )) == NULL)
  409. { /* Either we were unable to bring up the save dialog
  410. box, or we were unable to re-establish our
  411. block of reserved space. */
  412. #if WINVER >= 0x300
  413. WinFailure();
  414. #else
  415. Error(IDPMTNoMemory);
  416. #endif
  417. }
  418. UpdateInvalid(); /* Assure screen gets updated */
  419. vfCloseFilesInDialog = FALSE;
  420. }
  421. DoFileSaveAs(void)
  422. {
  423. /* This routine handles input to the Save dialog box. */
  424. static CHAR szDefault[ cchMaxFile ];
  425. extern int vfTextOnlySave;
  426. extern DoSaveAsFilenameGet(LPSTR,LPSTR,int *,int *,int * ,int *);
  427. BOOL bDontDelPictures=FALSE;
  428. int fWordFmt, fTextOnly, fBackup, fOldWrite;
  429. CHAR szFullNameNewDoc[ cchMaxFile ]; // full name of selection
  430. CHAR szShortNameNewDoc[ cchMaxFile ]; // file name of selection
  431. CHAR szDocName[ cchMaxFile ]; // file name of current
  432. #define szFullNameCurDoc (**((**hpdocdod)[docCur].hszFile)) // full name of current
  433. #define pDod ((struct DOD *)&(**hpdocdod)[docCur])
  434. {
  435. int cch = 0;
  436. CHAR szDOSPath[ cchMaxFile ];
  437. if (FNormSzFile( szDOSPath, "", dtyNormal ))
  438. {
  439. if ((cch=CchSz( szDOSPath )-2) > 2)
  440. {
  441. Assert( szDOSPath[ cch ] == '\\');
  442. szDOSPath [cch] = '\0';
  443. }
  444. #if 0
  445. if (cch > 3)
  446. szDOSPath [cch] = '\\';
  447. #endif
  448. }
  449. else
  450. szDOSPath[0] = '\0';
  451. if (szFullNameCurDoc [0] != '\0')
  452. { /* Set default string for filename edit area */
  453. CHAR szDocPath[ cchMaxFile ]; // path to current
  454. FreezeHp();
  455. SplitSzFilename( szFullNameCurDoc, szDocPath, szDocName );
  456. /* Default filename does not include the document's path if
  457. it is == the current directory path */
  458. if (WCompSz( szDOSPath, szDocPath ) == 0)
  459. bltsz(szDocName, szDefault);
  460. else
  461. bltsz(szFullNameCurDoc, szDefault);
  462. MeltHp();
  463. }
  464. else
  465. {
  466. szDefault[0] = szDocName[0] = '\0';
  467. }
  468. }
  469. fTextOnly = vfTextOnlySave;
  470. fBackup = vfBackupSave;
  471. fWordFmt = vWordFmtMode & ~CONVFROMWORD;
  472. fOldWrite = vfOldWriteFmt;
  473. EnableOtherModeless(FALSE);
  474. while(1)
  475. {
  476. if (!DoSaveAsFilenameGet(szDefault,szFullNameNewDoc,&fBackup,&fTextOnly,&fWordFmt,&fOldWrite))
  477. goto end;
  478. else
  479. {
  480. int dty;
  481. if (szFullNameNewDoc[0] == '\0')
  482. goto end;
  483. if (fOldWrite || fWordFmt || fTextOnly)
  484. {
  485. if (!WannaDeletePictures(docCur,fOldWrite ? SF_OLDWRITE : SF_WORD))
  486. continue;
  487. }
  488. StartLongOp();
  489. szFileExtract(szFullNameNewDoc, szShortNameNewDoc);
  490. #ifdef INTL /* International version */
  491. /* Read the "Microsoft Word Format" button */
  492. /* vWordFmtMode is used in WriteFn. If true, will convert
  493. to Word format, if false, no conversion is done.
  494. Another value, CONVFROMWORD, can be given during an open
  495. to allow saving a Word document in Write format. */
  496. if (fWordFmt)
  497. /* if set, make the default extension be doc instead of
  498. wri for word docs */
  499. dty = dtyWordDoc;
  500. else
  501. #endif /* International version */
  502. dty = dtyNormal;
  503. #if WINVER >= 0x300
  504. /* Currently: FNormSzFile *TAKES* an OEM sz, and
  505. *RETURNS* an ANSI sz ..pault */
  506. #endif
  507. if ( pDod->fReadOnly &&
  508. WCompSz( szFullNameNewDoc, szFullNameCurDoc ) == 0)
  509. { /* Must save read-only file under a different name */
  510. Error( IDPMTReadOnly );
  511. goto NSerious; /* Error not serious, stay in dialog */
  512. }
  513. #if WINVER >= 0x300
  514. else if (WCompSz(szFullNameCurDoc, szFullNameNewDoc) == 0 &&
  515. vWordFmtMode == CONVFROMWORD &&
  516. vfTextOnlySave == fTextOnly)
  517. /* User has loaded a text file and is going
  518. to save under the same name without changing
  519. formats, *OR* has loaded a Word document and
  520. is going to save in the same format -- don't
  521. prompt "replace file?" ..pault 1/17/90 */
  522. ;
  523. #endif
  524. else if ((WCompSz(szFullNameCurDoc, szFullNameNewDoc) != 0
  525. #ifdef INTL /* International version */
  526. /* vWordFmtMode hasn't be reset yet */
  527. || ( vWordFmtMode == CONVFROMWORD)
  528. #endif /* International version */
  529. )
  530. && FExistsSzFile( dtyNormal, szFullNameNewDoc ) )
  531. {
  532. /* User changed the default string and specified
  533. a filename for which the file already exists.
  534. Or, we did a Word format conversion, forcing the .WRI
  535. extension on the file, and a file with that name
  536. exists.(International version only).o
  537. Note that vfWordFmtMode will be set to True or False
  538. below, so this check is made only on the first save
  539. after a Word conversion.
  540. Prompt to make sure it's ok to trash the existing one */
  541. CHAR szFileUp[ cchMaxFile ];
  542. CHAR szUserOEM[cchMaxFile]; /* ..converted to OEM */
  543. CHAR szT[ cchMaxSz ];
  544. CchCopyUpperSz( szShortNameNewDoc, szFileUp );
  545. MergeStrings (IDSTRReplaceFile, szFileUp, szT);
  546. #if WINVER >= 0x300
  547. /* access() expects OEM! */
  548. AnsiToOem((LPSTR) szFullNameNewDoc, (LPSTR) szUserOEM);
  549. /* Make sure we don't let someone try to save to
  550. a file to which we do not have r/w permission */
  551. Diag(CommSzNum("fnSaveAs: access(write_perm)==", access(szUserOEM, WRITE_PERMISSION)));
  552. Diag(CommSzNum(" szExists()==", FExistsSzFile( dtyNormal, szFullNameNewDoc )));
  553. if (access(szUserOEM, WRITE_PERMISSION) == -1)
  554. {
  555. /* THIS COULD BE A CASE OF WRITING TO A FILE
  556. WITH R/O ATTRIBUTE, *OR* A SHARING ERROR!
  557. IMPROVE ERROR MESSAGE HERE ..pault 11/2/89 */
  558. //Error( IDPMTSDE2 );
  559. Error( IDPMTReadOnly );
  560. goto NSerious; /* Error not serious, stay in dialog */
  561. }
  562. #endif
  563. }
  564. vfTextOnlySave = fTextOnly;
  565. vfBackupSave = fBackup;
  566. vfOldWriteFmt = fOldWrite;
  567. #ifdef INTL /* International version */
  568. /* vWordFmtMode is used in WriteFn. If true, will convert
  569. to Word format, if false, no conversion is done.
  570. Another value, CONVFROMWORD, can be given during an open
  571. to allow saving a Word document in Write format. */
  572. vWordFmtMode = fWordFmt;
  573. #endif /* International version */
  574. /* Record whether a backup was made or not. */
  575. WriteProfileString( (LPSTR)szWriteProduct, (LPSTR)szBackup,
  576. vfBackupSave ? (LPSTR)"1" : (LPSTR)"0" );
  577. /* Save the document */
  578. CmdXfSave( szFullNameNewDoc,!vfTextOnlySave, vfBackupSave, vhcArrow);
  579. if (vfDiskFull || vfSysFull)
  580. goto NSerious;
  581. /* Case 1: Serious error. Leave the dialog. */
  582. if (vfDiskError)
  583. {
  584. EndLongOp( vhcArrow );
  585. goto end;
  586. }
  587. /* Case 2: Saved OK: set the new title, leave the dialog. */
  588. else if (!WCompSz( szFullNameNewDoc, szFullNameCurDoc ))
  589. {
  590. #if defined(OLE)
  591. ObjRenamedDoc(szFullNameNewDoc);
  592. ObjSavedDoc();
  593. #endif
  594. SetTitle(szShortNameNewDoc);
  595. #if WINVER >= 0x300
  596. FreeUnreferencedFns();
  597. #endif
  598. /* Update the fReadOnly attribute (9.10.91) v-dougk */
  599. pDod->fReadOnly = FALSE; // can't be readonly if just saved
  600. EndLongOp( vhcArrow );
  601. goto end;
  602. }
  603. /* Case 3: Nonserious error (disk full, bad path, etc.).
  604. stay in dialog. */
  605. else
  606. {
  607. NSerious:
  608. ferror = FALSE;
  609. EndLongOp( vhcArrow );
  610. StayInDialog:
  611. CloseEveryRfn( TRUE );
  612. }
  613. }
  614. } // end of while(1)
  615. end:
  616. EnableOtherModeless(FALSE);
  617. } /* end of DoFileSaveAs */
  618. #ifdef INTL /* International version */
  619. BOOL far PASCAL DialogWordCvt( hDlg, code, wParam, lParam )
  620. HWND hDlg; /* Handle to the dialog box */
  621. unsigned code;
  622. WORD wParam;
  623. LONG lParam;
  624. {
  625. /* This routine handles input to the Convert From Word Format dialog box. */
  626. switch (code) {
  627. case WM_INITDIALOG:
  628. {
  629. char szFileDescrip[cchMaxSz];
  630. char szPrompt[cchMaxSz];
  631. /* do not allow no convert for formatted file */
  632. if (fOpenedFormatted)
  633. {
  634. //EnableWindow(GetDlgItem(hDlg, idiNo), false);
  635. PchFillPchId(szFileDescrip, IDSTRConvertWord, sizeof(szFileDescrip));
  636. }
  637. else
  638. PchFillPchId(szFileDescrip, IDSTRConvertText, sizeof(szFileDescrip));
  639. MergeStrings(IDPMTConvert, szFileDescrip, szPrompt);
  640. SetDlgItemText(hDlg, idiConvertPrompt, (LPSTR)szPrompt);
  641. EnableOtherModeless(FALSE);
  642. break;
  643. }
  644. case WM_SETVISIBLE:
  645. if (wParam)
  646. EndLongOp(vhcArrow);
  647. return(FALSE);
  648. case WM_ACTIVATE:
  649. if (wParam)
  650. vhWndMsgBoxParent = hDlg;
  651. if (vfCursorVisible)
  652. ShowCursor(wParam);
  653. return(FALSE); /* so that we leave the activate message to the dialog
  654. manager to take care of setting the focus correctly */
  655. case WM_COMMAND:
  656. switch (wParam) {
  657. /* return one of these values:
  658. idiOk - convert
  659. idiCancel - cancel, no conversion
  660. idiNo - read in without conversion */
  661. case idiNo: /* User hit the "No Conversion" button */
  662. if (!IsWindowEnabled(GetDlgItem(hDlg, idiNo)))
  663. /* No convert is grayed -- ignore */
  664. return(TRUE);
  665. /* fall in */
  666. case idiOk: /* User hit the "Convert" button */
  667. case idiCancel:
  668. break;
  669. default:
  670. return(FALSE);
  671. }
  672. /* here after ok, cancel, no */
  673. OurEndDialog(hDlg, wParam);
  674. break;
  675. default:
  676. return(FALSE);
  677. }
  678. return(TRUE);
  679. } /* end of DialogWordCvt */
  680. /* International version */
  681. #else
  682. BOOL far PASCAL DialogWordCvt( hDlg, code, wParam, lParam )
  683. HWND hDlg; /* Handle to the dialog box */
  684. unsigned code;
  685. WORD wParam;
  686. LONG lParam;
  687. {
  688. Assert(FALSE);
  689. } /* end of DialogWordCvt */
  690. #endif /* Non Iternational version */
  691. IdConfirmDirty()
  692. { /* Put up a message box saying docCur "Has changed. Save changes?
  693. Yes/No/Cancel". Return IDYES, IDNO, or IDCANCEL. */
  694. extern HWND vhWnd;
  695. extern CHAR szUntitled[];
  696. extern HANDLE hszDirtyDoc;
  697. LPSTR szTmp = MAKELP(hszDirtyDoc,0);
  698. CHAR szPath[ cchMaxFile ];
  699. CHAR szName[ cchMaxFile ];
  700. CHAR szMsg[ cchMaxSz ];
  701. CHAR (**hszFile)[]=(**hpdocdod)[docCur].hszFile;
  702. if ((**hszFile)[0] == '\0')
  703. CchCopySz( szUntitled, szName );
  704. else
  705. SplitSzFilename( *hszFile, szPath, szName );
  706. wsprintf(szMsg,szTmp,(LPSTR)szName);
  707. return IdPromptBoxSz( vhWnd, szMsg, MB_YESNOCANCEL | MB_ICONEXCLAMATION );
  708. }
  709. SplitSzFilename( szFile, szPath, szName )
  710. CHAR *szFile;
  711. CHAR *szPath;
  712. CHAR *szName;
  713. { /* Split a normalized filename into path and bare name components.
  714. By the rules of normalized filenames, the path will have a drive
  715. letter, and the name will have an extension. If the name is null,
  716. we provide the default DOS path and a null szName */
  717. szPath [0] = '\0';
  718. szName [0] = '\0';
  719. if (szFile[0] == '\0')
  720. {
  721. #if WINVER >= 0x300
  722. /* Currently: FNormSzFile *TAKES* an OEM sz, and
  723. *RETURNS* an ANSI sz ..pault */
  724. #endif
  725. FNormSzFile( szPath, "", dtyNormal ); /* Use default DOS drive & path */
  726. }
  727. else
  728. {
  729. CHAR *pch;
  730. int cch;
  731. lstrcpy(szPath,(LPSTR)szFile);
  732. pch = szPath + lstrlen(szPath) - 1; // point to last character
  733. #ifdef DBCS
  734. while (pch != szPath) {
  735. CHAR *szptr;
  736. szptr = (CHAR near *)AnsiPrev(szPath,pch);
  737. if (*szptr == '\\')
  738. break;
  739. else
  740. pch = szptr;
  741. }
  742. #else /* DBCS */
  743. while (pch != szPath)
  744. if (*(pch-1) == '\\')
  745. break;
  746. else
  747. --pch;
  748. #endif
  749. lstrcpy(szName,(LPSTR)pch);
  750. #ifdef DBCS
  751. #if !defined(TAIWAN) && !defined(PRC)
  752. pch=(CHAR near *)AnsiPrev(szPath,pch);
  753. *pch = '\0';
  754. #endif
  755. #else
  756. *(pch-1) = '\0';
  757. #endif
  758. }
  759. }
  760. BOOL CheckEnableButton(hCtlEdit, hCtlEnable)
  761. HANDLE hCtlEdit; /* handle to edit item */
  762. HANDLE hCtlEnable; /* handle to control which is to enable or disable */
  763. {
  764. register BOOL fEnable = SendMessage(hCtlEdit, WM_GETTEXTLENGTH, 0, 0L);
  765. EnableWindow(hCtlEnable, fEnable);
  766. return(fEnable);
  767. } /* end of CheckEnableButton */
  768. /*** FDeleteFn - Delete a file
  769. *
  770. *
  771. *
  772. */
  773. int FDeleteFn(fn)
  774. int fn;
  775. { /* Delete a file & free its fn slot */
  776. /* Returns TRUE if the file was successfully deleted or if it was not
  777. found in the first place; FALSE if the file exists but
  778. cannot be deleted */
  779. int f = FALSE;
  780. if (FEnsureOnLineFn( fn )) /* Ensure disk w/ file is in drive */
  781. {
  782. CloseFn( fn ); /* Ensure file closed */
  783. f = FDeleteFile( &(**(**hpfnfcb) [fn].hszFile) [0] );
  784. }
  785. FreeFn( fn ); /* We free the fn even if the file delete failed */
  786. return f;
  787. }
  788. FDeleteFile( szFileName )
  789. CHAR szFileName[];
  790. { /* Delete szFilename. Return TRUE if the file was deleted,
  791. or there was no file by that name; FALSE otherwise.
  792. Before deleting the file, we ask all other WRITE instances whether
  793. they need it; if one does, we do not delete and return FALSE */
  794. HANDLE HszGlobalCreate( CHAR * );
  795. int fpe=0;
  796. int fOk;
  797. ATOM a;
  798. if ((a = GlobalAddAtom( szFileName )) != NULL)
  799. {
  800. fOk = WBroadcastMsg( wWndMsgDeleteFile, a, (LONG) 0, FALSE );
  801. if (fOk)
  802. { /* Ok to delete, no other instance needs it */
  803. fpe = FpeDeleteSzFfname( szFileName );
  804. }
  805. #ifdef DEBUG
  806. else
  807. Assert( !FIsErrFpe( fpe ) );
  808. #endif
  809. GlobalDeleteAtom( a );
  810. }
  811. /* OK if: (1) Deleted OK (2) Error was "File not found" */
  812. return (!FIsErrFpe(fpe)) || fpe == fpeFnfError;
  813. }
  814. FDeleteFileMessage( a )
  815. ATOM a;
  816. { /* We are being notified that the file hName is being deleted.
  817. a is a global atom. (Was global handle before fixing for NT 3.5)
  818. Return TRUE = Ok to delete; FALSE = Don't delete, this instance
  819. needs the file */
  820. LPCH lpch;
  821. CHAR sz[ cchMaxFile ];
  822. Scribble( 5, 'D' );
  823. if (GlobalGetAtomName( a, sz, sizeof(sz)) != 0)
  824. {
  825. if (FnFromSz( sz ) != fnNil)
  826. {
  827. Scribble( 4, 'F' );
  828. return FALSE;
  829. }
  830. }
  831. Scribble( 4, 'T' );
  832. return TRUE;
  833. }
  834. /*** FpeRenameFile - rename a file
  835. *
  836. */
  837. int FpeRenameFile(szFileCur, szFileNew) /* Both filenames expected in ANSI */
  838. CHAR *szFileCur, *szFileNew;
  839. {
  840. /* Rename a file. Return fpeNoErr if successful; error code if not. */
  841. int fn = FnFromSz( szFileCur );
  842. int fpe;
  843. CHAR (**hsz)[];
  844. HANDLE hName;
  845. HANDLE hNewName;
  846. #if WINVER >= 0x300
  847. /* The szPathName field in rgbOpenFileBuf is now treated as OEM
  848. as opposed to ANSI, so we must do a conversion. 12/5/89..pault */
  849. CHAR szFileOem[cchMaxFile];
  850. AnsiToOem((LPSTR)szFileNew, (LPSTR)szFileOem);
  851. #define sz4OpenFile szFileOem
  852. #else
  853. #define sz4OpenFile szFileNew
  854. #endif
  855. /* If this is a file we know about, try to make sure it's on line */
  856. if (fn != fnNil)
  857. if (FEnsureOnLineFn( fn ))
  858. {
  859. FFlushFn( fn ); /* just in case */
  860. CloseFn( fn );
  861. }
  862. else
  863. return fpeHardError;
  864. /* if the file exists on disk then try to rename it */
  865. if (szFileCur[0] != 0 && FExistsSzFile(dtyAny, szFileCur))
  866. {
  867. int fpe=FpeRenameSzFfname( szFileCur, szFileNew );
  868. if ( FIsErrFpe( fpe ) )
  869. /* Rename failed -- return error code */
  870. return fpe;
  871. }
  872. else
  873. return fpeNoErr;
  874. /* Inform other instances of WRITE */
  875. if ((hName = HszGlobalCreate( szFileCur )) != NULL)
  876. {
  877. if ((hNewName = HszGlobalCreate( szFileNew )) != NULL)
  878. {
  879. WBroadcastMsg( wWndMsgRenameFile, hName, (LONG)hNewName, -1 );
  880. GlobalFree( hNewName );
  881. }
  882. GlobalFree( hName );
  883. }
  884. if (fn != fnNil)
  885. { /* Rename current FCB for file if there is one */
  886. struct FCB *pfcb;
  887. FreeH((**hpfnfcb)[fn].hszFile);
  888. hsz = HszCreate((PCH)szFileNew);
  889. pfcb = &(**hpfnfcb) [fn];
  890. pfcb->hszFile = hsz;
  891. bltbyte( sz4OpenFile, ((POFSTRUCT)pfcb->rgbOpenFileBuf)->szPathName,
  892. umin( CchSz( sz4OpenFile ), cchMaxFile ) );
  893. #ifdef DFILE
  894. CommSzSz("FpeRenameFile szFileNew==",szFileNew);
  895. CommSzSz(" szFileCur==",szFileCur);
  896. CommSzSz(" szFileNewOem==",szFileOem);
  897. #endif
  898. #ifdef ENABLE
  899. pfcb->fOpened = FALSE; /* Signal OpenFile that it must open
  900. from scratch, not OF_REOPEN */
  901. #endif
  902. }
  903. return fpeNoErr;
  904. }
  905. RenameFileMessage( hName, hNewName )
  906. HANDLE hName;
  907. HANDLE hNewName;
  908. { /* We are being notified by another instance of WRITE that the name
  909. of file hName is being changed to hNewName. hName and hNewName
  910. are WINDOWS global handles */
  911. LPCH lpchName;
  912. LPCH lpchNewName;
  913. Scribble( 5, 'R' );
  914. Scribble( 4, ' ' );
  915. if ((lpchName = GlobalLock( hName )) != NULL)
  916. {
  917. if ((lpchNewName = GlobalLock( hNewName )) != NULL)
  918. {
  919. CHAR (**hsz) [];
  920. CHAR szName[ cchMaxFile ];
  921. CHAR szNewName[ cchMaxFile ];
  922. int fn;
  923. bltszx( lpchName, (LPCH) szName );
  924. bltszx( lpchNewName, (LPCH) szNewName );
  925. if ((fn=FnFromSz( szName )) != fnNil &&
  926. !FNoHeap(hsz = HszCreate( szNewName )))
  927. {
  928. #if WINVER >= 0x300
  929. /* The szPathName field in rgbOpenFileBuf is now treated as OEM
  930. as opposed to ANSI, so we must do a conversion. 12/5/89..pault */
  931. CHAR szNewOem[cchMaxFile];
  932. AnsiToOem((LPSTR)szNewName, (LPSTR)szNewOem);
  933. bltsz( szNewOem, ((POFSTRUCT)((**hpfnfcb) [fn].rgbOpenFileBuf))->szPathName );
  934. #else
  935. bltsz( szNewName, ((POFSTRUCT)((**hpfnfcb) [fn].rgbOpenFileBuf))->szPathName );
  936. #endif
  937. #ifdef ENABLE
  938. (**hpfnfcb) [fn].fOpened = FALSE;
  939. #endif
  940. FreeH( (**hpfnfcb) [fn].hszFile );
  941. (**hpfnfcb) [fn].hszFile = hsz;
  942. }
  943. GlobalUnlock( hNewName );
  944. }
  945. GlobalUnlock( hName );
  946. }
  947. }
  948. #ifdef DEBUG
  949. #define STATIC
  950. #else
  951. #define STATIC static
  952. #endif
  953. STATIC int messageBR;
  954. STATIC WORD wParamBR;
  955. STATIC LONG lParamBR;
  956. STATIC int wStopBR;
  957. STATIC int wResponseBR;
  958. STATIC FARPROC lpEnumAll=NULL;
  959. STATIC FARPROC lpEnumChild=NULL;
  960. WBroadcastMsg( message, wParam, lParam, wStop )
  961. int message;
  962. WORD wParam;
  963. LONG lParam;
  964. WORD wStop;
  965. { /* Send a message to the document child windows (MDOC) of all
  966. currently active instances of WRITE (except ourselves).
  967. Continue sending until all instances have been notified, or until
  968. one returns the value wStop as a response to the message.
  969. Return the response given by the last window notified, or
  970. -1 if no other instances of WRITE were found */
  971. extern HANDLE hMmwModInstance;
  972. int FAR PASCAL BroadcastAllEnum( HWND, LONG );
  973. int FAR PASCAL BroadcastChildEnum( HWND, LONG );
  974. messageBR = message;
  975. wParamBR = wParam;
  976. lParamBR = lParam;
  977. wStopBR = wStop;
  978. wResponseBR = -1;
  979. if (lpEnumAll == NULL)
  980. {
  981. lpEnumAll = MakeProcInstance( (FARPROC) BroadcastAllEnum, hMmwModInstance );
  982. lpEnumChild = MakeProcInstance( (FARPROC) BroadcastChildEnum, hMmwModInstance );
  983. }
  984. EnumWindows( lpEnumAll, (LONG)0 );
  985. return wResponseBR;
  986. }
  987. int FAR PASCAL BroadcastAllEnum( hwnd, lParam )
  988. HWND hwnd;
  989. LONG lParam;
  990. { /* If hwnd has the class of a WRITE parent (menu) window, call
  991. (*lpEnumChild)() for each of its children and return
  992. the value returned by EnumChildWindows
  993. If the window does not have the class of a WRITE parent, do nothing
  994. and return TRUE */
  995. extern CHAR szParentClass[];
  996. extern HWND hParentWw;
  997. if ( (hwnd != hParentWw) && FSameClassHwndSz( hwnd, szParentClass ) )
  998. return EnumChildWindows( hwnd, lpEnumChild, (LONG) 0 );
  999. else
  1000. return TRUE;
  1001. }
  1002. int FAR PASCAL BroadcastChildEnum( hwnd, lParam )
  1003. HWND hwnd;
  1004. LONG lParam;
  1005. { /* If hwnd is of the same class as a WRITE child (document) window,
  1006. send the message { messageBR, wParamBR, lParamBR } to it, else
  1007. return TRUE;
  1008. If the message is sent, return FALSE if the message return value
  1009. matched wStopBR; TRUE if it did not match.
  1010. Set wMessageBR to the message return value.
  1011. */
  1012. extern CHAR szDocClass[];
  1013. extern HWND vhWnd;
  1014. Assert( hwnd != vhWnd );
  1015. if (FSameClassHwndSz( hwnd, szDocClass ))
  1016. { /* WRITE DOCUMENT WINDOW: pass message along */
  1017. wResponseBR = SendMessage( hwnd, messageBR, wParamBR, lParamBR );
  1018. return wResponseBR != wStopBR;
  1019. }
  1020. else
  1021. return TRUE;
  1022. }
  1023. FSameClassHwndSz( hwnd, szClass )
  1024. HWND hwnd;
  1025. CHAR szClass[];
  1026. { /* Compare the Class name of hWnd with szClass; return TRUE
  1027. if they match, FALSE otherwise. */
  1028. #define cchClassMax 40 /* longest class name (for compare purposes) */
  1029. CHAR rgchWndClass[ cchClassMax ];
  1030. int cbCopied;
  1031. /* Count returned by GetClassName does not include terminator */
  1032. /* But, the count passed in to it does. */
  1033. cbCopied = GetClassName( hwnd, (LPSTR) rgchWndClass, cchClassMax ) + 1;
  1034. if (cbCopied <= 1)
  1035. return FALSE;
  1036. rgchWndClass[ cbCopied - 1 ] = '\0';
  1037. return WCompSz( rgchWndClass, szClass ) == 0;
  1038. }
  1039. FConfirmSave()
  1040. { /* Give the user the opportunity to save docCur, if it is dirty.
  1041. Return 1 - Document Saved OR user elected not to save changes
  1042. OR document was not dirty
  1043. 0 - User selected "Cancel" or Error during SAVE */
  1044. extern HANDLE hMmwModInstance;
  1045. extern HANDLE hParentWw;
  1046. extern int vfTextOnlySave, vfBackupSave;
  1047. struct DOD *pdod=&(**hpdocdod)[docCur];
  1048. #if defined(OLE)
  1049. if (CloseUnfinishedObjects(FALSE) == FALSE)
  1050. return FALSE;
  1051. #endif
  1052. if (pdod->fDirty)
  1053. { /* doc has been edited, offer confirm/save before quitting */
  1054. switch ( IdConfirmDirty() )
  1055. {
  1056. case IDYES:
  1057. {
  1058. #if 0
  1059. #if defined(OLE)
  1060. if (CloseUnfinishedObjects(TRUE) == FALSE)
  1061. return FALSE;
  1062. #endif
  1063. #endif
  1064. if ( (**(pdod->hszFile))[0] == '\0' )
  1065. goto SaveAs;
  1066. #ifdef INTL /* International version */
  1067. /* if saving after a Word conversion, bring up dialog
  1068. box to allow backup/ rename. */
  1069. else if ( vWordFmtMode == CONVFROMWORD)
  1070. goto SaveAs;
  1071. #endif /* International version */
  1072. else if (pdod->fReadOnly)
  1073. {
  1074. extern int ferror;
  1075. /* Read-only doc: tell the user to save under a different name */
  1076. Error( IDPMTReadOnly );
  1077. ferror = FALSE; /* Not really an error */
  1078. SaveAs:
  1079. fnSaveAs(); /* Bring up "save as" dialog box */
  1080. pdod = &(**hpdocdod)[docCur];
  1081. if (pdod->fDirty)
  1082. /* Save failed or was aborted */
  1083. return FALSE;
  1084. }
  1085. else
  1086. {
  1087. CmdXfSave( *pdod->hszFile, !vfTextOnlySave, vfBackupSave, vhcArrow);
  1088. #if defined(OLE)
  1089. if (!ferror)
  1090. ObjSavedDoc();
  1091. #endif
  1092. }
  1093. if (ferror)
  1094. /* Don't quit if we got a disk full error */
  1095. return FALSE;
  1096. }
  1097. break;
  1098. case IDNO:
  1099. #if 0
  1100. #if defined(OLE)
  1101. if (CloseUnfinishedObjects(FALSE) == FALSE)
  1102. return FALSE;
  1103. #endif
  1104. #endif
  1105. break;
  1106. case IDCANCEL:
  1107. default:
  1108. return FALSE;
  1109. }
  1110. }
  1111. #if 0
  1112. #if defined(OLE)
  1113. else /* not dirty */
  1114. if (CloseUnfinishedObjects(FALSE) == FALSE)
  1115. return FALSE;
  1116. #endif
  1117. #endif
  1118. return TRUE;
  1119. }
  1120. PreloadSaveSegs()
  1121. {
  1122. #ifdef GREGC /* kludge to get around the windows kernel bug for now */
  1123. LoadF( PurgeTemps ); /* TRANS4 */
  1124. LoadF( IbpEnsureValid ); /* FILE (includes doslib) */
  1125. LoadF( FnCreateSz ); /* CREATEWW */
  1126. LoadF( ClobberDoc ); /* EDIT */
  1127. LoadF( FNormSzFile ); /* FILEUTIL */
  1128. LoadF( CmdXfSave ); /* TRANS2 */
  1129. #endif
  1130. }
  1131. int CchCopyUpperSz(pch1, pch2)
  1132. register PCH pch1;
  1133. register PCH pch2;
  1134. {
  1135. int cch = 0;
  1136. while ((*pch2 = ChUpper(*pch1++)) != 0)
  1137. {
  1138. #ifdef DBCS /* KenjiK '90-11-20 */
  1139. if(IsDBCSLeadByte(*pch2))
  1140. {
  1141. pch2++;
  1142. *pch2 = *pch1++;
  1143. cch++;
  1144. }
  1145. #endif
  1146. pch2++;
  1147. cch++;
  1148. }
  1149. return cch;
  1150. } /* end of C c h C o p y U p p e r S z */
  1151. #ifdef DBCS // AnsiNext for near call.
  1152. static char NEAR *MyAnsiNext(char *sz)
  1153. {
  1154. if(!*sz) return sz;
  1155. sz++;
  1156. if(IsDBCSLeadByte(*sz)) return (sz+1);
  1157. else return sz;
  1158. }
  1159. #endif
  1160. #if 0
  1161. /* ** Given filename or partial filename or search spec or partial
  1162. search spec, add appropriate extension. */
  1163. /*
  1164. fSearching is true when we want to add \*.DOC to the string -
  1165. i.e., we are seeing if string szEdit is a directory. If the string
  1166. is .. or ends in: or \, we know we have a directory name, not a file
  1167. name, and so add \*.DOC or *.DOC to the string. Otherwise, if
  1168. fSearching is true ans szEdit has no wildcard characters,
  1169. add \*.DOC to the string, even if the string contains a period
  1170. (directories can have extensions). If fSearching is false, we will
  1171. add .DOC to the string if no period is found in the last file/directory
  1172. name.
  1173. Note the implicit assumption here that \ and not / will be used as the
  1174. path character. It is held in the defined variable PATHCHAR, but we
  1175. don't handle DOS setups where the / is path and - is the switch character.
  1176. */
  1177. #define PATHCHAR ('\\')
  1178. NEAR DlgAddCorrectExtension(szEdit, fSearching)
  1179. CHAR *szEdit;
  1180. BOOL fSearching;
  1181. {
  1182. register CHAR *pchLast;
  1183. register CHAR *pchT;
  1184. int ichExt;
  1185. BOOL fDone = FALSE;
  1186. int cchEdit;
  1187. pchT = pchLast = (szEdit + (cchEdit = CchSz(szEdit) - 1) - 1);
  1188. /* Is szEdit a drive letter followed by a colon (not a filename) ? */
  1189. if (cchEdit == 2
  1190. && *pchLast == ':')
  1191. /* don't use 0 or will interpret "z:" incorrectly as "z:\" ..pault */
  1192. ichExt = 1;
  1193. /* how about ".." (also not a file name)? */
  1194. else if (cchEdit == 2
  1195. && (*pchLast == '.' && *(pchLast-1) == '.'))
  1196. ichExt = 0;
  1197. else if (*pchLast == PATHCHAR) /* path character */
  1198. ichExt = 1;
  1199. else
  1200. {
  1201. if (fSearching)
  1202. {
  1203. /* any wild card chars? if so, is really a file name */
  1204. if (FSearchSpec(szEdit))
  1205. return;
  1206. ichExt = 0;
  1207. }
  1208. else
  1209. {
  1210. ichExt = 2;
  1211. for (; pchT > szEdit; pchT--) {
  1212. if (*pchT == '.') {
  1213. return;
  1214. }
  1215. if (*pchT == PATHCHAR) {
  1216. /* path character */
  1217. break;
  1218. }
  1219. }
  1220. }
  1221. }
  1222. if (CchSz(szExtSearch+ichExt) + cchEdit > cchMaxFile)
  1223. Error(IDPMTBadFilename);
  1224. else
  1225. #ifdef DBCS
  1226. CchCopySz((szExtSearch+ichExt), AnsiNext(pchLast));
  1227. #else
  1228. CchCopySz((szExtSearch+ichExt), (pchLast+1));
  1229. #endif
  1230. }
  1231. /* ** return TRUE iff 0 terminated string contains a '*' or '\' */
  1232. BOOL (NEAR FSearchSpec(sz))
  1233. register CHAR *sz;
  1234. {
  1235. #ifdef DBCS
  1236. for (; *sz;sz=AnsiNext(sz)) {
  1237. #else
  1238. for (; *sz;sz++) {
  1239. #endif
  1240. if (*sz == '*' || *sz == '?')
  1241. return TRUE;
  1242. }
  1243. return FALSE;
  1244. }
  1245. #endif
  1246. szFileExtract(szNormFileName, szExtFileName)
  1247. CHAR *szNormFileName; /* input: normalized file name */
  1248. CHAR *szExtFileName; /* output: simple file name with extension added to */
  1249. {
  1250. CHAR *pchLast, *pchT;
  1251. #ifdef DBCS /* KenjiK(MSKK) '90-11-20 */
  1252. for(pchT=szNormFileName;*pchT;pchT++);
  1253. pchLast = pchT;
  1254. do {
  1255. pchT = AnsiPrev(szNormFileName,pchT);
  1256. if (*pchT == '\\')
  1257. break;
  1258. } while(pchT > szNormFileName);
  1259. #else /* not DBCS */
  1260. pchLast = pchT = szNormFileName + CchSz(szNormFileName) - 1;
  1261. while (pchT > szNormFileName)
  1262. {
  1263. if (*pchT == '\\')
  1264. break;
  1265. pchT --;
  1266. }
  1267. #endif
  1268. bltbyte(pchT + 1, szExtFileName, pchLast - pchT);
  1269. //DlgAddCorrectExtension(szExtFileName, FALSE);
  1270. }
  1271. #ifdef INTL /* International version */
  1272. /* ** return TRUE if file opened is in Microsoft Word format */
  1273. BOOL FInWordFormat(fn)
  1274. int fn;
  1275. {
  1276. register struct FCB *pfcb;
  1277. int cchT;
  1278. /* Assumption: this routine has been called after FnOpenSz, which
  1279. has already determined whether the file is formatted,
  1280. and if the pnMac entry was 0, it set pnMac to be the same
  1281. as pnFfntb in the file's fcb. So a Word file is a formatted
  1282. file whose pnMac and pnFfntb are the same.
  1283. We are also pretending that unformatted files are word format files
  1284. so we will bring up a dialog box allowing character set conversion. */
  1285. pfcb = &(**hpfnfcb)[fn];
  1286. if (pfcb->fFormatted == false) /* unformatted treated as a word file */
  1287. return (true);
  1288. return (pfcb->pnMac == pfcb->pnFfntb);
  1289. }
  1290. #endif /* International version */
  1291. #ifdef INTL /* International version */
  1292. void ConvertFromWord ()
  1293. {
  1294. /* vWordFmtMode is used by FnWriteFile to translate the
  1295. Word file character set to ANSI. We leave it set to
  1296. CONVFROMWORD so that the next save can check if there was a
  1297. file with extension of szExtDoc.If there is no such file,
  1298. vWordFmtMode is set to true or false by the save dialog code.
  1299. *** as of 2/14/86, no backup is made, but code in CleanDoc checks for
  1300. vWordFmtMode=CONVFROMWORD, and saves without renaming the word
  1301. file instead of making an optional backup
  1302. *** as of 12/3/89, FreeUnreferencedFns() is removing the
  1303. lock on files not referenced by pieces in any documents, so
  1304. the word doc or text file being converted FROM is not being
  1305. "locked" and another app can grab it! I'm correcting this
  1306. in FreeUnreferencedFns() ..pault
  1307. */
  1308. extern CHAR szExtDoc[];
  1309. struct DOD *pdod=&(**hpdocdod)[docCur];
  1310. vWordFmtMode = CONVFROMWORD; /* will stay this value until save */
  1311. vfBackupSave = 1; /* force next save to default to backing up */
  1312. /* always a formatted save, no backup. */
  1313. CmdXfSave( *pdod->hszFile, true, false, vhcArrow);
  1314. #if defined(OLE)
  1315. if (!ferror)
  1316. ObjSavedDoc();
  1317. #endif
  1318. }
  1319. #endif /* International version */
  1320. #ifdef INTL /* International version */
  1321. TestWordCvt (fn, hWnd)
  1322. int fn;
  1323. HWND hWnd;
  1324. {
  1325. int wordVal;
  1326. #ifndef INEFFLOCKDOWN
  1327. FARPROC lpDialogWordCvt = MakeProcInstance(DialogWordCvt, hMmwModInstance);
  1328. if (!lpDialogWordCvt)
  1329. {
  1330. WinFailure();
  1331. return(fFalse);
  1332. }
  1333. #endif
  1334. /* This routine returns the following values:
  1335. -1 means dialog box failed (error already sent)
  1336. -2 means cancel without conversion.
  1337. FALSE means not a word document.
  1338. TRUE means convert this word document.
  1339. Its parent may change depending on the caller.
  1340. */
  1341. if (!(wordVal = FInWordFormat (fn)))
  1342. return (FALSE); /* not a word doc */
  1343. /* in word format - ask for conversion */
  1344. /* the cvt to word dialog returns 3 values
  1345. other than -1:
  1346. idiOk - convert
  1347. idiCancel - cancel, no conversion
  1348. idiNo - read in without conversion
  1349. vfBackupSave set to reflect whether backup is made */
  1350. /* Note it is a child of this dialog */
  1351. fOpenedFormatted = (**hpfnfcb)[fn].fFormatted; /* used in dialog func */
  1352. #ifdef DBCS /* was in KKBUGFIX */
  1353. // [yutakan:05/17/91] (I don't know why) sometimes hWnd would be invalid.
  1354. if (!IsWindow(hWnd)) hWnd = hParentWw;
  1355. #endif
  1356. if ((wordVal = (OurDialogBox( hMmwModInstance,
  1357. MAKEINTRESOURCE(dlgWordCvt), hWnd,
  1358. lpDialogWordCvt))) == -1)
  1359. {
  1360. #if WINVER >= 0x300
  1361. WinFailure();
  1362. #else
  1363. Error(IDPMTNoMemory);
  1364. #endif
  1365. }
  1366. #ifndef INEFFLOCKDOWN
  1367. FreeProcInstance(lpDialogWordCvt);
  1368. #endif
  1369. /* return -1 if either out of memory or no conversion desired */
  1370. /* will convert an unformatted file if No is the dialog response */
  1371. switch (wordVal)
  1372. {
  1373. case idiNo: /* User hit the "No Conversion" button */
  1374. return(FALSE); /* treat as non-word file */
  1375. case idiOk: /* User hit the "Convert" button */
  1376. return(TRUE);
  1377. case idiCancel:
  1378. return (-2);
  1379. case -1:
  1380. default:
  1381. return (-1);
  1382. }
  1383. }
  1384. #endif /* Kanji / International version */
  1385. /* ********** routines for doing message relocation ******* */
  1386. VOID MergeInit()
  1387. /* get merge spec, guaranteed to be 2 characters, into variable wMerge */
  1388. {
  1389. char sz[10];
  1390. PchFillPchId( sz, IDS_MERGE1, sizeof(sz) );
  1391. wMerge = *(unsigned *)sz;
  1392. }
  1393. BOOL MergeStrings (idSrc, szMerge, szDst)
  1394. IDPMT idSrc;
  1395. CHAR *szMerge;
  1396. CHAR *szDst;
  1397. {
  1398. /* get message from idSrc. Scan it for merge spec. If found, insert string
  1399. szMerge at that point, then append the rest of the message. NOTE!
  1400. merge spec guaranteed to be 2 characters. wMerge loaded at init by
  1401. MergeInit. Returns true if merge done, false otherwise.
  1402. */
  1403. CHAR szSrc[cchMaxSz];
  1404. register CHAR *pchSrc;
  1405. register CHAR *pchDst;
  1406. /* get message from resource file */
  1407. PchFillPchId( szSrc, idSrc, sizeof(szSrc) );
  1408. pchSrc = szSrc;
  1409. pchDst = szDst;
  1410. /* find merge spec if any */
  1411. while (*(unsigned *)pchSrc != wMerge)
  1412. {
  1413. *pchDst++ = *pchSrc;
  1414. /* if we reach the end of string before merge spec, just return false */
  1415. if (!*pchSrc++)
  1416. return FALSE;
  1417. }
  1418. /* if merge spec found, insert szMerge there. (check for null merge str */
  1419. if (szMerge)
  1420. while (*szMerge)
  1421. *pchDst++ = *szMerge++;
  1422. /* jump over merge spec */
  1423. pchSrc++;
  1424. pchSrc++;
  1425. /* append rest of string */
  1426. while (*pchDst++ = *pchSrc++)
  1427. ;
  1428. return TRUE;
  1429. }
  1430. #include "propdefs.h"
  1431. BOOL DocHasPictures(int doc)
  1432. {
  1433. extern struct PAP vpapAbs;
  1434. typeCP cpMac = CpMacText(doc),cpNow;
  1435. for ( cpNow = cp0; cpNow < cpMac; cpNow = vcpLimParaCache )
  1436. {
  1437. CachePara( doc, cpNow );
  1438. if (vpapAbs.fGraphics)
  1439. return TRUE;
  1440. }
  1441. return FALSE;
  1442. }
  1443. BOOL WannaDeletePictures(int doc, int fWhichFormat)
  1444. /* assume if SF_OLDWRITE that vcObjects is set */
  1445. {
  1446. CHAR szBuf[cchMaxSz];
  1447. BOOL bDoPrompt;
  1448. if (fWhichFormat == SF_OLDWRITE)
  1449. /* warn that OLE pictures will be deleted */
  1450. {
  1451. if (bDoPrompt = (vcObjects > 0))
  1452. PchFillPchId( szBuf, IDPMTDelObjects, sizeof(szBuf) );
  1453. }
  1454. else if (fWhichFormat == SF_WORD)
  1455. /* warn that all pictures will be deleted */
  1456. {
  1457. if (bDoPrompt = DocHasPictures(docCur))
  1458. PchFillPchId( szBuf, IDPMTDelPicture, sizeof(szBuf) );
  1459. }
  1460. else
  1461. return TRUE;
  1462. if (bDoPrompt)
  1463. return (IdPromptBoxSz( vhWnd, szBuf, MB_YESNO | MB_ICONEXCLAMATION ) == IDYES);
  1464. else
  1465. return TRUE;
  1466. }
  1467. BOOL NEAR PASCAL CanReadEveryFile(char *szFilename)
  1468. {
  1469. extern int fnMac;
  1470. int fn;
  1471. BOOL bRetval=TRUE;
  1472. FreezeHp();
  1473. for (fn = 0; fn < fnMac; fn++)
  1474. {
  1475. if ((**hpfnfcb)[fn].fDisableRead)
  1476. {
  1477. /* see if still can't read */
  1478. if (!FAccessFn( fn, dtyNormal ))
  1479. {
  1480. char szMsg[cchMaxSz];
  1481. ferror = FALSE;
  1482. MergeStrings (IDPMTCantRead, szFilename, szMsg);
  1483. IdPromptBoxSz(vhWndMsgBoxParent ? vhWndMsgBoxParent : hParentWw,
  1484. szMsg, MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL);
  1485. {
  1486. bRetval = FALSE;
  1487. break;
  1488. }
  1489. }
  1490. }
  1491. }
  1492. MeltHp();
  1493. return bRetval;
  1494. }