Freigeben über


IPaper::Load

Der folgende C++-Beispielcode zeigt, wie sie den vorhandenen Datenstrom im Speicher öffnen, neue Papiereigenschaften lesen und dann als aktuelle Werte für COPaper festlegen.

Es folgt die IPaper::Load-Methode aus Paper.cpp.

STDMETHODIMP COPaper::CImpIPaper::Load(
                 SHORT nLockKey,
                 IStorage* pIStorage)
  {
    HRESULT hr = E_FAIL;
    IStream* pIStream;
    INKDATA* paInkData;
    ULONG ulToRead, ulReadIn;
    LONG lNewArraySize;
    PAPER_PROPERTIES NewProps;

    if (OwnThis())
    {
      if (m_bLocked && m_cLockKey == nLockKey && NULL != pIStorage)
      {
       // Open the "PAPERDATA" stream where the paper data is stored.
        hr = pIStorage->OpenStream(
               STREAM_PAPERDATA_USTR,
               0,
               STGM_READ | STGM_DIRECT | STGM_SHARE_EXCLUSIVE,
               0,
               &pIStream);
        if (SUCCEEDED(hr))
        {
          // Obtained paper data stream. Read the Paper Properties.
          ulToRead = sizeof(PAPER_PROPERTIES);
          hr = pIStream->Read(
                           &NewProps,
                           ulToRead,
                           &ulReadIn);
          if (SUCCEEDED(hr) && ulToRead != ulReadIn)
            hr = E_FAIL;
          if (SUCCEEDED(hr))
          {
            // Handle the different versions of ink data format.
            switch (NewProps.lInkDataVersion)
            {
              case INKDATA_VERSION10:
                // Allocate an ample-sized ink data array.
                lNewArraySize = NewProps.lInkArraySize + 
                                               INKDATA_ALLOC;
                paInkData = new INKDATA[(LONG) lNewArraySize];
                if (NULL != paInkData)
                {
                  // Delete the old ink data array.
                  delete [] m_paInkData;

                  // Assign the new array.
                  m_paInkData = paInkData;
                  m_lInkDataMax = lNewArraySize;

                  // Read the complete array of Ink Data.
                  ulToRead = NewProps.lInkArraySize * sizeof(INKDATA);
                  hr = pIStream->Read(m_paInkData, 
                                      ulToRead, &ulReadIn);
                  if (SUCCEEDED(hr) && ulToRead != ulReadIn)
                    hr = E_FAIL;
                  if (SUCCEEDED(hr))
                  {
                    // Set COPaper to use the new PAPER_PROPERTIES
                    // data.
                    m_lInkDataEnd = NewProps.lInkArraySize-1;
                    m_crWinColor = NewProps.crWinColor;
                    m_WinRect.right = NewProps.WinRect.right;
                    m_WinRect.bottom = NewProps.WinRect.bottom;

                    // Copy the new properties into current 
                    // properties.
                    memcpy(
                      &m_PaperProperties,
                      &NewProps,
                      sizeof(PAPER_PROPERTIES));
                  }
                }
                else
                  hr = E_OUTOFMEMORY;
                break;
              default:
                hr = E_FAIL;  // Bad version.
                break;
            }
          }

          // Release the stream.
          pIStream->Release();
        }
      }

      UnOwnThis();
    }

    // Notify other connected clients that Paper is now loaded.
    // If Paper not loaded, then erase to a safe, empty ink data 
    // array.
    if (SUCCEEDED(hr))
      m_pBackObj->NotifySinks(PAPER_EVENT_LOADED, 0, 0, 0, 0);
    else
      Erase(nLockKey);

    return hr;
  }

Nun wird die IStorage::OpenStream--Methode aufgerufen, um den vorhandenen Datenstrom im Speicher namens "PAPERDATA" zu öffnen. Zugriffsmoduskennzeichnungen gelten für schreibgeschützten, direkten und nicht freigegebenen exklusiven Zugriff. Wenn der Datenstrom geöffnet ist, wird die IStream::Read-Methode aufgerufen, um die PAPER_PROPERTIES Struktur zu lesen. Wenn der tatsächlich gelesene Betrag nicht dem angeforderten Betrag entspricht, wird der Ladevorgang abgebrochen und E_FAIL zurückgegeben. Wenn die Formatversion im neu gelesenen PAPER_PROPERTIES nicht erkannt wird, wird der Ladevorgang abgebrochen, und Load gibt E_FAIL zurück.

Bei einer gültigen Freihanddatenformatversion wird die Größe des neuen Freihanddatenarrays aus der PAPER_PROPERTIES verwendet, die gelesen wurde, um ein neues Freihanddatenarray der erforderlichen Größe zuzuweisen. Die vorhandenen Freihanddaten werden gelöscht, und ihre Daten gehen verloren. Wenn diese Daten hilfreich waren, sollte sie gespeichert werden, bevor Laden aufgerufen wurde. Nachdem das neue Array zugewiesen wurde, wird IStream::Read erneut aufgerufen, um die Daten aus dem Datenstrom in das Array zu lesen. Wenn dieser Aufruf erfolgreich ist, werden die Werte in den neu gelesenen Papiereigenschaften als die aktuellen Werte für COPaper übernommen.

Während dieses Ladevorgangs wurde eine temporäre PAPER_PROPERTIES Struktur NewProps verwendet, um die neuen Eigenschaften zu lesen. Wenn alle erfolgreich beim Laden ausgeführt werden, wird NewProps in die PAPER_PROPERTIES-Struktur kopiert, m_PaperProperties. Wie zuvor, nach Abschluss des Ladens und das IStream- nicht mehr erforderlich ist, wird der IStream- Zeiger freigegeben.

Wenn am Ende der Loadein Fehler auftritt, wird das Freihanddatenarray gelöscht, da es beschädigte Daten enthalten kann.

Wenn am Ende der Loadkein Fehler auftritt, wird der Client IPaperSink::Loaded-Methode in der internen NotifySinks-Methode von COPaper aufgerufen, um den Client darüber zu benachrichtigen, dass der Ladevorgang abgeschlossen ist. Dies ist eine wichtige Benachrichtigung für den Client, da diese neuen geladenen Freihanddaten angezeigt werden müssen. Diese Benachrichtigung verwendet erhebliche Funktionen von verbindungsfähigen Objekten in COPaper.