| C & C++ Programming | MFC Programming | Download | Site Index |


 

 

 

Supplementary Notes For MFC Programming Module 26:

IStorage-Compound File Implementation

 

 

 

 

What we have in this Module?

  1. IStorage-Compound File Implementation

  2. When to Use

  3. Methods

  4. Remarks

  5. Istream

  6. When To Implement

  7. When To Use

  8. Methods in Vtable Order

  9. IStream - Compound File Implementation

  10. When to Use

  11. Methods

  12. IPersistStorage

  13. When to Implement

  14. When to Use

  15. Methods in Vtable Order

  16. IPersistStream

  17. When to Implement

  18. When to Use

  19. Methods in Vtable Order

  20. ILockBytes

  21. When To Implement

  22. When To Use

  23. Methods in Vtable Order

  24. STATSTG

  25. STATFLAG

 

IStorage-Compound File Implementation

 

The compound file implementation of IStorage allows you to create and manage substorages and streams within a storage object residing in a compound file object. To create a compound file object and get an IStorage pointer, call the API function StgCreateStorageEx(). To open an existing compound file object and get its root IStorage pointer, call StgOpenStorageEx().

 

When to Use

 

Most applications use this implementation to create and manage storages and streams.

 

Methods

 

IStorage::CreateStream - Creates and opens a stream object with the specified name contained in this storage object. The name must not exceed 31 characters in length (not including the string terminator). The 000 through 01f characters, serving as the first character of the stream/storage name, are reserved for use by OLE. This is a compound file restriction, not a structured storage restriction. The COM-provided compound file implementation of the IStorage::CreateStream method does not support the following behaviors:

  1. The STGM_DELETEONRELEASE flag is not supported.

  2. Transacted mode (STGM_TRANSACTED) is not supported for stream objects.

  3. Opening the same stream more than once from the same storage is not supported. The STGM_SHARE_EXCLUSIVE sharing-mode flag must be specified in the grfMode parameter.

IStorage::OpenStream - Opens an existing stream object within this storage object using the access modes specified in the grfMode parameter. The 000 through 01f characters, serving as the first character of the stream/storage name, are reserved for use by OLE. This is a compound file restriction, not a structured storage restriction. The COM-provided compound file implementation of the IStorage::OpenStream method does not support the following behavior:

  1. The STGM_DELETEONRELEASE flag.

  2. Transacted mode (STGM_TRANSACTED) for stream objects.

  3. Opening the same stream more than once from the same storage. The STGM_SHARE_EXCLUSIVE flag must be specified.

IStorage::CreateStorage - Creates and opens a new storage object with the specified name in the specified access mode. The name must not exceed 31 characters in length (not including the string terminator). The 000 through 01f characters, serving as the first character of the stream/storage name, are reserved for use by OLE. This is a compound file restriction, not a structured storage restriction. The COM-provided compound file implementation of the IStorage::CreateStorage method does not support the following behavior:

  1. The STGM_PRIORITY flag for non-root storages.

  2. Opening the same storage object more than once from the same parent storage. The STGM_SHARE_EXCLUSIVE flag must be specified.

  3. The STGM_DELETEONRELEASE flag. If this flag is specified, the function returns STG_E_INVALIDFLAG.

IStorage::OpenStorage - Opens an existing storage object with the specified name in the specified access mode. The 000 through 01f characters, serving as the first character of the stream/storage name, are reserved for use by OLE. This is a compound file restriction, not a structured storage restriction. The COM-provided compound file implementation of the IStorage::OpenStorage method does not support the following behavior:

  1. The STGM_PRIORITY flag for non-root storages.

  2. Opening the same storage object more than once from the same parent storage. The STGM_SHARE_EXCLUSIVE flag must be specified.

  3. The STGM_DELETEONRELEASE flag. If this flag is specified, the function returns STG_E_INVALIDFUNCTION.

IStorage::CopyTo - Copies only the substorages and streams of this open storage object into another storage object. The rgiidExclude parameter can be set to IID_IStream to copy only substorages, or to IID_IStorage to copy only streams.

IStorage::MoveElementTo - Copies or moves a substorage or stream from this storage object to another storage object.

IStorage::Commit - Ensures that any changes made to a storage object open in transacted mode are reflected in the parent storage; for a root storage, reflects the changes in the actual device; for example, a file on disk. For a root storage object opened in direct mode, this method has no effect except to flush all memory buffers to the disk. For non-root storage objects in direct mode, this method has no effect.

