Laying Out Command Structures

The first member of a command structure must be a DWORD for storing a window handle. The window handle is provided by the application and is used by winmm.dll for delivering command notification messages associated with the MCI_NOTIFY flag. Since all commands must support MCI_NOTIFY, all structures must contain this member. By convention, this member is called dwCallback.

Following the dwCallback member, each additional structure member must be matched to an entry in the command’s description within the command table. The order and data type of each member must match those in the command description.

If a return value is associated with the command, then the second structure member is used for storing the return value. For all return types except MCI_STRING and MCI_RECT, the return member must be DWORD-sized. If the command returns a string, then the structure must provide storage for a string buffer address and a string buffer length, both of which are supplied by the application. For commands whose return type is MCI_RECT, the structure must provide a RECT-sized return member.

The “info” command’s return value is a string, and its structure follows:

typedef struct tagMCI_INFO_PARMS {
    DWORD   dwCallback;
    LPSTR   lpstrReturn;
    DWORD   dwRetSize;
} MCI_INFO_PARMS;
 

If a command does not provide a return value, then the command’s structure does not include return members. For example, the “play” command does not provide a return value. Following is its structure:

typedef struct tagMCI_PLAY_PARMS {
    DWORD   dwCallback;
    DWORD   dwFrom;
    DWORD   dwTo;
} MCI_PLAY_PARMS;
 

After the return value member, the rest of the structure members are used for storing input or output arguments. Following is the “play” command description, so you can see how it matches the MCI_PLAY_PARMS structure. Entries with the MCI_FLAG type do not require space in the data structure.

L"play\0",            MCI_PLAY, 0,                  MCI_COMMAND_HEAD,
L"notify\0",          MCI_NOTIFY,                   MCI_FLAG,
L"wait\0",            MCI_WAIT,                     MCI_FLAG,
L"from\0",            MCI_FROM,                     MCI_INTEGER,
L"to\0",              MCI_TO,                       MCI_INTEGER,
L"\0",                0L,                           MCI_END_COMMAND,
 

Here’s the “open” command’s description:

L"open\0",            MCI_OPEN, 0,                  MCI_COMMAND_HEAD,
L"\0",                MCI_INTEGER, 0,               MCI_RETURN,
L"notify\0",          MCI_NOTIFY,                   MCI_FLAG,
L"wait\0",            MCI_WAIT,                     MCI_FLAG,
L"type\0",            MCI_OPEN_TYPE,                MCI_STRING,
L"element\0",         MCI_OPEN_ELEMENT,             MCI_STRING,
L"alias\0",           MCI_OPEN_ALIAS,               MCI_STRING,
L"shareable\0",       MCI_OPEN_SHAREABLE,           MCI_FLAG,
L"\0",                0L,                           MCI_END_COMMAND,
 

And here is the MCI_OPEN_PARMS structure:

typedef struct tagMCI_OPEN_PARMS {
    DWORD       dwCallback;
    MCIDEVICEID wDeviceID;
    WORD        wReserved0;
    LPCSTR      lpstrDeviceType;
    LPCSTR      lpstrElementName;
    LPCSTR      lpstrAlias;
} MCI_OPEN_PARMS;
 

Note the difference between string return values, shown previously in MCI_INFO_PARMS, and string arguments, illustrated in MCI_OPEN_PARMS. For string return values, the structure must contain members to hold both a string buffer address and a string buffer size. For string arguments, only a string pointer is stored.