Baca dalam bahasa Inggris

Bagikan melalui


IPaper::Load

Kode sampel C++ berikut menunjukkan cara membuka aliran yang ada di penyimpanan, membaca properti kertas baru di lalu mengaturnya sebagai nilai saat ini untuk COPaper.

Berikut ini adalah metode IPaper::Load dari 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;
  }

Sekarang, metode IStorage::OpenStream dipanggil untuk membuka aliran yang ada di penyimpanan yang disebut "PAPERDATA". Bendera mode akses adalah untuk akses eksklusif baca-saja, langsung, dan non-bersama. Saat aliran terbuka, metode IStream::Read dipanggil untuk membaca struktur PAPER_PROPERTIES. Jika jumlah yang benar-benar dibaca tidak sama dengan jumlah yang diminta, operasi beban dibatalkan, dan E_FAIL dikembalikan. Jika versi format dalam PAPER_PROPERTIES yang baru dibaca tidak dikenali, maka operasi pemuatan dibatalkan dan Load mengembalikan E_FAIL.

Dengan versi format data tinta yang valid, ukuran array data tinta baru dari PAPER_PROPERTIES yang dibaca digunakan untuk mengalokasikan array data tinta baru dengan ukuran yang diperlukan. Data tinta yang ada dihapus, dan datanya hilang. Jika data ini berharga, seharusnya disimpan sebelum Load dipanggil. Setelah array baru dialokasikan, IStream::Read dipanggil lagi untuk membaca data ke dalam array dari aliran. Jika panggilan ini berhasil, nilai dalam properti kertas yang baru dibaca diadopsi sebagai nilai saat ini untuk COPaper.

Selama operasi pemuatan ini, struktur PAPER_PROPERTIES sementara, NewProps, digunakan untuk menahan properti baru yang dibaca. Jika semua berhasil dengan beban, NewProps disalin ke dalam struktur PAPER_PROPERTIES, m_PaperProperties. Seperti sebelumnya, setelah Pemuatan selesai dan IStream tidak lagi diperlukan, penunjuk IStream dirilis.

Jika ada kesalahan di akhir Muat, array data tinta dihapus, karena mungkin berisi data yang rusak.

Jika tidak ada kesalahan di akhir Beban, metode IPaperSink::Loaded klien dipanggil, dalam metode NotifySinks internal COPaper, untuk memberi tahu klien bahwa operasi beban selesai. Ini adalah pemberitahuan penting untuk klien, karena harus menampilkan data tinta baru yang dimuat ini. Pemberitahuan ini memanfaatkan fitur objek yang dapat dihubungkan secara signifikan di COPaper.