영어로 읽기

다음을 통해 공유


IPaper::Load

다음 C++ 샘플 코드는 스토리지에서 기존 스트림을 열고 에서 새 용지 속성을 읽은 다음 COPaper의 현재 값으로 설정하는 방법을 보여 줍니다.

다음은 Paper.cpp의 IPaper::Load 메서드입니다.

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;
  }

이제 IStorage::OpenStream 메서드가 호출되어 "PAPERDATA"라는 스토리지에서 기존 스트림을 엽니다. 액세스 모드 플래그는 읽기 전용, 직접 및 비 공유 전용 액세스용입니다. 스트림이 열리면 IStream::Read 메서드가 호출되어 PAPER_PROPERTIES 구조를 읽습니다. 실제로 읽은 양이 요청된 양과 같지 않으면 로드 작업이 중단되고 E_FAIL 반환됩니다. 새로 읽은 PAPER_PROPERTIES 형식 버전이 인식되지 않으면 로드 작업이 중단되고 Load 가 E_FAIL 반환됩니다.

유효한 잉크 데이터 형식 버전을 사용하면 읽은 PAPER_PROPERTIES 새 잉크 데이터 배열의 크기를 사용하여 필요한 크기의 새 잉크 데이터 배열을 할당합니다. 기존 잉크 데이터가 삭제되고 해당 데이터가 손실됩니다. 이 데이터가 중요한 경우 Load 가 호출되기 전에 저장되어야 합니다. 새 배열이 할당된 후 IStream::Read 가 다시 호출되어 스트림에서 배열로 데이터를 읽습니다. 이 호출이 성공하면 새로 읽은 용지 속성의 값이 COPaper의 현재 값으로 채택됩니다.

이 로드 작업 중에 임시 PAPER_PROPERTIES 구조인 NewProps를 사용하여 새 속성을 읽어들였습니다. 모두 로드에 성공하면 NewProps가 PAPER_PROPERTIES 구조체에 복사되고 m_PaperProperties. 이전과 마찬가지로 로드가 완료되고 IStream 이 더 이상 필요하지 않으면 IStream 포인터가 해제됩니다.

Load 끝에 오류가 있는 경우 손상된 데이터가 포함될 수 있으므로 잉크 데이터 배열이 지워집니다.

Load 끝에 오류가 없으면 클라이언트 IPaperSink::Loaded 메서드가 COPaper 내부 NotifySinks 메서드에서 호출되어 로드 작업이 완료되었음을 클라이언트에 알립니다. 이 새 로드된 잉크 데이터를 표시해야 하므로 클라이언트에 대한 중요한 알림입니다. 이 알림은 COPaper에서 연결 가능한 개체 기능을 크게 사용합니다.