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