The COM-provided compound files implementation uses a two-phase commit process unless STGC_OVERWRITE is specified in the grfCommitFlags parameter. This two-phase process ensures the robustness of data, in case the commit operation fails. First, all new data is written to unused space in the underlying file. If necessary, new space is allocated to the file. After this step has been completed, a table in the file is updated using a single-sector write operation to indicate that the new data is to be used in place of the old. The old data becomes free space to be used at the next commit operation. Thus, the old data is available and can be restored if an error occurs when committing changes. If STGC_OVERWRITE is specified, a single phase commit operation is used.

IStorage::Revert - Discards all changes that have been made to the storage object since the last commit operation.

IStorage::EnumElements - Creates and retrieves a pointer to an enumerator object that can be used to enumerate the storage and stream objects contained within this storage object. The COM-provided compound file implementation takes a snapshot of that information. Therefore, changes to the streams and storages are not reflected in the enumerator until a new enumerator is obtained.

IStorage::DestroyElement - Removes the specified element (substorage or stream) from this storage object.

IStorage::RenameElement - Renames the specified substorage or stream in this storage object. The 000 through 01f characters, serving as the first character of the stream/storage name, are reserved for use by OLE. This is a compound file restriction, not a structured storage restriction.

IStorage::SetElementTimes - Sets the modification, access, and creation times of the specified storage element. The COM-provided compound-file implementation maintains modification and change times for internal storage objects. Root storage objects support whatever is supported by the underlying file system (or by ILockBytes). The compound file implementation does not maintain any time stamps for internal streams. Unsupported time stamps are reported as zero, which allows the caller to test for support.

IStorage::SetClass - Assigns the specified CLSID to this storage object.

IStorage::SetStateBits - Stores up to 32 bits of state information in this storage object. The state set by this method is for external use only. The COM-provided compound file implementation does not perform any action based on the state.

IStorage::Stat - Retrieves the STATSTG structure for this open storage object.

 

Remarks

 

If the storage object is opened in simple mode, use of the above methods is restricted. A storage is in simple mode if it is opened with the STGM_SIMPLE element specified in the grfMode parameter of the StgCreateStorageEx() or StgOpenStorageEx() function. If the simple-mode storage object was obtained from the StgCreateStorageEx() function, then the CreateStream() method can be called but the OpenStream() method cannot. If the simple mode storage object was obtained from the StgOpenStorageEx() function, then the OpenStream() method can be called but the CreateStream() method cannot.

When a simple-mode storage object is used to create a stream, the minimum size of that stream typically is 4096 bytes. If less data is written to the stream, the size is rounded up to 4096 bytes.

 

Istream

 

The IStream interface lets you read and write data to stream objects. Stream objects contain the data in a structured storage object, where storages provide the structure. Simple data can be written directly to a stream but, most frequently, streams are elements nested within a storage object. They are similar to standard files. The IStream interface defines methods similar to the MS-DOS FAT file functions. For example, each stream object has its own access rights and a seek pointer. The main difference between a DOS file and a stream object is that in the latter case, streams are opened using an IStream interface pointer rather than a file handle. The methods in this interface present your object's data as a contiguous sequence of bytes that you can read or write. There are also methods for committing and reverting changes on streams that are open in transacted mode and methods for restricting access to a range of bytes in the stream. Streams can remain open for long periods of time without consuming file-system resources. The IUnknown::Release method is similar to a close function on a file. Once released, the stream object is no longer valid and cannot be used. Clients of asynchronous monikers can choose between a data-pull or data-push model for driving an asynchronous IMoniker::BindToStorage operation and for receiving asynchronous notifications. See URL Monikers for more information. The following table compares the behavior of asynchronous ISequentialStream::Read and IStream::Seek calls returned in IBindStatusCallback::OnDataAvailable in these two download models:

 

IStream method call

Behavior in data-pull model

Behavior in data-push model

Read() is called to read partial data (that is, not all the available data)

Returns S_OK. The client must continue to read all available data before returning from IBindStatusCallback::OnDataAvailable or else the bind operation is blocked. (that is, read until S_FALSE or E_PENDING is returned)

Returns S_OK. Even if the client returns from IBindStatusCallback::OnDataAvailable at this point the bind operation continues and IBindStatusCallback::OnDataAvailable will be called again repeatedly until the binding finishes.

Read() is called to read all the available data

