|
|
1.1 root 1: /*
2: OLE SERVER DEMO
3: File.c
4:
5: This file contains file input/output functions for for the OLE server demo.
6:
7: (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved
8: */
9:
10:
11:
12: #include <windows.h>
13: #include <commDlg.h>
14: #include <ole.h>
15:
16: #include "srvrdemo.h"
17:
18: // File signature stored in the file.
19: #define szSignature "ServerDemo"
20: #define cchSigLen (10+1)
21:
22: // Delimiter for fields in the file
23: #define chDelim ':'
24:
25: // Default file extension
26: #define szDefExt "sd"
27:
28: // File header structure
29: typedef struct
30: {
31: CHAR szSig [cchSigLen];
32: CHAR chDelim1;
33: VERSION version;
34: CHAR chDelim2;
35: CHAR rgfObjNums [cfObjNums+1];
36: } HEADER;
37:
1.1.1.3 ! root 38: // BOOL GetFileSaveFilename (LPSTR lpszFilename);
1.1 root 39: static VOID InitOfn (OPENFILENAME *pofn);
40: static BOOL SaveDocIntoFile (PSTR);
41: static LPOBJ ReadObj (INT fh);
42:
43:
44:
45: /* CreateDocFromFile
46: * -----------------
47: *
48: * Read a document from the specified file.
49: *
50: * LPSTR lpszDoc - Name of the file containing the document
51: * LHSERVERDOC lhdoc - Handle to the document
52: * DOCTYPE doctype - In what state the document is created
53: *
54: * RETURNS: TRUE if successful, FALSE otherwise
55: *
56: * CUSTOMIZATION: Re-implement
57: * This function will need to be completely re-implemented
58: * to support your application's file format.
59: *
60: */
61: BOOL CreateDocFromFile (LPSTR lpszDoc, LHSERVERDOC lhdoc, DOCTYPE doctype)
62: {
63: INT fh; // File handle
64: HEADER hdr;
65: INT i;
66:
67: if ((fh =_lopen(lpszDoc, OF_READ)) == -1)
68: return FALSE;
69:
70: // Read header from file.
71: if (_lread(fh, (LPSTR) &hdr, (UINT)sizeof(HEADER)) < sizeof (HEADER))
72: goto Error;
73:
74: // Check to see if file is a server demo file.
75: if (lstrcmp(hdr.szSig, szSignature))
76: goto Error;
77:
78: if (hdr.chDelim1 != chDelim)
79: goto Error;
80:
81: // Check to see if file was saved under the most recent version.
82: // Here is where you would handle reading in old versions.
83: if (hdr.version != version)
84: goto Error;
85:
86: if (hdr.chDelim2 != chDelim)
87: goto Error;
88:
89: if (!CreateNewDoc (lhdoc, lpszDoc, doctype))
90: goto Error;
91:
92: // Get the array indicating which object numbers have been used.
93: for (i=1; i <= cfObjNums; i++)
94: docMain.rgfObjNums[i] = hdr.rgfObjNums[i];
95:
96: // Read in object data.
97: for (i=0; ReadObj (fh); i++);
98:
99: if (!i)
100: {
101: OLESTATUS olestatus;
102:
103: fRevokeSrvrOnSrvrRelease = FALSE;
104:
105: if ((olestatus = RevokeDoc()) > OLE_WAIT_FOR_RELEASE)
106: goto Error;
107: else if (olestatus == OLE_WAIT_FOR_RELEASE)
108: Wait (&fWaitingForDocRelease);
109:
110: fRevokeSrvrOnSrvrRelease = TRUE;
111: EmbeddingModeOff();
112: goto Error;
113: }
114:
115: _lclose(fh);
116:
117: fDocChanged = FALSE;
118: return TRUE;
119:
120: Error:
121: _lclose(fh);
122: return FALSE;
123:
124: }
125:
126:
127:
128: /* OpenDoc
129: * -------
130: *
131: * Prompt the user for which document he wants to open
132: *
133: * RETURNS: TRUE if successful, FALSE otherwise.
134: *
135: * CUSTOMIZATION: None, except your application may or may not call
136: * CreateNewObj to create a default object.
137: *
138: */
139: BOOL OpenDoc (VOID)
140: {
141: CHAR szDoc[cchFilenameMax];
142: BOOL fUpdateLater;
143: OLESTATUS olestatus;
144:
145: if (SaveChangesOption (&fUpdateLater) == IDCANCEL)
146: return FALSE;
147:
148: if (!GetFileOpenFilename (szDoc))
149: {
150: if (fUpdateLater)
151: {
152: // The user chose the "Yes, Update" button but the
153: // File Open dialog box failed for some reason
154: // (perhaps the user chose Cancel).
155: // Even though the user chose "Yes, Update", there is no way
156: // to update a client that does not accept updates
157: // except when the document is closed.
158: }
159: return FALSE;
160: }
161:
162: if (fUpdateLater)
163: {
164: // The non-standard OLE client did not accept the update when
165: // we requested it, so we are sending the client OLE_CLOSED now that
166: // we are closing the document.
167: SendDocMsg (OLE_CLOSED);
168: }
169:
170: fRevokeSrvrOnSrvrRelease = FALSE;
171:
172: if ((olestatus = RevokeDoc()) > OLE_WAIT_FOR_RELEASE)
173: return FALSE;
174: else if (olestatus == OLE_WAIT_FOR_RELEASE)
175: Wait (&fWaitingForDocRelease);
176:
177: fRevokeSrvrOnSrvrRelease = TRUE;
178: EmbeddingModeOff();
179:
1.1.1.3 ! root 180: if (!CreateDocFromFile (szDoc, 0, doctypeFromFile))
1.1 root 181: {
182: MessageBox (hwndMain,
183: "Reading from file failed.\r\nFile may not be in proper file format.",
184: szAppName,
185: MB_ICONEXCLAMATION | MB_OK);
186: // We already revoked the document, so give the user a new one to edit.
1.1.1.3 ! root 187: CreateNewDoc (0, "(Untitled)", doctypeNew);
1.1 root 188: CreateNewObj (FALSE);
189: return FALSE;
190: }
191: fDocChanged = FALSE;
192: return TRUE;
193: }
194:
195:
196:
197: /* ReadObj
198: * --------
199: *
200: * Read the next object from a file, allocate memory for it, and return
201: * a pointer to it.
202: *
203: * int fh - File handle
204: *
205: * RETURNS: A pointer to the object
206: *
207: * CUSTOMIZATION: Server Demo specific
208: *
209: */
210: static LPOBJ ReadObj (INT fh)
211: {
212: HANDLE hObj = NULL;
213: LPOBJ lpobj = NULL;
214:
215: hObj = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (OBJ));
216:
217: if (hObj == NULL)
218: return NULL;
219:
220: lpobj = (LPOBJ) LocalLock (hObj);
221:
222: if (lpobj==NULL)
223: {
224: LocalFree (hObj);
225: return NULL;
226: }
227:
228: if (_lread(fh, (LPSTR) &lpobj->native, (UINT)sizeof(NATIVE)) < sizeof (NATIVE))
229: {
230: LocalUnlock (hObj);
231: LocalFree (hObj);
232: return NULL;
233: }
234:
235: lpobj->hObj = hObj;
236: lpobj->oleobject.lpvtbl = &objvtbl;
237: lpobj->aName = GlobalAddAtom (lpobj->native.szName);
238:
239: if (!CreateWindow(
240: "ObjClass",
241: "Obj",
242: WS_THICKFRAME | WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE ,
243: lpobj->native.nX,
244: lpobj->native.nY,
245: lpobj->native.nWidth,
246: lpobj->native.nHeight,
247: hwndMain,
248: NULL,
249: hInst,
250: (LPSTR) lpobj ))
251: {
252: LocalUnlock (hObj);
253: LocalFree (hObj);
254: return NULL;
255: }
256:
257: return lpobj;
258: }
259:
260:
261:
262: /* SaveDoc
263: * -------
264: *
265: * Save the document.
266: *
267: * CUSTOMIZATION: None
268: *
269: */
270:
271: BOOL SaveDoc (VOID)
272: {
273: if (docMain.doctype == doctypeNew)
274: return SaveDocAs();
275: else
276: {
277: CHAR szDoc [cchFilenameMax];
278:
279: GlobalGetAtomName (docMain.aName, szDoc, cchFilenameMax);
280: return SaveDocIntoFile(szDoc);
281: }
282: }
283:
284:
285:
286: /* SaveDocAs
287: * ---------
288: *
289: * Prompt the user for a filename, and save the document under that filename.
290: *
291: * RETURNS: TRUE if successful or user chose CANCEL
292: * FALSE if SaveDocIntoFile fails
293: *
294: * CUSTOMIZATION: None
295: *
296: */
297: BOOL SaveDocAs (VOID)
298: {
1.1.1.3 ! root 299: CHAR szDoc[cchFilenameMax];
! 300: BOOL fUpdateLater;
1.1 root 301: CHAR szDocOld[cchFilenameMax];
302:
303: // If document is embedded, give user a chance to update.
304: // Save old document name in case the save fails.
305: if (!GlobalGetAtomName (docMain.aName, szDocOld, cchFilenameMax))
306: ErrorBox ("Fatal Error: Document name is invalid.");
307:
1.1.1.3 ! root 308: if (GetFileSaveFilename (szDoc))
! 309:
1.1 root 310: {
311:
312: if (docMain.doctype == doctypeEmbedded)
313: return SaveDocIntoFile(szDoc);
314:
315: if (fUpdateLater)
316: {
317: // The non-standard OLE client did not accept the update when
318: // we requested it, so we are sending the client OLE_CLOSED now that
319: // we are closing the document.
320: SendDocMsg (OLE_CLOSED);
321: }
322:
323: // Set the window title bar.
324: SetTitle (szDoc, FALSE);
325: OleRenameServerDoc(docMain.lhdoc, szDoc);
326:
327: if (SaveDocIntoFile(szDoc))
328: return TRUE;
329: else
330: { // Restore old name
331: SetTitle (szDocOld, FALSE);
332: OleRenameServerDoc(docMain.lhdoc, szDocOld);
333: return FALSE;
334: }
335: }
336: else // user chose Cancel
337: return FALSE;
338: // The user chose the "Yes, Update" button but the
339: // File Open dialog box failed for some reason
340: // (perhaps the user chose Cancel).
341: // Even though the user chose "Yes, Update", there is no way
342: // to update a non-standard OLE client that does not accept updates
343: // except when the document is closed.
344: }
345:
346:
347:
348: /* SaveDocIntoFile
349: * ---------------
350: *
351: * Save the document into a file whose name is determined from docMain.aName.
352: *
353: * RETURNS: TRUE if successful
354: * FALSE otherwise
355: *
356: * CUSTOMIZATION: Re-implement
357: *
358: */
359: static BOOL SaveDocIntoFile (PSTR pDoc)
360: {
361: HWND hwnd;
362: INT fh; // File handle
363: LPOBJ lpobj;
364: HEADER hdr;
365: INT i;
366:
367: hwnd = GetWindow (hwndMain, GW_CHILD);
368:
369: if (!hwnd)
370: {
371: ErrorBox ("Could not save NULL file.");
372: return FALSE;
373: }
374:
375: // Get document name.
376: if ((fh =_lcreat(pDoc, 0)) == -1)
377: {
378: ErrorBox ("Could not save file.");
379: return FALSE;
380: }
381:
382: // Fill in header.
383: lstrcpy (hdr.szSig, szSignature);
384: hdr.chDelim1 = chDelim;
385: hdr.version = version;
386: hdr.chDelim2 = chDelim;
387: for (i=1; i <= cfObjNums; i++)
388: hdr.rgfObjNums[i] = docMain.rgfObjNums[i];
389:
390: // Write header to file.
391: if (_lwrite(fh, (LPSTR) &hdr, (UINT)sizeof(HEADER)) < sizeof(HEADER))
392: goto Error; // Error writing file header
393:
394: // Write each object's native data.
395: while (hwnd)
396: {
397: lpobj = (LPOBJ) GetWindowLong (hwnd, ibLpobj);
398: if (_lwrite(fh, (LPSTR)&lpobj->native, (UINT)sizeof (NATIVE))
399: < sizeof(NATIVE))
400: goto Error; // Error writing file header
401:
402: hwnd = GetWindow (hwnd, GW_HWNDNEXT);
403: }
404: _lclose(fh);
405:
406:
407: if (docMain.doctype != doctypeEmbedded)
408: {
409: docMain.doctype = doctypeFromFile;
410: OleSavedServerDoc(docMain.lhdoc);
411: fDocChanged = FALSE;
412: }
413:
414: return TRUE;
415:
416: Error:
417: _lclose(fh);
418: ErrorBox ("Could not save file.");
419: return FALSE;
420:
421: }
422:
423:
424:
425: /* Common Dialog functions */
426:
427:
428: /* InitOfn
429: * -------
430: *
431: * Initialize an OPENFILENAME structure with default values.
432: * OPENFILENAME is defined in CommDlg.h.
433: *
434: *
435: * CUSTOMIZATION: Change lpstrFilter. You may also customize the common
436: * dialog box if you wish. (See the Windows SDK documentation.)
437: *
438: */
439: static VOID InitOfn (OPENFILENAME *pofn)
440: {
441: // GetOpenFileName or GetSaveFileName will put the 8.3 filename into
442: // szFileTitle[].
443: // SrvrDemo does not use this filename, but rather uses the fully qualified
444: // pathname in pofn->lpstrFile[].
445: static CHAR szFileTitle[13];
446:
447: pofn->Flags = 0;
448: pofn->hInstance = hInst;
449: pofn->hwndOwner = hwndMain;
1.1.1.3 ! root 450: pofn->lCustData = 0;
1.1 root 451: pofn->lpfnHook = NULL;
452: pofn->lpstrCustomFilter = NULL;
453: pofn->lpstrDefExt = szDefExt;
454: // lpstrFile[] is the initial filespec that appears in the edit control.
455: // Must be set to non-NULL before calling the common dialog box function.
456: // On return, lpstrFile[] will contain the fully-qualified pathname
457: // corresponding to the file the user chose.
458: pofn->lpstrFile = NULL;
459: pofn->lpstrFilter = "Server Demo (*." szDefExt ")\0*." szDefExt "\0" ;
460: // lpstrFileTitle[] will contain the user's chosen filename without a path.
461: pofn->lpstrFileTitle = szFileTitle;
462: pofn->lpstrInitialDir= NULL;
463: // Title Bar. NULL means use default title.
464: pofn->lpstrTitle = NULL;
465: pofn->lpTemplateName = NULL;
466: pofn->lStructSize = sizeof (OPENFILENAME);
467: pofn->nFilterIndex = 1L;
468: pofn->nFileOffset = 0;
469: pofn->nFileExtension = 0;
470: pofn->nMaxFile = cchFilenameMax;
471: pofn->nMaxCustFilter = 0L;
472: }
473:
474:
475:
476:
477: /* GetFileOpenFilename
478: * -------------------
479: *
480: * Call the common dialog box function GetOpenFileName to get a file name
481: * from the user when the user chooses the "File Open" menu item.
482: *
483: * LPSTR lpszFilename - will contain the fully-qualified pathname on exit.
484: *
485: * RETURNS: TRUE if successful, FALSE otherwise.
486: *
487: * CUSTOMIZATION: None
488: *
489: */
490: BOOL GetFileOpenFilename (LPSTR lpszFilename)
491: {
492: OPENFILENAME ofn;
493: InitOfn (&ofn);
494: ofn.Flags |= OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
495: // Create initial filespec.
496: wsprintf (lpszFilename, "*.%s", (LPSTR) szDefExt);
497: // Have the common dialog function return the filename in lpszFilename.
498: ofn.lpstrFile = lpszFilename;
499: if (!GetOpenFileName (&ofn))
500: return FALSE;
501: return TRUE;
502: }
503:
504:
505:
506: /* GetFileSaveFilename
507: * -------------------
508: *
509: * Call the common dialog box function GetSaveFileName to get a file name
510: * from the user when the user chooses the "File Save As" menu item, or the
511: * "File Save" menu item for an unnamed document.
512: *
513: * LPSTR lpszFilename - will contain the fully-qualified pathname on exit.
514: *
515: * RETURNS: TRUE if successful, FALSE otherwise.
516: *
517: * CUSTOMIZATION: None
518: *
519: */
520: BOOL GetFileSaveFilename (LPSTR lpszFilename)
521: {
522: OPENFILENAME ofn;
523: InitOfn (&ofn);
524: ofn.Flags |= OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
525: // Create initial filespec.
526: wsprintf (lpszFilename, "*.%s", (LPSTR) szDefExt);
527: // Have the common dialog function return the filename in lpszFilename.
528: ofn.lpstrFile = lpszFilename;
529: if (!GetSaveFileName (&ofn))
530: return FALSE;
531: return TRUE;
532: }
1.1.1.2 root 533:
1.1.1.3 ! root 534:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.