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에서 연결 가능한 개체 기능을 크게 사용합니다.