Returns E_PENDING if the bind operation has not completed, and IBindStatusCallback::OnDataAvailable will be called again when more data is available.

Same as data-pull model.

Read() is called to read all the available data and the bind operation is over (end of file)

Returns S_FALSE. There will be a subsequent call to IBindStatusCallback::OnDataAvailable with the grfBSC flag set to BSCF_LASTDATANOTIFICATION.

Same as data-pull model.

Seek() is called

Seek() does not work in data-pull model

Seek() does not work in data-push model.

 

 Table 1.

 

When To Implement

 

Implement IStream on a container or object application when you require functionality not provided by the COM compound file implementation. The specification of IStream defines more functionality that the COM implementation supports. In addition, if you are creating a stream object that is larger than the heap in your machine's memory and you are using a global memory handle, the compound file implementation calls GlobalReAlloc() internally whenever it needs more memory, which can be very inefficient. In this case, the preferred solution is to implement an IStream that uses memory allocated by VirtualAlloc instead of GlobalAlloc(). This can reserve a large chunk of virtual address space and then commit memory within that address space as required. No data copying occurs and memory is committed only as it is needed. The IStream interface inherits Read() and Write() methods from ISequentialStream. Note:  Most containers do not implement ISequentialStream as a separate interface, and you are not required to provide it separately even if you provide an IStream implementation. For example, the compound file implementation of structured storage does not succeed on a QueryInterface() method for ISequentialStream but it includes the Read() and Write() methods through the IStream interface pointer.

 

When To Use

 

Call the methods of the IStream interface from a container or application to read and write the data for an object. Since stream objects can be marshaled to other processes, applications can share the data in storage objects without having to use global memory.

 

Methods in Vtable Order

 

The IStream interface inherits the methods of the standard COM interface IUnknown. In addition, IStream defines the following methods.

 

Method

Description

Read()

Reads a specified number of bytes from the stream object into memory starting at the current seek pointer.

Write()

Writes a specified number of bytes into the stream object starting at the current seek pointer.

Seek()

Changes the seek pointer to a new location relative to the beginning of the stream, the end of the stream, or the current seek pointer.

SetSize()

Changes the size of the stream object.

CopyTo()

Copies a specified number of bytes from the current seek pointer in the stream to the current seek pointer in another stream.

Commit()

Ensures that any changes made to a stream object open in transacted mode are reflected in the parent storage object.

Revert()

Discards all changes that have been made to a transacted stream since the last call to IStream::Commit.

LockRegion()

Restricts access to a specified range of bytes in the stream. Supporting this functionality is optional since some file systems do not provide it.

UnlockRegion()

Removes the access restriction on a range of bytes previously restricted with IStream::LockRegion.

Stat()

Retrieves the STATSTG structure for this stream.

Clone()

Creates a new stream object that references the same bytes as the original stream but provides a separate seek pointer to those bytes.

 

 Table 2.

 

IStream - Compound File Implementation

 

The IStream interface supports reading and writing data to stream objects. In a structured storage object, stream objects contain the data and storages provide the structure. Simple data can be written directly to a stream, but more frequently, streams are elements nested within a storage object. They are similar to standard files. The specification of IStream defines more functionality that the COM implementation supports. For example, the IStream interface defines streams up to 264 bytes in length requiring a 64-bit seek pointer. However, the COM implementation only supports streams up to 232 bytes in length (4 GB) and read and write operations are always limited to 232 bytes at a time. The COM implementation also does not support stream transactioning or region locking. To create a simple stream based on global memory, get an IStream pointer by calling the API function CreateStreamOnHGlobal(). To get an IStream pointer within a compound file object, call either StgCreateDocfile() or StgOpenStorage(). These functions retrieve an IStorage pointer, with which you can then call CreateStream() or OpenStream() for an IStream pointer. In either case, the same IStream implementation code is used.  The compound file implementation of structured storage does not succeed on a QueryInterface() method for ISequentialStream, but it includes the Read() and Write() methods through the IStream interface pointer.

 

When to Use

 

