IStream
is nothing more than just a stream of bytes. Though it's usually related to other interfaces in OLE such as
IStorage
, it will be fair enough to treat
IStream
as a standalone medium. Let's see. Suppose there is a function that takes an
IStream
pointer as a parameter:
void readInImage(IStream *)
. This generally means the expected byte-content of the data (in this case an image) may come from anywhere, only it should be interfaced through
IStream
. Now suppose your byte-content is in the following form:
extern char *imgBytes
.
So how to put that
char*
into
IStream
? Here we go:
extern char *imgBytes;
extern int cbImgBytes;
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, cbImgBytes);
ASSERT( hMem != NULL );
PVOID pMem = GlobalLock(hMem);
RtlMoveMemory(pMem, imgBytes, cbImgBytes);
IStream *pStream = 0;
HRESULT hr = CreateStreamOnHGlobal(hMem, TRUE, &pStream);
Now we can simply use that
pStream
like so:
readInImage(pStream);
pStream->Release();
For a reverse operation, i.e. writing into
IStream
, no need to use those
GlobalAlloc
/
GlobalLock
functions. Suppose we have the following function
writeOutImage(IStream *)
. In the following illustration,
writeOutImage
puts its byte-content into
IStream
:
IStream *pStream = 0;
HRESULT hr = CreateStreamOnHGlobal(0, TRUE, &pStream);
writeOutImage(pStream);
And finally, the following code shows how one can get back byte-content form
IStream
itself:
STATSTG statsg;
HRESULT hr = pStream->Stat(&statsg, STATFLAG_NONAME);
LARGE_INTEGER seekPos;
seekPos.QuadPart = 0;
hr = pStream->Seek(seekPos, STREAM_SEEK_SET, NULL);
char *bytes = new char[statsg.cbSize.QuadPart];
ULONG cbRead;
hr = pStream->Read(bytes, statsg.cbSize.QuadPart, &cbRead);
That is it. The bottom line is that
IStream
is just a way of holding a stream of bytes.