Most new messages require additional parameters to specify their exact function. MCI messages use lParam2 as a pointer to a data structure, and use lParam1 as a bitfield for the flags associated with the message. A flag will exist for each field in the data structure that accepts data from the calling application. The application uses the flag to set the bitfield of lParam1 to indicate a value is assigned to a particular field. Flags also specify options without parameters. Thus these flags do not correspond to a field in the data structure.
The fields of the data structure for an MCI message are always the size of DWORDs. The number of fields in the structure depends on the particular message. The first field must be reserved for a handle to a window function used with the MCI_NOTIFY flag. The next fields in the data structure depend on the type of data returned for the message:
If no data is returned, no return fields are reserved in the data structure. Any data fields for passing information to the device driver immediately follow the dwCallback field. For example, the following structure does not have a return field:
typedef struct {
DWORDdwCallback;
DWORDlpfilename;
If integer data is returned, the second field of the data structure is reserved for the return data. Any data fields for passing information to the device driver start in the third field. For example, the following structure uses dwReturn as the integer return field:
typedef struct {
DWORDdwCallback;
DWORDdwReturn;
DWORDdwItem;
If string data is returned, the second and third fields of the data structure are reserved for the return data. The second DWORD is assigned to a field reserved for a pointer to the null-terminated return string. The third DWORD is assigned to a field reserved for the size of return buffer. The application is responsible for creating the buffer for return string. Any data fields for passing information to the device driver start in the fourth field. For example, the following structure uses lpstrReturn and dwRetSize for the return fields:
typedef struct {
DWORDdwCallback;
LPSTRlpstrReturn;
DWORDdwRetSize;
If RECT data is returned, the second and third fields of the data structure are reserved for the return data. The first DWORD position is reserved for the top-left values of the RECT data. The second DWORD position is reserved for the bottom-right values of the RECT data. Any data fields for passing information to the device driver start in the fourth DWORD position. Rather than specifying two DWORDS for the RECT data, most data structure definitions use one RECT data field to obtain an equivalent data structure. For example, the following structure uses rc for the return field:
typedef struct {
DWORDdwCallback;
RECTrc;
In addition to indicating the fields used in a data structure, flags can indicate an option that does not use any parameters. For example, the wait flag does not use any parameters.
When you add new flags, you must ensure they do not conflict with the flags already used. Bits 0 through 15 of the 32-bit DWORD are reserved for MCI. Bit 16 (0x00010000) is the first bit that a driver can use for its flags. If your command is a new command, you can start with this bit position. If your command extends a command, you must choose bit positions that do not conflict with the flags already defined for that command. Any unused bits in the new flag must be set to zero. For example, if a new command for videodisc players uses flags 16 through 20, a custom extension to the new command could use flags 21 through 31.
To continue the example for adding a RESET command to a videodisc driver, the following code fragment defines a data structure, a corresponding pointer for it, and the flag corresponding to the program field of the data structure:
typedef struct {
DWORDdwCallback;
DWORDdwProgram;
} MCI_VDISC_RESET_PARMS;
typedefMCI_VDISC_RESET_PARMS FAR * LPMCI_VDISC_RESET_PARMS;
#defineMCI_VDISC_RESET_PROGRAM0x00010000L
When the application sets the MCI_VDISC_RESET_PROGRAM flag in lParam1, it indicates that a value is assigned in the dwProgram field.
Now that you have created the message command, flags and data structure, you need to create the command table that tells MCI how to translate the equivalent string command into the message command form. Creating the command table is explained in the following section.