Call the methods of IStream to read and write data to a stream. Because stream objects can be marshaled to other processes, applications can share the data in storage objects without having to use global memory. In the COM compound file implementation of stream objects, the custom marshaling facilities in COM create a remote version of the original object in the new process when the two processes have shared-memory access. Thus, the remote version does not need to communicate with the original process to carry out its functions. The remote version of the stream object shares the same seek pointer as the original stream. If you do not want to share the seek pointer, use the IStream::Clone method to provide a copy of the stream object for the remote process. If creating a stream object that is larger than the heap in your computer's memory and you are using an HGLOBAL handle to a global memory object, the stream object calls the GlobalRealloc() method internally when it requires more memory. Because GlobalRealloc() always copies data from the source to the destination, increasing a stream object from 20 MB to 25 MB, for example, requires large amounts of time. This is due to the size of the increments copied and is worsened if there is less than 45 MB of memory on the computer because of disk swapping. The preferred solution is to implement an IStream method that uses memory allocated by VirtualAlloc() instead of GlobalAlloc(). This can reserve a large chunk of virtual address space and then commit memory within that address space as required. No data copying occurs and memory is committed only as it is required. An alternative to GlobalRealloc() is to call the IStream::SetSize method on the stream object to increase the memory allocation in advance. This is not, however, as efficient as using VirtualAlloc(), as described above.

 

Methods

  1. ISequentialStream::Read - Reads a specified number of bytes from the stream object into memory starting at the current seek pointer. This implementation returns S_OK if the end of the stream was reached during the read. (This is the same as the "end of file" behavior found in the MS-DOS FAT file system.)

  2. ISequentialStream::Write - Writes a specified number from bytes into the stream object starting at the current seek pointer. In this implementation, stream objects are not sparse. Any fill bytes are eventually allocated on the disk and assigned to the stream.

  3. IStream::Seek - Changes the seek pointer to a new location relative to the beginning of the stream, to the end of the stream, or to the current seek pointer.

  4. IStream::SetSize - Changes the size of the stream object. In this implementation, there is no guarantee that the space allocated will be contiguous.

  5. IStream::CopyTo - Copies a specified number of bytes from the current seek pointer in the stream to the current seek pointer in another stream.

  6. IStream::Commit - The compound file implementation of IStream supports opening streams only in direct mode, not transacted mode. Therefore, the method has no effect when called other than to flush all memory buffers to the next storage level. In this implementation, it does not matter if you commit changes to streams, you need only commit changes for storage objects.

  7. IStream::Revert - This implementation does not support transacted streams, so a call to this method has no effect.

  8. IStream::LockRegion - Range-locking is not supported by this implementation, so a call to this method has no effect.

  9. IStream::UnlockRegion - Removes the access restriction on a range of bytes previously restricted with IStream::LockRegion.

  10. IStream::Stat - Retrieves the STATSTG structure for this stream.

  11. IStream::Clone - Creates a new stream object with its own seek pointer that references the same bytes as the original stream. A simple-mode IStream is subject to the following constraints.

 

 

 

 

 

 

 

 

 

 

 

 

 

IPersistStorage

 

The IPersistStorage interface defines methods that enable a container application to pass a storage object to one of its contained objects and to load and save the storage object. This interface supports the structured storage model, in which each contained object has its own storage that is nested within the container's storage. The IPersistStorage contract inherits its definition from IPersist, so all implementations must also include the GetClassID() method of IPersist.

 

When to Implement

 

Any object that can be embedded in a container must implement the IPersistStorage interface. This interface is one of the primary interfaces for a compound document object. Embeddable objects must also implement the IOleObject and IDataObject interfaces. The OLE default handler for embedded objects provides an implementation of the IPersistStorage interface that is used when the object is in the loaded state. Similarly, the OLE default link handler provides an IPersistStorage implementation that manages storage for a linked object. These default handlers both interact with the OLE default cache implementation, which has its own IPersistStorage implementation. If you are providing a custom embedding or link handler for your objects, the handler must include an implementation of IPersistStorage. You can delegate calls to the default handler so you can take advantage of the default cache implementation.

 

When to Use

 

When an OLE container creates a new object, loads an existing object from storage, or inserts a new object in a clipboard or a drag-and-drop operation, the container uses the IPersistStorage interface to initialize the object and put it in the loaded or running state. When an object is loaded or running, an OLE container calls other IPersistStorage methods to instruct the object to perform various save operations or to release its storage. Typically, applications use helper functions such as OleLoad() or OleCreate(), rather than calling the IPersistStorage::Load or IPersistStorage::InitNew methods directly. Similarly, applications typically call the OleSave() helper function rather than calling IPersistStorage::Save directly.

 

Methods in Vtable Order

 

IUnknown Methods

Description

QueryInterface()

Returns pointers to supported interfaces.

AddRef()

Increments reference count.

Release()

Decrements reference count.

 

 Table 3.

 

