|
|
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.2 ! 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:
180: if (!CreateDocFromFile (szDoc, NULL, doctypeFromFile))
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.
187: CreateNewDoc (NULL, "(Untitled)", doctypeNew);
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: {
299: CHAR szDoc[cchFilenameMax];
300: CHAR szDocOld[cchFilenameMax];
301: BOOL fUpdateLater = FALSE;
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:
308: if (GetFileSaveFilename (szDoc))
309: {
310:
311: if (docMain.doctype == doctypeEmbedded)
312: return SaveDocIntoFile(szDoc);
313:
314: if (fUpdateLater)
315: {
316: // The non-standard OLE client did not accept the update when
317: // we requested it, so we are sending the client OLE_CLOSED now that
318: // we are closing the document.
319: SendDocMsg (OLE_CLOSED);
320: }
321:
322: // Set the window title bar.
323: SetTitle (szDoc, FALSE);
324: OleRenameServerDoc(docMain.lhdoc, szDoc);
325:
326: if (SaveDocIntoFile(szDoc))
327: return TRUE;
328: else
329: { // Restore old name
330: SetTitle (szDocOld, FALSE);
331: OleRenameServerDoc(docMain.lhdoc, szDocOld);
332: return FALSE;
333: }
334: }
335: else // user chose Cancel
336: return FALSE;
337: // The user chose the "Yes, Update" button but the
338: // File Open dialog box failed for some reason
339: // (perhaps the user chose Cancel).
340: // Even though the user chose "Yes, Update", there is no way
341: // to update a non-standard OLE client that does not accept updates
342: // except when the document is closed.
343: }
344:
345:
346:
347: /* SaveDocIntoFile
348: * ---------------
349: *
350: * Save the document into a file whose name is determined from docMain.aName.
351: *
352: * RETURNS: TRUE if successful
353: * FALSE otherwise
354: *
355: * CUSTOMIZATION: Re-implement
356: *
357: */
358: static BOOL SaveDocIntoFile (PSTR pDoc)
359: {
360: HWND hwnd;
361: INT fh; // File handle
362: LPOBJ lpobj;
363: HEADER hdr;
364: INT i;
365:
366: hwnd = GetWindow (hwndMain, GW_CHILD);
367:
368: if (!hwnd)
369: {
370: ErrorBox ("Could not save NULL file.");
371: return FALSE;
372: }
373:
374: // Get document name.
375: if ((fh =_lcreat(pDoc, 0)) == -1)
376: {
377: ErrorBox ("Could not save file.");
378: return FALSE;
379: }
380:
381: // Fill in header.
382: lstrcpy (hdr.szSig, szSignature);
383: hdr.chDelim1 = chDelim;
384: hdr.version = version;
385: hdr.chDelim2 = chDelim;
386: for (i=1; i <= cfObjNums; i++)
387: hdr.rgfObjNums[i] = docMain.rgfObjNums[i];
388:
389: // Write header to file.
390: if (_lwrite(fh, (LPSTR) &hdr, (UINT)sizeof(HEADER)) < sizeof(HEADER))
391: goto Error; // Error writing file header
392:
393: // Write each object's native data.
394: while (hwnd)
395: {
396: lpobj = (LPOBJ) GetWindowLong (hwnd, ibLpobj);
397: if (_lwrite(fh, (LPSTR)&lpobj->native, (UINT)sizeof (NATIVE))
398: < sizeof(NATIVE))
399: goto Error; // Error writing file header
400:
401: hwnd = GetWindow (hwnd, GW_HWNDNEXT);
402: }
403: _lclose(fh);
404:
405:
406: if (docMain.doctype != doctypeEmbedded)
407: {
408: docMain.doctype = doctypeFromFile;
409: OleSavedServerDoc(docMain.lhdoc);
410: fDocChanged = FALSE;
411: }
412:
413: return TRUE;
414:
415: Error:
416: _lclose(fh);
417: ErrorBox ("Could not save file.");
418: return FALSE;
419:
420: }
421:
422:
423:
424: /* Common Dialog functions */
425:
426:
427: /* InitOfn
428: * -------
429: *
430: * Initialize an OPENFILENAME structure with default values.
431: * OPENFILENAME is defined in CommDlg.h.
432: *
433: *
434: * CUSTOMIZATION: Change lpstrFilter. You may also customize the common
435: * dialog box if you wish. (See the Windows SDK documentation.)
436: *
437: */
438: static VOID InitOfn (OPENFILENAME *pofn)
439: {
440: // GetOpenFileName or GetSaveFileName will put the 8.3 filename into
441: // szFileTitle[].
442: // SrvrDemo does not use this filename, but rather uses the fully qualified
443: // pathname in pofn->lpstrFile[].
444: static CHAR szFileTitle[13];
445:
446: pofn->Flags = 0;
447: pofn->hInstance = hInst;
448: pofn->hwndOwner = hwndMain;
449: pofn->lCustData = NULL;
450: pofn->lpfnHook = NULL;
451: pofn->lpstrCustomFilter = NULL;
452: pofn->lpstrDefExt = szDefExt;
453: // lpstrFile[] is the initial filespec that appears in the edit control.
454: // Must be set to non-NULL before calling the common dialog box function.
455: // On return, lpstrFile[] will contain the fully-qualified pathname
456: // corresponding to the file the user chose.
457: pofn->lpstrFile = NULL;
458: pofn->lpstrFilter = "Server Demo (*." szDefExt ")\0*." szDefExt "\0" ;
459: // lpstrFileTitle[] will contain the user's chosen filename without a path.
460: pofn->lpstrFileTitle = szFileTitle;
461: pofn->lpstrInitialDir= NULL;
462: // Title Bar. NULL means use default title.
463: pofn->lpstrTitle = NULL;
464: pofn->lpTemplateName = NULL;
465: pofn->lStructSize = sizeof (OPENFILENAME);
466: pofn->nFilterIndex = 1L;
467: pofn->nFileOffset = 0;
468: pofn->nFileExtension = 0;
469: pofn->nMaxFile = cchFilenameMax;
470: pofn->nMaxCustFilter = 0L;
471: }
472:
473:
474:
475:
476: /* GetFileOpenFilename
477: * -------------------
478: *
479: * Call the common dialog box function GetOpenFileName to get a file name
480: * from the user when the user chooses the "File Open" menu item.
481: *
482: * LPSTR lpszFilename - will contain the fully-qualified pathname on exit.
483: *
484: * RETURNS: TRUE if successful, FALSE otherwise.
485: *
486: * CUSTOMIZATION: None
487: *
488: */
489: BOOL GetFileOpenFilename (LPSTR lpszFilename)
490: {
491: OPENFILENAME ofn;
492: InitOfn (&ofn);
493: ofn.Flags |= OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
494: // Create initial filespec.
495: wsprintf (lpszFilename, "*.%s", (LPSTR) szDefExt);
496: // Have the common dialog function return the filename in lpszFilename.
497: ofn.lpstrFile = lpszFilename;
498: if (!GetOpenFileName (&ofn))
499: return FALSE;
500: return TRUE;
501: }
502:
503:
504:
505: /* GetFileSaveFilename
506: * -------------------
507: *
508: * Call the common dialog box function GetSaveFileName to get a file name
509: * from the user when the user chooses the "File Save As" menu item, or the
510: * "File Save" menu item for an unnamed document.
511: *
512: * LPSTR lpszFilename - will contain the fully-qualified pathname on exit.
513: *
514: * RETURNS: TRUE if successful, FALSE otherwise.
515: *
516: * CUSTOMIZATION: None
517: *
518: */
519: BOOL GetFileSaveFilename (LPSTR lpszFilename)
520: {
521: OPENFILENAME ofn;
522: InitOfn (&ofn);
523: ofn.Flags |= OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
524: // Create initial filespec.
525: wsprintf (lpszFilename, "*.%s", (LPSTR) szDefExt);
526: // Have the common dialog function return the filename in lpszFilename.
527: ofn.lpstrFile = lpszFilename;
528: if (!GetSaveFileName (&ofn))
529: return FALSE;
530: return TRUE;
531: }
1.1.1.2 ! root 532:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.