IPaper::Load

Il codice di esempio C++ seguente illustra come aprire il flusso esistente nello spazio di archiviazione, leggere le nuove proprietà del documento in e quindi impostarle come valori correnti per COPaper.

Di seguito è riportato il metodo IPaper::Load da 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;
  }

Il metodo IStorage::OpenStream viene ora chiamato per aprire il flusso esistente nella risorsa di archiviazione denominata "PAPERDATA". I flag di modalità di accesso sono per l'accesso esclusivo in sola lettura, diretto e non condiviso. Quando il flusso è aperto, viene chiamato il metodo IStream::Read per leggere la struttura PAPER_PROPERTIES. Se l'importo effettivamente letto non è uguale alla quantità richiesta, l'operazione di caricamento viene interrotta e E_FAIL viene restituito. Se la versione del formato nel PAPER_PROPERTIES appena letto non viene riconosciuta, l'operazione di caricamento viene interrotta e Load restituisce E_FAIL.

Con una versione valida del formato dati input penna, le dimensioni della nuova matrice di dati input penna del PAPER_PROPERTIES letto in vengono usate per allocare una nuova matrice di dati input penna delle dimensioni richieste. I dati dell'input penna esistenti vengono eliminati e i relativi dati vengono persi. Se questi dati sono utili, dovrebbero essere stati salvati prima della chiamata a Load . Dopo aver allocato la nuova matrice, viene chiamato nuovamente IStream::Read per leggere i dati nella matrice dal flusso. Se la chiamata ha esito positivo, i valori nelle proprietà del documento appena letto vengono adottati come valori correnti per COPaper.

Durante questa operazione di caricamento, è stata usata una struttura di PAPER_PROPERTIES temporanea, NewProps, per contenere le nuove proprietà lette. Se il caricamento ha esito positivo, NewProps viene copiato nella struttura PAPER_PROPERTIES, m_PaperProperties. Come in precedenza, dopo il caricamento e l'IStream non è più necessario, il puntatore IStream viene rilasciato.

Se si verifica un errore alla fine del caricamento, la matrice di dati dell'input penna viene cancellata perché può contenere dati danneggiati.

Se non è presente alcun errore alla fine di Load, viene chiamato il metodo IPaperSink::Loaded client, nel metodo COPaper interno NotifySinks, per notificare al client che l'operazione di caricamento è stata completata. Si tratta di una notifica importante per il client, perché deve visualizzare questi nuovi dati input penna caricati. Questa notifica usa in modo significativo le funzionalità degli oggetti collegabili in COPaper.