IPersist Method

Description

GetClassID()

Returns the class identifier (CLSID) for the object on which it is implemented.

 

 Table 4.

 

IPersistStorage Methods

Description

IsDirty()

Indicates whether the object has changed since it was last saved to its current storage.

InitNew()

Initializes a new storage object.

Load()

Initializes an object from its existing storage.

Save()

Saves an object, and any nested objects that it contains, into the specified storage object. The object enters NoScribble mode.

SaveCompleted()

Notifies the object that it can revert from NoScribble or HandsOff mode, in which in must not write to its storage object, to Normal mode in which it can.

HandsOffStorage()

Instructs the object to release all storage objects that have been passed to it by its container and to enter HandsOffAfterSave or HandsOffFromNormal mode.

 

 Table5.

 

 IPersistStream

 

The IPersistStream interface provides methods for saving and loading objects that use a simple serial stream for their storage needs. The IPersistStream interface inherits its definition from the IPersist interface, and so includes the GetClassID() method of IPersist. One way in which it is used is to support OLE moniker implementations. Each of the OLE-provided moniker interfaces provides an IPersistStream implementation through which the moniker saves or loads itself. An instance of the OLE generic composite moniker class calls the IPersistStream methods of its component monikers to load or save the components in the proper sequence in a single stream. OLE containers with embedded and linked component objects do not use this interface; they use the IPersistStorage interface instead.

 

When to Implement

 

Implement the IPersistStream interface on objects that are to be saved to a simple stream. Some objects of this type are monikers and some OLE controls, although generally, controls use the IPersistStreamInit interface, which has the same methods as IPersistStream, with one added method, IPersistStreamInit::InitNew. The IMoniker interface is derived from the IPersistStream interface, so you must implement the IPersistStream interface if you are implementing a new moniker class.

 

When to Use

 

Call methods of IPersistStream from a container application to save or load objects that are contained in a simple stream. When used to save or load monikers, typical applications do not call the methods directly, but allow the default link handler to make the calls to save and load the monikers that identify the link source. These monikers are stored in a stream in the storage for the linked object. If you are writing a custom link handler for your class of objects, you would call the methods of IPersistStream to implement the link handler.

 

Methods in Vtable Order

 

IUnknown Methods

Description

QueryInterface()

Returns pointers to supported interfaces.

AddRef()

Increments the reference count.

Release()

Decrements the reference count.

 

 Table 6.

 

IPersist Method

Description

GetClassID()

Returns the class identifier (CLSID) for the component object.

 

 table 7.

 

 

IPersistStream Methods

Description

IsDirty()

Checks the object for changes since it was last saved.

Load()

Initializes an object from the stream where it was previously saved.

Save()

Saves an object into the specified stream and indicates whether the object should reset its dirty flag.

GetSizeMax()

Return the size in bytes of the stream needed to save the object.

 

 Table 8.

 

ILockBytes

 

The ILockBytes interface is implemented on a byte array object that is backed by some physical storage, such as a disk file, global memory, or a database. It is used by a COM compound file storage object to give its root storage access to the physical device, while isolating the root storage from the details of accessing the physical storage.

 

When To Implement

 

Most applications will not implement the ILockBytes interface because COM provides implementations for the two most common situations:

  1. File-based implementation - If you call StgCreateDocfile() function to create a compound file storage object, it contains an implementation of ILockBytes that is associated with a byte array stored in a physical disk file. The compound file storage object calls the ILockBytes methods, you do not call them directly in this implementation.

  2. Memory-based implementation - COM also provides a byte array object based on global memory that supports an implementation of ILockBytes. You can get a pointer through a call to the CreateILockBytesOnHGlobal() function). Then, to create a compound file storage object on top of that byte array object, call the StgCreateDocfileOnILockBytes() function. The compound file storage object calls the ILockBytes methods, you do not call them directly in this implementation.

There are situations in which it would be useful for an application to provide its own ILockBytes implementation. For example, a database application could implement ILockBytes to create a byte array object backed by the storage of its relational tables. However, it is strongly recommended that you use the COM-provided implementations. For a discussion of the advantages of using the COM implementations rather than creating your own, see the StgCreateDocfileOnILockBytes() API function, which creates a compound file storage object on top of a caller-provided byte array object. If you choose to implement your own ILockBytes interface, you should consider providing custom marshaling by implementing the IMarshal interface as part of your byte array object. The reason for this is that when the COM-provided implementations of IStorage and IStream are marshaled to another process, their ILockBytes interface pointers are also marshaled to the other process. The default marshaling mechanism creates a proxy byte array object (on which is the ILockBytes interface) that transmits method calls back to the original byte array object. Custom marshaling can improve efficiency by creating a remote byte array object that can access the byte array directly.

 

