IPaper::Load
Der folgende C++-Beispielcode zeigt, wie Sie den vorhandenen Stream im Speicher öffnen, neue Papiereigenschaften in lesen und diese dann als aktuelle Werte für COPaper festlegen.
Es folgt die IPaper::Load-Methode von 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;
}
Nun wird die IStorage::OpenStream-Methode aufgerufen, um den vorhandenen Stream im Speicher mit dem Namen "PAPERDATA" zu öffnen. Zugriffsmodusflags dienen für schreibgeschützten, direkten und nicht freigegebenen exklusiven Zugriff. Wenn der Stream geöffnet ist, wird die IStream::Read-Methode aufgerufen, um die PAPER_PROPERTIES-Struktur zu lesen. Wenn der tatsächlich gelesene Betrag nicht dem angeforderten Betrag entspricht, wird der Ladevorgang abgebrochen und E_FAIL zurückgegeben. Wenn die Formatversion im neu gelesenen PAPER_PROPERTIES nicht erkannt wird, wird der Ladevorgang abgebrochen, und Load gibt E_FAIL zurück.
Bei einer gültigen Freihanddatenformatversion wird die Größe des neuen Freihanddatenarrays aus dem eingelesenen PAPER_PROPERTIES verwendet, um ein neues Freihanddatenarray der erforderlichen Größe zuzuordnen. Die vorhandenen Freihanddaten werden gelöscht, und ihre Daten gehen verloren. Wenn diese Daten wertvoll waren, hätte sie vor dem Aufruf von Load gespeichert werden müssen. Nachdem das neue Array zugewiesen wurde, wird IStream::Read erneut aufgerufen, um die Daten aus dem Stream in das Array zu lesen. Wenn dieser Aufruf erfolgreich ist, werden die Werte in den neu gelesenen Papiereigenschaften als aktuelle Werte für COPaper übernommen.
Während dieses Ladevorgangs wurde eine temporäre PAPER_PROPERTIES-Struktur, NewProps, verwendet, um die neuen Eigenschaften einzulesen. Wenn alles mit dem Laden erfolgreich ist, wird NewProps in die PAPER_PROPERTIES-Struktur kopiert, m_PaperProperties. Wie zuvor wird der IStream-Zeiger freigegeben, nachdem das Laden abgeschlossen ist und der IStream nicht mehr erforderlich ist.
Wenn am Ende des Ladens ein Fehler auftritt, wird das Freihanddatenarray gelöscht, da es möglicherweise beschädigte Daten enthält.
Wenn am Ende von Load kein Fehler auftritt, wird die Client-IPaperSink::Loaded-Methode in der internen COPaper NotifySinks-Methode aufgerufen, um den Client darüber zu informieren, dass der Ladevorgang abgeschlossen ist. Dies ist eine wichtige Benachrichtigung für den Client, da diese neu geladenen Freihanddaten angezeigt werden müssen. Diese Benachrichtigung nutzt in COPaper erheblich die Features des zu verbindenden Objekts.