Compartir a través de


IPaper::Load

El siguiente código de ejemplo de C++ muestra cómo abrir la secuencia existente en el almacenamiento, leer nuevas propiedades de papel en y, a continuación, establecerlas como valores actuales para COPaper.

A continuación se muestra el método IPaper::Load de 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;
  }

Ahora, se llama al método IStorage::OpenStream para abrir la secuencia existente en el almacenamiento denominado "PAPERDATA". Las marcas de modo de acceso son para el acceso exclusivo de solo lectura, directo y no compartido. Cuando se abre la secuencia, se llama al método IStream::Read para leer la estructura de PAPER_PROPERTIES. Si la cantidad realmente leída no es igual a la cantidad solicitada, se anula la operación de carga y se devuelve E_FAIL. Si no se reconoce la versión de formato en el PAPER_PROPERTIES de lectura recién leído, la operación de carga se anula y Load devuelve E_FAIL.

Con una versión válida de formato de datos de entrada de lápiz, se usa el tamaño de la nueva matriz de datos de entrada de lápiz de la PAPER_PROPERTIES que se leyó en para asignar una nueva matriz de datos de entrada de lápiz del tamaño necesario. Se eliminan los datos de entrada de lápiz existentes y se pierden sus datos. Si estos datos eran valiosos, debería haberse guardado antes de que se llamara a Load. Una vez asignada la nueva matriz, se vuelve a llamar a IStream::Read para leer los datos en la matriz desde la secuencia. Si esta llamada se realiza correctamente, los valores de las propiedades de papel recién leídos se adoptan como los valores actuales de COPaper.

Durante esta operación de carga, se usó una estructura de PAPER_PROPERTIES temporal, NewProps, para contener las nuevas propiedades leídas. Si todo se realiza correctamente con la carga, NewProps se copia en la estructura PAPER_PROPERTIES, m_PaperProperties. Como antes, después de realizar la carga y elde IStreamya no es necesario, se libera el puntero IStream.

Si hay un error al final de Carga, se borra la matriz de datos de entrada de lápiz, ya que puede contener datos dañados.

Si no se produce ningún error al final de Load, se llama al método IPaperSink::Loaded del cliente, en el método Interno NotifySinks de COPaper, para notificar al cliente que se ha completado la operación de carga. Se trata de una notificación importante para el cliente, ya que debe mostrar estos nuevos datos de entrada de lápiz cargados. Esta notificación hace un uso significativo de las características de objetos conectables en COPaper.