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中的格式版本,則會中止載入 作業並傳 回E_FAIL。
使用有效的筆跡資料格式版本,從讀取所在的PAPER_PROPERTIES,新筆跡資料陣列的大小會用來配置所需大小的新筆跡資料陣列。 刪除現有的筆跡資料,並遺失其資料。 如果此資料有價值,則應該已在呼叫 Load 之前儲存。 配置新的陣列之後,會再次呼叫 IStream::Read ,以從資料流程將資料讀取到陣列。 如果此呼叫成功,則會採用新讀取紙張屬性中的值作為 COPaper 的目前值。
在此載入作業期間,會使用暫存PAPER_PROPERTIES結構 NewProps 來保存讀取的新屬性。 如果載入成功,則 NewProps 會複製到 PAPER_PROPERTIES 結構中,m_PaperProperties。 如同之前,在 Load 完成且不再需要 IStream 之後, 就會釋放 IStream 指標。
如果在 Load結束時發生錯誤,則會清除筆跡資料陣列,因為它可能包含損毀的資料。
如果在 Load結束時沒有錯誤,則會在 COPaper 內部 NotifySinks 方法中呼叫用戶端 IPaperSink::Loaded 方法,以通知用戶端載入作業已完成。 這是用戶端的重要通知,因為它必須顯示這個新載入的筆跡資料。 此通知會大幅使用 COPaper 中的可連線物件功能。