Udostępnij przez


IPaper::Load

Poniższy przykładowy kod języka C++ przedstawia sposób otwierania istniejącego strumienia w magazynie, odczytywania nowych właściwości papieru w programie, a następnie ustawiania ich jako bieżących wartości copaper.

Poniżej przedstawiono metodę IPaper::Load z 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;
  }

Teraz wywoływana jest metoda IStorage::OpenStream, aby otworzyć istniejący strumień w magazynie o nazwie "PAPERDATA". Flagi trybu dostępu dotyczą dostępu tylko do odczytu, bezpośredniego i nieudostępnianego dostępu wyłącznego. Po otwarciu strumienia wywoływana jest metoda IStream::Read w celu odczytania struktury PAPER_PROPERTIES. Jeśli kwota faktycznie odczyta nie jest równa żądanej kwoty, operacja ładowania zostanie przerwana, a E_FAIL zostanie zwrócona. Jeśli wersja formatu w nowo odczytanej PAPER_PROPERTIES nie jest rozpoznawana, operacja ładowania zostanie przerwana i load zwraca E_FAIL.

Z prawidłową wersją formatu danych pisma odręcznego rozmiar nowej tablicy danych pisma odręcznego z PAPER_PROPERTIES, który został odczytany, jest używany do przydzielenia nowej tablicy danych pisma odręcznego wymaganego rozmiaru. Istniejące dane pisma odkowego są usuwane, a ich dane zostaną utracone. Jeśli te dane były cenne, powinny zostać zapisane przed wywołaniem Load. Po przydzieleniu nowej tablicy IStream::Read jest wywoływana ponownie w celu odczytania danych do tablicy ze strumienia. Jeśli to wywołanie powiedzie się, wartości w nowo odczytanych właściwościach papieru zostaną przyjęte jako bieżące wartości copaper.

Podczas tej operacji ładowania użyto tymczasowej struktury PAPER_PROPERTIES NewProps do przechowywania nowych właściwości odczytanych. Jeśli obciążenie zakończy się powodzeniem, polecenie NewProps zostanie skopiowane do struktury PAPER_PROPERTIES, m_PaperProperties. Tak jak wcześniej, po zakończeniu ładowania i IStream nie jest już wymagany, wskaźnik IStream IStream jest zwalniany.

Jeśli na końcu ładowaniewystąpi błąd, tablica danych pisma odręcznego zostanie wymazana, ponieważ może zawierać uszkodzone dane.

Jeśli na końcu ładowanienie występuje błąd , wywoływana jest metoda IPaperSink::Load, w wewnętrznej metodzie NotifySinks COPaper, aby powiadomić klienta o zakończeniu operacji ładowania. Jest to ważne powiadomienie dla klienta, ponieważ musi wyświetlać te nowe załadowane dane pisma odkowego. To powiadomienie sprawia, że znaczące wykorzystanie funkcji obiektów możliwych do połączenia w programie COPaper.