When To Use

 

The ILockBytes methods are called by the COM implementations of IStorage and IStream on the compound file object. Unless you are implementing IStorage and IStream, you would not need to call ILockBytes methods directly. If you write your own ILockBytes implementation, you can use the StgCreateDocfileOnILockBytes() function to create a compound file storage object backed by your implementation of ILockBytes.

 

Methods in Vtable Order

 

The ILockBytes interface inherits the methods of the standard COM interface IUnknown. In addition, ILockBytes defines the following methods.

 

Method

Description

ReadAt()

Reads a specified number of bytes starting at a specified offset from the beginning of the byte array.

WriteAt()

Writes a specified number of bytes to a specified location in the byte array.

Flush()

Ensures that any internal buffers maintained by the byte array object are written out to the backing storage.

SetSize()

Changes the size of the byte array.

LockRegion()

Restricts access to a specified range of bytes in the byte array.

UnlockRegion()

Removes the access restriction on a range of bytes previously restricted with ILockBytes::LockRegion.

Stat()

Retrieves a STATSTG structure for this byte array object.

 

 Table 9.

 

STATSTG structure

 

Item

Description

Structure

STATSTG.

Info

Contains statistical information about an open storage, stream, or byte-array object. This structure is used in the IEnumSTATSTG, ILockBytes, IStorage, and IStream interfaces.

Definition

typedef struct tagSTATSTG {

  LPWSTR pwcsName;

  DWORD type;

  ULARGE_INTEGER cbSize;

  FILETIME mtime;

  FILETIME ctime;

  FILETIME atime;

  DWORD grfMode;

  DWORD grfLocksSupported;

  CLSID clsid;

  DWORD grfStateBits;

  DWORD reserved;

} STATSTG;

Members

pwcsName - Pointer to a NULL-terminated Unicode string containing the name. Space for this string is allocated by the method called and freed by the caller (see CoTaskMemFree()). You can specify not to return this member by specifying the STATFLAG_NONAME value when you call a method that returns a STATSTG structure, except for calls to IEnumSTATSTG::Next, which provides no way to specify this value.

type - Indicates the type of storage object. This is one of the values from the STGTY enumeration.

cbSize - Specifies the size in bytes of the stream or byte array.

mtime - Indicates the last modification time for this storage, stream, or byte array.

ctime - Indicates the creation time for this storage, stream, or byte array.

atime - Indicates the last access time for this storage, stream or byte array.

grfMode - Indicates the access mode specified when the object was opened. This member is only valid in calls to Stat() methods.

grfLocksSupported - Indicates the types of region locking supported by the stream or byte array. See the LOCKTYPE enumeration for the values available. This member is not used for storage objects.

clsid - Indicates the class identifier for the storage object; set to CLSID_NULL for new storage objects. This member is not used for streams or byte arrays.

grfStateBits - Indicates the current state bits of the storage object; that is, the value most recently set by the IStorage::SetStateBits method. This member is not valid for streams or byte arrays.

reserved - Reserved for future use.

Header file

objidl.h

Remark

 -

 

Table 10.

 

STATFLAG enum

 

Item

Description

Enumeration type

STATFLAG.

Info

The enumeration values indicate whether the method should try to return a name in the pwcsName member of the STATSTG structure. The values are used in the ILockBytes::Stat, IStorage::Stat, and IStream::Stat methods to save memory when the pwcsName member is not needed.

Definition

typedef enum tagSTATFLAG

{

  STATFLAG_DEFAULT= 0,

  STATFLAG_NONAME= 1

} STATFLAG;

Constants

STATFLAG_DEFAULT - Requests that the statistics include the pwcsName member of the STATSTG structure.

STATFLAG_NONAME - Requests that the statistics not include the pwcsName member of the STATSTG structure. If the name is omitted, there is no need for the Stat() methods to allocate and free memory for the string value of the name, therefore the method reduces time and resources used in an allocation and free operation.

Header file

objidl.h

Remark

Defined in the IOLETypes pseudo-interface (oletyp.idl).

 

Table 11.

 

 

 

 

 

 


| C & C++ Programming | MFC Programming | Download | Site Index |