|
|
/*
OLE SERVER DEMO File.c
This file contains file input/output functions for for the OLE server demo.
(c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved */
#include <windows.h>
#include <commDlg.h>
#include <ole.h>
#include "srvrdemo.h"
// File signature stored in the file.
#define szSignature "ServerDemo"
#define cchSigLen (10+1)
// Delimiter for fields in the file
#define chDelim ':'
// Default file extension
#define szDefExt "sd1"
// File header structure
typedef struct { CHAR szSig [cchSigLen]; CHAR chDelim1; VERSION version; CHAR chDelim2; CHAR rgfObjNums [cfObjNums+1]; } HEADER;
// BOOL GetFileSaveFilename (LPSTR lpszFilename);
static VOID InitOfn (OPENFILENAME *pofn); static BOOL SaveDocIntoFile (PSTR); static LPOBJ ReadObj (INT fh);
/* CreateDocFromFile
* ----------------- * * Read a document from the specified file. * * LPSTR lpszDoc - Name of the file containing the document * LHSERVERDOC lhdoc - Handle to the document * DOCTYPE doctype - In what state the document is created * * RETURNS: TRUE if successful, FALSE otherwise * * CUSTOMIZATION: Re-implement * This function will need to be completely re-implemented * to support your application's file format. * */ BOOL CreateDocFromFile (LPSTR lpszDoc, LHSERVERDOC lhdoc, DOCTYPE doctype) { INT fh; // File handle
HEADER hdr; INT i;
if ((fh =_lopen(lpszDoc, OF_READ)) == -1) return FALSE;
// Read header from file.
if (_lread(fh, (LPSTR) &hdr, (UINT)sizeof(HEADER)) < sizeof (HEADER)) goto Error;
// Check to see if file is a server demo file.
if (lstrcmp(hdr.szSig, szSignature)) goto Error;
if (hdr.chDelim1 != chDelim) goto Error;
// Check to see if file was saved under the most recent version.
// Here is where you would handle reading in old versions.
if (hdr.version != version) goto Error;
if (hdr.chDelim2 != chDelim) goto Error;
if (!CreateNewDoc (lhdoc, lpszDoc, doctype)) goto Error;
// Get the array indicating which object numbers have been used.
for (i=1; i <= cfObjNums; i++) docMain.rgfObjNums[i] = hdr.rgfObjNums[i];
// Read in object data.
for (i=0; ReadObj (fh); i++);
if (!i) { OLESTATUS olestatus;
fRevokeSrvrOnSrvrRelease = FALSE;
if ((olestatus = RevokeDoc()) > OLE_WAIT_FOR_RELEASE) goto Error; else if (olestatus == OLE_WAIT_FOR_RELEASE) Wait (&fWaitingForDocRelease);
fRevokeSrvrOnSrvrRelease = TRUE; EmbeddingModeOff(); goto Error; }
_lclose(fh);
fDocChanged = FALSE; return TRUE;
Error: _lclose(fh); return FALSE;
}
/* OpenDoc
* ------- * * Prompt the user for which document he wants to open * * RETURNS: TRUE if successful, FALSE otherwise. * * CUSTOMIZATION: None, except your application may or may not call * CreateNewObj to create a default object. * */ BOOL OpenDoc (VOID) { CHAR szDoc[cchFilenameMax]; BOOL fUpdateLater; OLESTATUS olestatus;
if (SaveChangesOption (&fUpdateLater) == IDCANCEL) return FALSE;
if (!GetFileOpenFilename (szDoc)) { if (fUpdateLater) { // The user chose the "Yes, Update" button but the
// File Open dialog box failed for some reason
// (perhaps the user chose Cancel).
// Even though the user chose "Yes, Update", there is no way
// to update a client that does not accept updates
// except when the document is closed.
} return FALSE; }
if (fUpdateLater) { // The non-standard OLE client did not accept the update when
// we requested it, so we are sending the client OLE_CLOSED now that
// we are closing the document.
SendDocMsg (OLE_CLOSED); }
fRevokeSrvrOnSrvrRelease = FALSE;
if ((olestatus = RevokeDoc()) > OLE_WAIT_FOR_RELEASE) return FALSE; else if (olestatus == OLE_WAIT_FOR_RELEASE) Wait (&fWaitingForDocRelease);
fRevokeSrvrOnSrvrRelease = TRUE; EmbeddingModeOff();
if (!CreateDocFromFile (szDoc, 0, doctypeFromFile)) { MessageBox (hwndMain, "Reading from file failed.\r\nFile may not be in proper file format.", szAppName, MB_ICONEXCLAMATION | MB_OK); // We already revoked the document, so give the user a new one to edit.
CreateNewDoc (0, "(Untitled)", doctypeNew); CreateNewObj (FALSE); return FALSE; } fDocChanged = FALSE; return TRUE; }
/* ReadObj
* -------- * * Read the next object from a file, allocate memory for it, and return * a pointer to it. * * int fh - File handle * * RETURNS: A pointer to the object * * CUSTOMIZATION: Server Demo specific * */ static LPOBJ ReadObj (INT fh) { HANDLE hObj = NULL; LPOBJ lpobj = NULL;
hObj = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (OBJ));
if (hObj == NULL) return NULL;
lpobj = (LPOBJ) LocalLock (hObj);
if (lpobj==NULL) { LocalFree (hObj); return NULL; }
if (_lread(fh, (LPSTR) &lpobj->native, (UINT)sizeof(NATIVE)) < sizeof (NATIVE)) { LocalUnlock (hObj); LocalFree (hObj); return NULL; }
lpobj->hObj = hObj; lpobj->oleobject.lpvtbl = &objvtbl; lpobj->aName = GlobalAddAtom (lpobj->native.szName);
if (!CreateWindow( "ObjClass", "Obj", WS_THICKFRAME | WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE , lpobj->native.nX, lpobj->native.nY, lpobj->native.nWidth, lpobj->native.nHeight, hwndMain, NULL, hInst, (LPSTR) lpobj )) { LocalUnlock (hObj); LocalFree (hObj); return NULL; }
return lpobj; }
/* SaveDoc
* ------- * * Save the document. * * CUSTOMIZATION: None * */
BOOL SaveDoc (VOID) { if (docMain.doctype == doctypeNew) return SaveDocAs(); else { CHAR szDoc [cchFilenameMax];
GlobalGetAtomName (docMain.aName, szDoc, cchFilenameMax); return SaveDocIntoFile(szDoc); } }
/* SaveDocAs
* --------- * * Prompt the user for a filename, and save the document under that filename. * * RETURNS: TRUE if successful or user chose CANCEL * FALSE if SaveDocIntoFile fails * * CUSTOMIZATION: None * */ BOOL SaveDocAs (VOID) { CHAR szDoc[cchFilenameMax]; BOOL fUpdateLater; CHAR szDocOld[cchFilenameMax];
// If document is embedded, give user a chance to update.
// Save old document name in case the save fails.
if (!GlobalGetAtomName (docMain.aName, szDocOld, cchFilenameMax)) ErrorBox ("Fatal Error: Document name is invalid.");
if (GetFileSaveFilename (szDoc))
{
if (docMain.doctype == doctypeEmbedded) return SaveDocIntoFile(szDoc);
if (fUpdateLater) { // The non-standard OLE client did not accept the update when
// we requested it, so we are sending the client OLE_CLOSED now that
// we are closing the document.
SendDocMsg (OLE_CLOSED); }
// Set the window title bar.
SetTitle (szDoc, FALSE); OleRenameServerDoc(docMain.lhdoc, szDoc);
if (SaveDocIntoFile(szDoc)) return TRUE; else { // Restore old name
SetTitle (szDocOld, FALSE); OleRenameServerDoc(docMain.lhdoc, szDocOld); return FALSE; } } else // user chose Cancel
return FALSE; // The user chose the "Yes, Update" button but the
// File Open dialog box failed for some reason
// (perhaps the user chose Cancel).
// Even though the user chose "Yes, Update", there is no way
// to update a non-standard OLE client that does not accept updates
// except when the document is closed.
}
/* SaveDocIntoFile
* --------------- * * Save the document into a file whose name is determined from docMain.aName. * * RETURNS: TRUE if successful * FALSE otherwise * * CUSTOMIZATION: Re-implement * */ static BOOL SaveDocIntoFile (PSTR pDoc) { HWND hwnd; INT fh; // File handle
LPOBJ lpobj; HEADER hdr; INT i;
hwnd = GetWindow (hwndMain, GW_CHILD);
if (!hwnd) { ErrorBox ("Could not save NULL file."); return FALSE; }
// Get document name.
if ((fh =_lcreat(pDoc, 0)) == -1) { ErrorBox ("Could not save file."); return FALSE; }
// Fill in header.
lstrcpy (hdr.szSig, szSignature); hdr.chDelim1 = chDelim; hdr.version = version; hdr.chDelim2 = chDelim; for (i=1; i <= cfObjNums; i++) hdr.rgfObjNums[i] = docMain.rgfObjNums[i];
// Write header to file.
if (_lwrite(fh, (LPSTR) &hdr, (UINT)sizeof(HEADER)) < sizeof(HEADER)) goto Error; // Error writing file header
// Write each object's native data.
while (hwnd) { lpobj = (LPOBJ) GetWindowLong (hwnd, ibLpobj); if (_lwrite(fh, (LPSTR)&lpobj->native, (UINT)sizeof (NATIVE)) < sizeof(NATIVE)) goto Error; // Error writing file header
hwnd = GetWindow (hwnd, GW_HWNDNEXT); } _lclose(fh);
if (docMain.doctype != doctypeEmbedded) { docMain.doctype = doctypeFromFile; OleSavedServerDoc(docMain.lhdoc); fDocChanged = FALSE; }
return TRUE;
Error: _lclose(fh); ErrorBox ("Could not save file."); return FALSE;
}
/* Common Dialog functions */
/* InitOfn
* ------- * * Initialize an OPENFILENAME structure with default values. * OPENFILENAME is defined in CommDlg.h. * * * CUSTOMIZATION: Change lpstrFilter. You may also customize the common * dialog box if you wish. (See the Windows SDK documentation.) * */ static VOID InitOfn (OPENFILENAME *pofn) { // GetOpenFileName or GetSaveFileName will put the 8.3 filename into
// szFileTitle[].
// SrvrDemo does not use this filename, but rather uses the fully qualified
// pathname in pofn->lpstrFile[].
static CHAR szFileTitle[13];
pofn->Flags = 0; pofn->hInstance = hInst; pofn->hwndOwner = hwndMain; pofn->lCustData = 0; pofn->lpfnHook = NULL; pofn->lpstrCustomFilter = NULL; pofn->lpstrDefExt = szDefExt; // lpstrFile[] is the initial filespec that appears in the edit control.
// Must be set to non-NULL before calling the common dialog box function.
// On return, lpstrFile[] will contain the fully-qualified pathname
// corresponding to the file the user chose.
pofn->lpstrFile = NULL; pofn->lpstrFilter = "Server Demo (*." szDefExt ")\0*." szDefExt "\0" ; // lpstrFileTitle[] will contain the user's chosen filename without a path.
pofn->lpstrFileTitle = szFileTitle; pofn->lpstrInitialDir= NULL; // Title Bar. NULL means use default title.
pofn->lpstrTitle = NULL; pofn->lpTemplateName = NULL; pofn->lStructSize = sizeof (OPENFILENAME); pofn->nFilterIndex = 1L; pofn->nFileOffset = 0; pofn->nFileExtension = 0; pofn->nMaxFile = cchFilenameMax; pofn->nMaxCustFilter = 0L; }
/* GetFileOpenFilename
* ------------------- * * Call the common dialog box function GetOpenFileName to get a file name * from the user when the user chooses the "File Open" menu item. * * LPSTR lpszFilename - will contain the fully-qualified pathname on exit. * * RETURNS: TRUE if successful, FALSE otherwise. * * CUSTOMIZATION: None * */ BOOL GetFileOpenFilename (LPSTR lpszFilename) { OPENFILENAME ofn; InitOfn (&ofn); ofn.Flags |= OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; // Create initial filespec.
wsprintf (lpszFilename, "*.%s", (LPSTR) szDefExt); // Have the common dialog function return the filename in lpszFilename.
ofn.lpstrFile = lpszFilename; if (!GetOpenFileName (&ofn)) return FALSE; return TRUE; }
/* GetFileSaveFilename
* ------------------- * * Call the common dialog box function GetSaveFileName to get a file name * from the user when the user chooses the "File Save As" menu item, or the * "File Save" menu item for an unnamed document. * * LPSTR lpszFilename - will contain the fully-qualified pathname on exit. * * RETURNS: TRUE if successful, FALSE otherwise. * * CUSTOMIZATION: None * */ BOOL GetFileSaveFilename (LPSTR lpszFilename) { OPENFILENAME ofn; InitOfn (&ofn); ofn.Flags |= OFN_PATHMUSTEXIST | OFN_HIDEREADONLY; // Create initial filespec.
wsprintf (lpszFilename, "*.%s", (LPSTR) szDefExt); // Have the common dialog function return the filename in lpszFilename.
ofn.lpstrFile = lpszFilename; if (!GetSaveFileName (&ofn)) return FALSE; return TRUE; }
|