windows-nt/Source/XPSP1/NT/com/winole/samples/clidemo/stream.c
2020-09-26 16:20:57 +08:00

349 lines
11 KiB
C

/*
* stream.c - io stream function callbacks
*
* Created by Microsoft Corporation.
* (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved
*/
/***************************************************************************
* This file contains all routines that directly and indirectly deal with
* file i/o. The OLE stream call back functions exist in this file.
**************************************************************************/
//*** INCLUDES ***
#include <windows.h>
#include <ole.h>
#include "global.h"
#include "utility.h"
#include "stream.h"
#include "object.h"
#include "demorc.h"
//*** Globals ***
BOOL fLoadFile = FALSE;
/***************************************************************************
* ReadStream() - OLE Callback Function (Get)
*
* This function is pointed to from the OLESTREAM vtbl; it is Get.
*
* returns DWORD - number of bytes actually read
**************************************************************************/
DWORD APIENTRY ReadStream( //* ENTRY:
LPAPPSTREAM lpStream, //* application stream pointer
LPSTR lpstr, //* string pointer
DWORD cb //* byte count
){
return _lread(lpStream->fh, lpstr, cb);
}
/***************************************************************************
* WriteStream() - OLE Callback function (Put)
*
* This function is pointed to from the OLESTREAM vtbl; it is Put.
*
* Returns DWORD - number of bytes actually written
**************************************************************************/
DWORD APIENTRY WriteStream( //* ENTRY:
LPAPPSTREAM lpStream, //* application stream pointer
LPSTR lpstr, //* string pointer
DWORD cb //* number of bytes to write
){
return _lwrite(lpStream->fh, lpstr, cb);
}
/****************************************************************************
* ReadFromFile()
*
* This function reads OLE objects from a file. If the document
* contains manual links, the user will be prompted to update those links.
*
* Returns BOOL - TRUE if the read(s) were successful
***************************************************************************/
BOOL FAR ReadFromFile( //* ENTRY:
LPAPPSTREAM lpStream, //* application stream pointer
LHCLIENTDOC lhcDoc, //* document handle
LPOLECLIENT lpClient //* pointer to OLE client structure
){ //* LOCAL:
BOOL bReturn = FALSE; //* return value
INT cFileObjects; //* number of file objects
Hourglass(TRUE);
fLoadFile = TRUE;
SetFilePointer((HANDLE)lpStream->fh, 0, NULL, 0);
//* in the file
if (_lread(lpStream->fh, (LPSTR)&cFileObjects, sizeof(INT)) < sizeof(INT))
goto Error;
for (; cFileObjects; --cFileObjects)
{
if (!ObjRead(lpStream,lhcDoc,lpClient))
{
ErrorMessage(E_FAILED_TO_READ_OBJECT);
goto Error;
}
}
ShowDoc(lhcDoc,1);
UpdateLinks(lhcDoc);
bReturn = TRUE; //* SUCCESS
Error: //* ERROR Tag
Hourglass(FALSE);
fLoadFile = FALSE;
return bReturn; //* return
}
/****************************************************************************
* ObjRead()
*
* Rread an object from the specified file. The file pointer will
* be advanced past the object.
*
* HANDLE fh - DOS file handle of file to be read from
*
* returns HWND - window handle to item window containing the OLE object
***************************************************************************/
BOOL FAR ObjRead( //* ENTRY:
LPAPPSTREAM lpStream, //* application stream pointer
LHCLIENTDOC lhcDoc, //* document handle
LPOLECLIENT lpClient //* pointer to OLE client structure
){ //* LOCAL:
APPITEMPTR pItem; //* application item pointer
LPOLEOBJECT lpObject; //* pointer ole object
LONG otObject; //* type of object
RECT rcObject; //* object rect
CHAR szTmp[CBOBJNAMEMAX]; //* temporary string buffer
CHAR szProto[PROTOCOL_STRLEN+1];//* protocol string
INT i; //* index
if (_lread(lpStream->fh, szTmp, CBOBJNAMEMAX) < CBOBJNAMEMAX )
return FALSE;
if (_lread(lpStream->fh, szProto, PROTOCOL_STRLEN) < PROTOCOL_STRLEN )
return FALSE;
for (i=0; szProto[i] != ' '; i++);
szProto[i] = 0;
ValidateName( szTmp );
if (!(pItem = PreItemCreate(lpClient, TRUE, lhcDoc)))
return FALSE;
if (Error(OleLoadFromStream((LPOLESTREAM)&(lpStream->olestream),
szProto,(LPOLECLIENT)&(pItem->oleclient), lhcDoc, szTmp, &lpObject)))
goto Error;
if (_lread(lpStream->fh, (LPSTR)&rcObject, sizeof(RECT)) < sizeof(RECT))
goto Error;
if (_lread(lpStream->fh, (LPSTR)&otObject, sizeof(LONG)) < sizeof(LONG))
goto Error;
if (PostItemCreate(lpObject, otObject, &rcObject, pItem))
{
pItem->fNew = TRUE;
ObjSetBounds(pItem);
return TRUE; //* SUCCESS return
}
else
return FALSE;
Error: //* ERROR Tag
FreeAppItem(pItem);
return FALSE;
}
/*************************************************************************
* 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();
SetFilePointer((HANDLE)lpStream->fh, 0, NULL, 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
UINT cbTmp = CBOBJNAMEMAX;
CHAR szTmp[PROTOCOL_STRLEN];//* protocol string
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
}
/****************************************************************************
* UpdateLinks()
*
* Get the most up to date rendering information and show it.
***************************************************************************/
static VOID UpdateLinks( //* ENTRY
LHCLIENTDOC lhcDoc //* client document handle
){ //* LOCAL:
INT i=0; //* index
APPITEMPTR pItem; //* temporary item pointer
CHAR szUpdate[CBMESSAGEMAX];//* update message?
for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
{
if (pItem->lhcDoc == lhcDoc && pItem->otObject == OT_LINK)
{
if (!i)
{
LoadString(hInst, IDS_UPDATELINKS, szUpdate, CBMESSAGEMAX);
if (MessageBox(hwndFrame, szUpdate, szAppName,
MB_YESNO | MB_ICONEXCLAMATION) != IDYES)
break;
i++;
}
Error(OleUpdate(pItem->lpObject));
}
}
WaitForAllObjects();
}
/****************************************************************************
* UpdateFromOpenServers()
*
* Get the most up to date rendering information before storing it.
***************************************************************************/
static VOID UpdateFromOpenServers(VOID)
{ //* LOCAL:
APPITEMPTR pItem; //* temporary item pointer
APPITEMPTR pItemNext;
for (pItem = GetTopItem(); pItem; pItem = pItemNext)
{
pItemNext = GetNextItem(pItem);
if (pItem->otObject == OT_EMBEDDED ||
(pItem->uoObject == oleupdate_oncall
&& pItem->otObject == OT_LINK ))
if (OleQueryOpen(pItem->lpObject) == OLE_OK)
{
CHAR szMessage[2*CBMESSAGEMAX];
CHAR szBuffer[CBMESSAGEMAX];
UINT cb = CBOBJNAMEMAX; //* The name will be the server window title.
CHAR szTmp[CBOBJNAMEMAX]; //* when the object is edited.
Error(OleQueryName(pItem->lpObject,szTmp,&cb));
LoadString(hInst, IDS_UPDATE_OBJ, szBuffer, CBMESSAGEMAX);
wsprintf(szMessage, szBuffer, (LPSTR)szTmp);
if (MessageBox(hwndFrame, szMessage, szAppName, MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
{
Error(OleUpdate(pItem->lpObject));
WaitForObject(pItem);
}
if (!pItem->fVisible)
ObjDelete(pItem, OLE_OBJ_DELETE);
}
}
WaitForAllObjects();
}