home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / SAMPLES / CLIDEMO / STREAM.C_ / STREAM.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  14.3 KB  |  429 lines

  1. /*
  2.  * stream.c - io stream function callbacks
  3.  *
  4.  * Created by Microsoft Corporation.
  5.  * (c) Copyright Microsoft Corp. 1990 - 1992  All Rights Reserved
  6.  */
  7.  
  8. /***************************************************************************
  9.  * This file contains all routines that directly and indirectly deal with
  10.  * file i/o.  The OLE stream call back functions exist in this file.
  11.  **************************************************************************/
  12.  
  13. //--- INCLUDES ---
  14. //The order of the includes matters for compile efficiency ... /YX
  15.  
  16. #include <windows.h>
  17. #include <ole.h>
  18. #include "demorc.h"
  19. #include "global.h"
  20.  
  21. #include "utility.h"
  22. #include "stream.h"
  23. #include "object.h"
  24.  
  25.  
  26. //--- Globals ---
  27.  
  28. BOOL fLoadFile = FALSE;
  29.  
  30. /***************************************************************************
  31.  *  lread()
  32.  *
  33.  *  This is function is essentially an _lread() that
  34.  *  can read more than 64K. We need this due to the fact
  35.  *  that objects and files may be greater than 64K.
  36.  *  This function must be declared PASCAL so that it won't
  37.  *  conflict with the _lread() function.
  38.  *
  39.  *  returns DWORD       - number of bytes actually read
  40.  **************************************************************************/
  41.  
  42. DWORD PASCAL lread(                    //- ENTRY:
  43.    HANDLE         hFile,               //- DOS file handle
  44.    void FAR       *pBuffer,            //- buffer to be read into from hfile
  45.    DWORD          dwBytes              //- byte count
  46. ){                                     //- LOCAL:
  47.    BYTE  huge     *hpBuffer = pBuffer; //- buffer containing data read
  48.    DWORD          dwByteCount = dwBytes;//- number of bytes read
  49.  
  50.    while (dwByteCount > MAXREAD)
  51.    {
  52.       if (_lread(hFile, hpBuffer, (WORD)MAXREAD) != MAXREAD)
  53.          return(dwBytes - dwByteCount);
  54.       dwByteCount -= MAXREAD;
  55.       hpBuffer += MAXREAD;
  56.    }
  57.  
  58.  
  59.    if ((dwByteCount -= (DWORD)_lread(hFile, hpBuffer, (WORD)dwByteCount)))
  60.       return(dwBytes - dwByteCount);
  61.  
  62.    return dwBytes;                      //- return
  63. }
  64.  
  65. /***************************************************************************
  66.  *  lwrite()
  67.  *
  68.  *  This function is essentially an _lwrite() which can handle writes
  69.  *  greater than 64K. This function must be declared PASCAL so that it
  70.  *  won't conflict with the _lwrite() function.
  71.  *
  72.  *  Returns DWORD       - number of bytes actually written
  73.  **************************************************************************/
  74.  
  75. DWORD PASCAL lwrite(                   //- ENTRY:
  76.    HANDLE         hFile,               //- DOS file handle
  77.    void FAR       *pBuffer,            //- buffer to write to hfile
  78.    DWORD          dwBytes              //- number of bytes
  79. ){                                     //- LOCAL:
  80.    DWORD          dwByteCount = dwBytes;//- number of bytes to write
  81.    BYTE  huge     *hpBuffer = pBuffer; //- buffer of data to be written
  82.  
  83.    while (dwByteCount > MAXREAD)
  84.    {
  85.       if (_lwrite(hFile, (LPSTR)hpBuffer, (WORD)MAXREAD) != MAXREAD)
  86.          return(dwBytes - dwByteCount);
  87.       dwByteCount -= MAXREAD;
  88.       hpBuffer += MAXREAD;
  89.    }
  90.  
  91.    if ((dwByteCount -= _lwrite(hFile, (LPSTR)hpBuffer, (WORD)dwByteCount)))
  92.       return(dwBytes - dwByteCount);   //- less bytes than requested read
  93.  
  94.    return dwBytes;                     //- return
  95. }
  96.  
  97. /***************************************************************************
  98.  *  ReadStream() - OLE Callback Function (Get)
  99.  *
  100.  *  This function is pointed to from the OLESTREAM vtbl; it is Get.
  101.  *  A branch is made based upon whether or not the read request is
  102.  *  greater than 64K.
  103.  *
  104.  *  returns DWORD  - number of bytes actually read
  105.  **************************************************************************/
  106.  
  107. DWORD FAR PASCAL __export ReadStream(  //- ENTRY:
  108.    LPAPPSTREAM    lpStream,            //- application stream pointer
  109.    LPSTR          lpstr,               //- string pointer
  110.    DWORD          cb                   //- byte count
  111. ){
  112.  
  113.    if (cb < 0x00010000)
  114.       return _lread(lpStream->fh, lpstr, (WORD) cb);
  115.    else
  116.       return lread(lpStream->fh, lpstr, cb);
  117.  
  118. }
  119.  
  120. /***************************************************************************
  121.  *  WriteStream() - OLE Callback function (Put)
  122.  *
  123.  *  This function is pointed to from the OLESTREAM vtbl; it is Put.
  124.  *  A branch is made based upon wether or not the write request is
  125.  *  greater than 64K.
  126.  *
  127.  *  Returns DWORD  - number of bytes actually written
  128.  **************************************************************************/
  129.  
  130. DWORD FAR PASCAL __export WriteStream( //- ENTRY:
  131.    LPAPPSTREAM    lpStream,            //- application stream pointer
  132.    LPSTR          lpstr,               //- string pointer
  133.    DWORD          cb                   //- number of bytes to write
  134. ){
  135.  
  136.    if (cb < 0x00010000)
  137.       return _lwrite(lpStream->fh, lpstr, (WORD) cb);
  138.    else
  139.       return lwrite(lpStream->fh, lpstr, cb);
  140.  
  141. }
  142.  
  143. /****************************************************************************
  144.  *  ReadFromFile()
  145.  *
  146.  *  This function reads OLE objects from a file. If the document
  147.  *  contains manual links, the user will be prompted to update those links.
  148.  *
  149.  *  Returns BOOL  - TRUE if the read(s) were successful
  150.  ***************************************************************************/
  151.  
  152. BOOL FAR ReadFromFile(                 //- ENTRY:
  153.    LPAPPSTREAM    lpStream,            //- application stream pointer
  154.    LHCLIENTDOC    lhcDoc,              //- document handle
  155.    LPOLECLIENT    lpClient             //- pointer to OLE client structure
  156. ){                                     //- LOCAL:
  157.    BOOL           bReturn = FALSE;     //- return value
  158.    unsigned int   cFileObjects;        //- number of file objects
  159.  
  160.    Hourglass(TRUE);
  161.    fLoadFile = TRUE;
  162.  
  163.    _llseek(lpStream->fh, 0L, 0);       //- Read the number of objects
  164.                                        //- in the file
  165.    if (_lread(lpStream->fh, (LPSTR)&cFileObjects, sizeof(int)) < sizeof(int))
  166.       goto Error;
  167.  
  168.    for (; cFileObjects; --cFileObjects)
  169.    {
  170.       if (!ObjRead(lpStream,lhcDoc,lpClient))
  171.       {
  172.          ErrorMessage(E_FAILED_TO_READ_OBJECT);
  173.          goto Error;
  174.       }
  175.    }
  176.  
  177.    ShowDoc(lhcDoc,1);
  178.    UpdateLinks(lhcDoc);
  179.  
  180.    bReturn = TRUE;                     //- SUCCESS
  181.  
  182. Error:                                 //- ERROR Tag
  183.  
  184.    Hourglass(FALSE);
  185.    fLoadFile = FALSE;
  186.    return bReturn;                     //- return
  187.  
  188. }
  189.  
  190. /****************************************************************************
  191.  *  ObjRead()
  192.  *
  193.  *  Rread an object from the specified file. The file pointer will
  194.  *  be advanced past the object.
  195.  *
  196.  *  HANDLE fh     - DOS file handle of file to be read from
  197.  *
  198.  *  returns HWND  - window handle to item window containing the OLE object
  199.  ***************************************************************************/
  200.  
  201. BOOL FAR ObjRead(                      //- ENTRY:
  202.    LPAPPSTREAM    lpStream,            //- application stream pointer
  203.    LHCLIENTDOC    lhcDoc,              //- document handle
  204.    LPOLECLIENT    lpClient             //- pointer to OLE client structure
  205. ){                                     //- LOCAL:
  206.    APPITEMPTR     pItem;               //- application item pointer
  207.    LPOLEOBJECT    lpObject;            //- pointer ole object
  208.    long           otObject;            //- type of object
  209.    RECT           rcObject;            //- object rect
  210.    char           szTmp[CBOBJNAMEMAX]; //- temporary string buffer
  211.    char           szProto[PROTOCOL_STRLEN+1];//- protocol string
  212.    int            i;                   //- index
  213.  
  214.    if (_lread(lpStream->fh, szTmp, CBOBJNAMEMAX) < CBOBJNAMEMAX )
  215.       return FALSE;
  216.  
  217.    if (_lread(lpStream->fh, szProto, PROTOCOL_STRLEN) < PROTOCOL_STRLEN )
  218.       return FALSE;
  219.  
  220.    for (i=0; szProto[i] != ' '; i++);
  221.    szProto[i] = NULL;
  222.  
  223.    ValidateName( szTmp );
  224.  
  225.    if (!(pItem = PreItemCreate(lpClient, TRUE, lhcDoc)))
  226.       return FALSE;
  227.  
  228.    if (Error(OleLoadFromStream((LPOLESTREAM)&(lpStream->olestream),
  229.          szProto,(LPOLECLIENT)&(pItem->oleclient), lhcDoc, szTmp, &lpObject)))
  230.       goto Error;
  231.  
  232.    if (_lread(lpStream->fh, (LPSTR)&rcObject, sizeof(RECT)) < sizeof(RECT))
  233.       goto Error;
  234.  
  235.    if (_lread(lpStream->fh, (LPSTR)&otObject, sizeof(long)) < sizeof(long))
  236.       goto Error;
  237.  
  238.    if (PostItemCreate(lpObject, otObject, &rcObject, pItem))
  239.    {
  240.       pItem->fNew = TRUE;
  241.       ObjSetBounds(pItem);
  242.       return TRUE;                     //- SUCCESS return
  243.    }
  244.    else
  245.       return FALSE;
  246.  
  247. Error:                                 //- ERROR Tag
  248.  
  249.    FreeAppItem(pItem);
  250.    return FALSE;
  251.  
  252. }
  253.  
  254. /*************************************************************************
  255.  *  WriteToFile()
  256.  *
  257.  *  Write current document to a file.
  258.  *
  259.  *  returns BOOL - TRUE if file successfully written
  260.  ************************************************************************/
  261.  
  262. BOOL FAR WriteToFile(                  //- ENTRY:
  263.    LPAPPSTREAM    lpStream             //- application stream pointer
  264. ){                                     //- LOCAL:
  265.    int            iObjectsWritten=0;   //- counter of objects written to file
  266.    APPITEMPTR     pItem;               //- application Item pointer
  267.  
  268.    UpdateFromOpenServers();
  269.  
  270.    _llseek(lpStream->fh, 0L, 0);
  271.  
  272.    Hourglass(TRUE);
  273.  
  274.    if (_lwrite(lpStream->fh, (LPSTR)&iObjects, sizeof(int)) < sizeof(int))
  275.       goto Error;
  276.  
  277.    for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
  278.    {
  279.       if (!ObjWrite(lpStream, pItem))
  280.          goto Error;
  281.       iObjectsWritten++;
  282.    }
  283.  
  284.    if (iObjectsWritten != iObjects)
  285.       goto Error;
  286.  
  287.  
  288.    Dirty(DOC_CLEAN);
  289.    Hourglass(FALSE);
  290.    return(TRUE);                       //- SUCCESS return
  291.  
  292. Error:                                 //- ERROR Tag
  293.  
  294.    Hourglass(FALSE);
  295.    return(FALSE);                      //- ERROR return
  296.  
  297. }
  298.  
  299. /****************************************************************************
  300.  *  ObjWrite()
  301.  *
  302.  *  This function writes an object to the specified
  303.  *  file. The file pointer will be advanced past the end of
  304.  *  the written object.
  305.  
  306.  *  Returns BOOL - TRUE if object written successfully
  307.  ***************************************************************************/
  308.  
  309. BOOL FAR ObjWrite(                     //- ENTRY:
  310.    LPAPPSTREAM    lpStream,            //- application stream pointer
  311.    APPITEMPTR     pItem                //- application item pointer
  312. ){                                     //- LOCAL:
  313.   POINT           pt;                  //- center of rec point
  314.   RECT            rc;                  //- bounding rectangle
  315.   int             cbTmp;
  316.   char            szTmp[PROTOCOL_STRLEN];//- protocol string
  317.  
  318.    cbTmp = CBOBJNAMEMAX;
  319.    OleQueryName(pItem->lpObject, szTmp, &cbTmp);
  320.  
  321.    if (_lwrite(lpStream->fh, szTmp, CBOBJNAMEMAX) < CBOBJNAMEMAX )
  322.       return FALSE;
  323.  
  324.    if (pItem->otObject == OT_STATIC)
  325.       wsprintf(szTmp, "%-15s", STATICP);
  326.    else
  327.       wsprintf(szTmp, "%-15s", STDFILEEDITING);
  328.  
  329.    if (_lwrite(lpStream->fh, szTmp, PROTOCOL_STRLEN) < PROTOCOL_STRLEN )
  330.       return FALSE;
  331.  
  332.    if (Error(OleSaveToStream(pItem->lpObject, (LPOLESTREAM)&(lpStream->olestream))))
  333.       return FALSE;
  334.  
  335.    GetClientRect(pItem->hwnd, (LPRECT)&rc);
  336.    pt = *(LPPOINT)&rc;
  337.    ClientToScreen(pItem->hwnd, (LPPOINT)&pt);
  338.    ScreenToClient(hwndFrame, (LPPOINT)&pt);
  339.    OffsetRect(
  340.       &rc,
  341.       pt.x - rc.left - GetSystemMetrics(SM_CXFRAME),
  342.       pt.y - rc.top  - GetSystemMetrics(SM_CYFRAME)
  343.    );
  344.  
  345.    if (_lwrite(lpStream->fh, (LPSTR)&rc, sizeof(RECT)) < sizeof(RECT)
  346.          || _lwrite(lpStream->fh, (LPSTR)&(pItem->otObject), sizeof(long)) < sizeof(long))
  347.       return FALSE;
  348.  
  349.    return TRUE;                        //- SUCCESS return
  350.  
  351. }
  352.  
  353. /****************************************************************************
  354.  * UpdateLinks()
  355.  *
  356.  * Get the most up to date rendering information and show it.
  357.  ***************************************************************************/
  358.  
  359. static void UpdateLinks(               //- ENTRY
  360.    LHCLIENTDOC    lhcDoc               //- client document handle
  361. ){                                     //- LOCAL:
  362.    int            i=0;                 //- index
  363.    APPITEMPTR     pItem;               //- temporary item pointer
  364.    char           szUpdate[CBMESSAGEMAX];//- update message?
  365.  
  366.    for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
  367.    {
  368.       if (pItem->lhcDoc == lhcDoc && pItem->otObject == OT_LINK)
  369.       {
  370.          if (!i)
  371.          {
  372.             LoadString(hInst, IDS_UPDATELINKS, szUpdate, CBMESSAGEMAX);
  373.             if (MessageBox(hwndFrame, szUpdate, szAppName,
  374.                MB_YESNO | MB_ICONEXCLAMATION) != IDYES)
  375.                break;
  376.             i++;
  377.          }
  378.          Error(OleUpdate(pItem->lpObject));
  379.       }
  380.    }
  381.  
  382.    WaitForAllObjects();
  383.  
  384. }
  385.  
  386. /****************************************************************************
  387.  * UpdateFromOpenServers()
  388.  *
  389.  * Get the most up to date rendering information before storing it.
  390.  ***************************************************************************/
  391.  
  392. static void UpdateFromOpenServers(void)
  393. {                                      //- LOCAL:
  394.    APPITEMPTR pItem;                   //- temporary item pointer
  395.    APPITEMPTR pItemNext;
  396.  
  397.    for (pItem = GetTopItem(); pItem; pItem = pItemNext)
  398.    {
  399.       pItemNext = GetNextItem(pItem);
  400.       if (pItem->otObject == OT_EMBEDDED ||
  401.          (pItem->uoObject == oleupdate_oncall
  402.                && pItem->otObject == OT_LINK ))
  403.  
  404.          if (OleQueryOpen(pItem->lpObject) == OLE_OK)
  405.          {
  406.             char szMessage[2*CBMESSAGEMAX];
  407.             char szBuffer[CBMESSAGEMAX];
  408.             int cb = CBOBJNAMEMAX;     //- The name will be the server window title.
  409.             char szTmp[CBOBJNAMEMAX];  //- when the object is edited.
  410.  
  411.             Error(OleQueryName(pItem->lpObject,szTmp,&cb));
  412.             LoadString(hInst, IDS_UPDATE_OBJ, szBuffer, CBMESSAGEMAX);
  413.             wsprintf(szMessage, szBuffer, (LPSTR)szTmp);
  414.  
  415.             if (MessageBox(hwndFrame, szMessage, szAppName, MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
  416.             {
  417.                Error(OleUpdate(pItem->lpObject));
  418.                WaitForObject(pItem);
  419.             }
  420.             if (!pItem->fVisible)
  421.                ObjDelete(pItem, DELETE);
  422.          }
  423.  
  424.    }
  425.  
  426.    WaitForAllObjects();
  427.  
  428. }
  429.