Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
L’exemple de code C++ suivant montre comment ouvrir le flux existant dans le stockage, lire les nouvelles propriétés de papier, puis les définir comme valeurs actuelles pour COPaper.
Voici la méthode 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;
}
À présent, la méthode IStorage ::OpenStream est appelée pour ouvrir le flux existant dans le stockage appelé « PAPERDATA ». Les indicateurs de mode d’accès sont destinés à l’accès exclusif en lecture seule, direct et non partagé. Lorsque le flux est ouvert, la méthode IStream ::Read est appelée pour lire la structure PAPER_PROPERTIES. Si la quantité réellement lue n’est pas égale à la quantité demandée, l’opération de chargement est abandonnée et E_FAIL est retournée. Si la version de format du PAPER_PROPERTIES nouvellement lu n’est pas reconnue, l’opération de chargement est abandonnée et Load retourne E_FAIL.
Avec une version valide du format de données manuscrites, la taille du nouveau tableau de données manuscrites de l’PAPER_PROPERTIES lue est utilisée pour allouer un nouveau tableau de données manuscrits de la taille requise. Les données manuscrites existantes sont supprimées et ses données sont perdues. Si ces données étaient précieuses, elles doivent avoir été enregistrées avant l’appel de chargement. Une fois le nouveau tableau alloué, IStream ::Read est appelé à nouveau pour lire les données dans le tableau à partir du flux. Si cet appel réussit, les valeurs des propriétés de papier nouvellement lues sont adoptées en tant que valeurs actuelles pour COPaper.
Pendant cette opération de charge, une structure de PAPER_PROPERTIES temporaire, NewProps, a été utilisée pour contenir les nouvelles propriétés lues. Si tout réussit avec la charge, NewProps est copié dans la structure PAPER_PROPERTIES, m_PaperProperties. Comme précédemment, une fois le chargement terminé et leIStreamn’est plus nécessaire, le pointeur IStream est libéré.
En cas d’erreur à la fin de chargement, le tableau de données manuscrites est effacé, car il peut contenir des données endommagées.
S’il n’y a aucune erreur à la fin de Load, le client méthode IPaperSink ::Loaded est appelée, dans la méthode NotifySinks interne coPaper, pour informer le client que l’opération de chargement est terminée. Il s’agit d’une notification importante pour le client, car elle doit afficher ces nouvelles données manuscrites chargées. Cette notification utilise considérablement les fonctionnalités d’objet connectables dans COPaper.