To save a document, a client application should do the following:
Save the data for the document in the document's file.
For each object in the document, call the OleSaveToStream function (which in turn, calls the client application's Put callback function).
After all objects have been saved, call the OleSavedClientDoc function to inform the client DLL that all objects have been saved.
A client application can call the OleQuerySize function to determine the size of the buffer required to store an object before calling OleSaveToStream.
Note When saving objects in a container document, be careful not to save any presentation formats other than those needed to recreate the object—file size can grow dramatically saving needless formats. When saving embedded objects, only the Native data and the presentation data need to be stored in the container document. For linked objects, only the OwnerLink and presentation formats need to be stored.
CLIDEMO.EXE initiates the saving of a document by calling the SaveFile function. SaveFile displays a dialog box asking the user to save changes. If the user chooses to save the document, then SaveFile calls the WriteToFile function, which in turn calls ObjWrite. ObjWrite makes the necessary call to OleSaveToStream. After the data has been saved, SaveFile calls OleSavedClientDoc to notify the client DLL of the status.
/*
* SaveFile()
*
* Save a compound document file. If the file is untitled, ask the
* user for a name and save the document to that file.
*/
static BOOL SaveFile // ENTRY:
(PSTR pFileName, // file to save document to
LHCLIENTDOC lhcDoc, // OLE document handle
LPAPPSTREAM lpStream) // pointer to app. stream
// struct
{ // LOCAL:
char szNewFile[CBPATHMAX]; // New file name strings
char szOemFileName[2*CBPATHMAX];
static char szUntitled[CBMESSAGEMAX] = "";
HANDLE fh; // file handle
*szNewFile = NULL;
if (!(*szUntitled))
LoadString(hInst, IDS_UNTITLED, (LPSTR)szUntitled,CBMESSAGEMAX);
if (!lstrcmp(szUntitled, pFileName)) // get filename for the
// untitled case
{
if (!OfnGetName(hwndFrame, szNewFile, IDM_SAVEAS))
return FALSE; // CANCEL return
lstrcpy(pFileName,szNewFile);
SetTitle(pFileName);
}
AnsiToOem(pFileName, szOemFileName);
if ((fh =_lcreat((LPSTR)szOemFileName, 0)) <= 0)
{
ErrorMessage(E_INVALID_FILENAME);
return FALSE; // ERROR return
}
lpStream->fh = fh;
// save file on disk
if (!WriteToFile(lpStream))
{
_lclose(fh);
ErrorMessage(E_FAILED_TO_SAVE_FILE);
return FALSE; // ERROR return
}
_lclose(fh);
if (Error(OleSavedClientDoc(lhcDoc)))
{
ErrorMessage(W_FAILED_TO_NOTIFY);
return FALSE; // ERROR return
}
Dirty(DOC_CLEAN);
return TRUE; // SUCCESS return
}
/*
* WriteToFile()
*
* Write current document to a file.
*
* returns BOOL - TRUE if file successfully written
*/
BOOL FAR WriteToFile // ENTRY:
(LPAPPSTREAM lpStream) // application stream pointer
{ // LOCAL:
int iObjectsWritten=0; // counter of objects written
// to file
APPITEMPTR pItem; // application Item pointer
UpdateFromOpenServers();
_llseek(lpStream->fh, 0L, 0);
Hourglass(TRUE);
if (_lwrite(lpStream->fh, (LPSTR)&iObjects,
sizeof(int)) < sizeof(int))
goto Error;
for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
{
if (!ObjWrite(lpStream, pItem))
goto Error;
iObjectsWritten++;
}
if (iObjectsWritten != iObjects)
goto Error;
Dirty(DOC_CLEAN);
Hourglass(FALSE);
return(TRUE); // SUCCESS return
Error: // ERROR Tag
Hourglass(FALSE);
return(FALSE); // ERROR return
}
/*
* ObjWrite()
*
* This function writes an object to the specified
* file. The file pointer will be advanced past the end of
* the written object.
* Returns BOOL - TRUE if object written successfully
*/
BOOL FAR ObjWrite // ENTRY:
(LPAPPSTREAM lpStream, // application stream pointer
APPITEMPTR pItem) // application item pointer
{ // LOCAL:
POINT pt; // center of rec point
RECT rc; // bounding rectangle
int cbTmp;
char szTmp[PROTOCOL_STRLEN];// protocol string
cbTmp = CBOBJNAMEMAX;
OleQueryName(pItem->lpObject, szTmp, &cbTmp);
if (_lwrite(lpStream->fh, szTmp, CBOBJNAMEMAX) < CBOBJNAMEMAX )
return FALSE;
if (pItem->otObject == OT_STATIC)
wsprintf(szTmp, "%-15s", STATICP);
else
wsprintf(szTmp, "%-15s", STDFILEEDITING);
if (_lwrite(lpStream->fh, szTmp,PROTOCOL_STRLEN) < PROTOCOL_STRLEN )
return FALSE;
if (Error(OleSaveToStream(pItem->lpObject,
(LPOLESTREAM)&(lpStream->olestream))))
return FALSE;
GetClientRect(pItem->hwnd, (LPRECT)&rc);
pt = *(LPPOINT)&rc;
ClientToScreen(pItem->hwnd, (LPPOINT)&pt);
ScreenToClient(hwndFrame, (LPPOINT)&pt);
OffsetRect(&rc, pt.x - rc.left - GetSystemMetrics(SM_CXFRAME),
pt.y - rc.top - GetSystemMetrics(SM_CYFRAME));
if (_lwrite(lpStream->fh, (LPSTR)&rc, sizeof(RECT)) < sizeof(RECT)
|| _lwrite(lpStream->fh, (LPSTR)&(pItem->otObject),
sizeof(long)) < sizeof(long))
return FALSE;
return TRUE; // SUCCESS return
}