91网址你们懂得:使用mciSendCommand播放CD

来源:百度文库 编辑:偶看新闻 时间:2024/04/29 00:27:24
MCI(Media Control Interface,媒体控制接口)向Windows程序提供了在高层次上控制媒体设备接口的能力。程序不必关心具体设备,就可以对激光唱机(CD)、视盘机、波形音频设备、视频播放设备和MIDI设备等媒体设备进行控制。  mciSendCommand(MCIDEVICEID wIDDevice, //设备的ID,在打开设备时不用该参数    UINT uMsg, //命令消息     DWORD fdwCommand, //命令消息的标志  DWORD dwParam //指向包含命令消息参数的结构 )// //若成功则返回0,否则返回错误码 应用实例:(1)CD的播放1.打开设备时,MCI为不同的多媒体设备打开提供相应的数据结构类型。若不想使用设备中特定的参数数据,则可使用统一的MCI_OPEN_PARMS结构,原型:typedef struct {      DWORD          dwCallback;               // 低字节用于MCI_NOTIFY的窗口句柄      MCIDEVICEID  wDeviceID;           // 返回的设备标识符      LPCSTR       lpstrDeviceType;            // MCI设备的类型      LPCSTR       lpstrElementName;   // 设备元素      LPCSTR       lpstrAlias;                    // 可选的设备别名  } MCI_OPEN_PARMS;    打开多媒体设备的过程:定义一个MCI_OPEN_PARMS结构类型变量,给结构变量中的相应参数赋值,调用mciSendCommand向设备发送MCI_OPEN命令消息,成功调用时,可获得相应的设备标识符。        设置或获取设备信息

      使用MCI_SET和MCI_STATUS命令可以用来设置和获取设备信息,在用函数mciSendCommand发送命令时,使用相应的MCI_SET_PARMS和MCI_STATUS_PARMS结构。原型:

      typedef struct   {       

      DWORD           dwCallback; // 低字节用于MCI_NOTIFY的窗口句柄

      DWORD           dwTimeFormat;                           // 时间格式

      DWORD           dwAudio;                                     // 输出声道

      } MCI_SET_PARMS;

      typedef struct  {       

      DWORD           dwCallback;     // 低字节用于MCI_NOTIFY的窗口句柄

      DWORD          dwReturn;                         // 要获取的设备信息

      DWORD           dwItem;                     // 需要获取的信息项

      DWORD           dwTrack;                                     // 曲目的长度或曲目号

      } MCI_STATUS_PARMS;  MCI_STATUS_CURRENT_TRACK 得到当前曲目MCI_STATUS_LENGTH 得到CD或指定曲目长度MCI_STATUS_MODE 得到驱动器的当前状态MCI_STATUS_NUMBER_OF_TRACKS 得到CD曲目的数目MCI_STATUS_POSITION 得到当前格式下的位置MCI_STATUS_READY 检查设备是否就绪MCI_STATUS_TIME_FORMAT 得到当前时间格式MCI_STATUS_MEDIA_divSENT 检查以确认CD是否在驱动器内MCI_CDA_STATUS_TYPE_TRACK 检查已确认某曲目是否为音频曲目  1.OnOpen(){        MCI_OPEN_PARMS OpenParms;
        OpenParms.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_CD_AUDIO;              int ireturn=0; 
        ireturn=::mciSendCommand (NULL,
                      MCI_OPEN,
                      MCI_WAIT | MCI_OPEN_SHAREABLE|
                      MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID ,
                      (DWORD)(LPVOID) &OpenParms);       if(ireturn==0)
       {            // 获取CD中的歌曲数目,写入ListCtrl中
            StatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
                          mciSendCommand (m_wDeviceID,
                          MCI_STATUS, MCI_STATUS_ITEM,
                          (DWORD)(LPVOID) &StatusParms);
            UINT cdnum=StatusParms.dwReturn;
            for(int i=0;i            {
                   CString cdstr;
                   cdstr.Format("曲目%d",i+1);
                   m_cdcata.InsertItem(i,cdstr);
              }
        }
 } 2.OPlay(){   
    MCI_SET_PARMS SetParms;
    //// 设置时间格式: Tracks, Minutes, Seconds, & Frames
    SetParms.dwTimeFormat = MCI_FORMAT_TMSF;
    ::mciSendCommand (m_wDeviceID,
                      MCI_SET,
                      MCI_WAIT | MCI_SET_TIME_FORMAT,
                      (DWORD)(LPVOID) &SetParms);
    ::mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_SEEK_TO_START, NULL);
    MCI_PLAY_PARMS PlayParms;
    //指定播放起点必须经过MCI_MAKE_TMSF(Track,Minute,Second,Frame)转化
    PlayParms.dwFrom=MCI_MAKE_TMSF(m_cdcata.GetSelectionMark();,0,0,0);
    ::mciSendCommand (m_wDeviceID, MCI_PLAY, MCI_FROM, (DWORD)(LPVOID) &PlayParms);} 3.OnStop() {
    ::mciSendCommand (m_wDeviceID, MCI_STOP, NULL, NULL);
} 4.OnPause(){     ::mciSendCommand (m_wDeviceID, MCI_PAUSE, 0,NULL));} 注: 
使用MCI_STATUS_LENGTH 参数查询CD 及曲目长度,返回值通过调用
    MCI_MSF_MINUTE(),
    MCI_MSF_SECOND()
转换为分、秒。 
//得到CD总长void CCDAudio::GetTotalLength (int *pnMinutes, int *pnSeconds){if (m_bOpened){MCI_STATUS_PARMS StatusParms;StatusParms.dwItem = MCI_STATUS_LENGTH;if (::mciSendCommand (m_wDeviceID, MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM,(DWORD)(LPVOID) &StatusParms)){*pnMinutes = -1;*pnSeconds = -1;return;}*pnMinutes = MCI_MSF_MINUTE (StatusParms.dwReturn);*pnSeconds = MCI_MSF_SECOND (StatusParms.dwReturn);return;}*pnMinutes = -1;*pnSeconds = -1;}
//得到指定轨道的长度void CCDAudio::GetTrackLength (int nTrack, int *pnMinutes, int *pnSeconds){if (m_bOpened){MCI_STATUS_PARMS StatusParms;StatusParms.dwItem = MCI_STATUS_LENGTH;StatusParms.dwTrack = (DWORD) nTrack;if (::mciSendCommand (m_wDeviceID, MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM | MCI_TRACK,(DWORD)(LPVOID) &StatusParms)){*pnMinutes = -1;*pnSeconds = -1;return;}*pnMinutes = MCI_MSF_MINUTE (StatusParms.dwReturn);*pnSeconds = MCI_MSF_SECOND (StatusParms.dwReturn);return;}*pnMinutes = -1;*pnSeconds = -1;}

------------------------------------------------------
 注: 
MCI_STATUS_POSITION 参数返回值调用
         MCI_TMSF_TRACK(), 
         MCI_TMSF_MINUTE(),
         MCI_TMSF_SECOND(),
         MCI_TMSF_FRAME()
才能得到当前的位置的 道、分、秒、帧。

//得到当前轨道号int CCDAudio::GetCurrentTrack (void){if (m_bOpened){// Save the current positionMCI_STATUS_PARMS StatusParms;StatusParms.dwItem = MCI_STATUS_POSITION;if (::mciSendCommand (m_wDeviceID, MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM,(DWORD)(LPVOID) &StatusParms))return -1;return MCI_TMSF_TRACK (StatusParms.dwReturn);}return -1;}
//得到当前时间(分)int CCDAudio::GetMinutes (void){if (m_bOpened){// Save the current positionMCI_STATUS_PARMS StatusParms;StatusParms.dwItem = MCI_STATUS_POSITION;if (::mciSendCommand (m_wDeviceID, MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM,(DWORD)(LPVOID) &StatusParms))return -1;return MCI_TMSF_MINUTE (StatusParms.dwReturn);}return -1;}
//得到当前时间(秒)int CCDAudio::GetSeconds (void){if (m_bOpened){// Save the current positionMCI_STATUS_PARMS StatusParms;StatusParms.dwItem = MCI_STATUS_POSITION;if (::mciSendCommand (m_wDeviceID, MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM,(DWORD)(LPVOID) &StatusParms))return -1;return MCI_TMSF_SECOND (StatusParms.dwReturn);}return -1;}
//得到当前(帧)int CCDAudio::GetFrames (void){if (m_bOpened){// Save the current positionMCI_STATUS_PARMS StatusParms;StatusParms.dwItem = MCI_STATUS_POSITION;if (::mciSendCommand (m_wDeviceID, MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM,(DWORD)(LPVOID) &StatusParms))return -1;return MCI_TMSF_FRAME (StatusParms.dwReturn);}return -1;}

------------------------------------------------------

//BOOL CCDAudio::IsDriveReady (void){if (m_bOpened){// See if the CD is ready and the drive is closedMCI_STATUS_PARMS StatusParms;StatusParms.dwItem = MCI_STATUS_MODE;if (::mciSendCommand (m_wDeviceID, MCI_STATUS,MCI_STATUS_ITEM,(DWORD)(LPVOID) &StatusParms))return FALSE;if (StatusParms.dwReturn == MCI_MODE_NOT_READY|| StatusParms.dwReturn == MCI_MODE_OPEN)return FALSE;// See if there is media in the driveStatusParms.dwItem = MCI_STATUS_MEDIA_PRESENT;if (::mciSendCommand (m_wDeviceID, MCI_STATUS,MCI_STATUS_ITEM,(DWORD)(LPVOID) &StatusParms))return FALSE;return (BOOL) StatusParms.dwReturn;}return FALSE;}
//BOOL CCDAudio::IsAudioTrack (int nTrack){if (m_bOpened){// See if this track is an audio trackMCI_STATUS_PARMS StatusParms;StatusParms.dwItem = MCI_CDA_STATUS_TYPE_TRACK;StatusParms.dwTrack = nTrack;if (::mciSendCommand (m_wDeviceID, MCI_STATUS,MCI_STATUS_ITEM | MCI_TRACK,(DWORD)(LPVOID) &StatusParms))return FALSE;if (StatusParms.dwReturn == MCI_CDA_TRACK_AUDIO)return TRUE;}return FALSE;}

 注:
跳转的目标必须经过MCI_MAKE_TMSF(Track,Minute,Second,Frame)转化

//BOOL CCDAudio::SeekTo (int nTrack, int nMinute, int nSecond, int nFrame){if (m_bOpened){MCI_SEEK_PARMS SeekParms;SeekParms.dwTo = MCI_MAKE_TMSF (nTrack, nMinute, nSecond, nFrame);if (m_bPlaying && !m_bPaused)::mciSendCommand (m_wDeviceID, MCI_PAUSE, 0, NULL);if (::mciSendCommand (m_wDeviceID, MCI_SEEK,MCI_TO | MCI_WAIT,(DWORD)(LPVOID) &SeekParms))return FALSE;if (m_bPlaying && !m_bPaused)Play ();return TRUE;}return FALSE;}
//void CCDAudio::SkipForward (int nSeconds){if (m_bOpened){// Change format to millisecondsMCI_SET_PARMS SetParms;SetParms.dwTimeFormat = MCI_FORMAT_MILLISECONDS;::mciSendCommand (m_wDeviceID, MCI_SET,MCI_WAIT | MCI_SET_TIME_FORMAT,(DWORD)(LPVOID) &SetParms);// Get the current positionMCI_STATUS_PARMS StatusParms;DWORD dwPos;StatusParms.dwItem = MCI_STATUS_POSITION;::mciSendCommand (m_wDeviceID, MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM,(DWORD)(LPVOID) &StatusParms);dwPos = StatusParms.dwReturn;// Skip forward n millisecondsdwPos += (DWORD) nSeconds * 1000;// Pause & seek toMCI_SEEK_PARMS SeekParms;SeekParms.dwTo = dwPos;if (m_bPlaying && !m_bPaused)::mciSendCommand (m_wDeviceID, MCI_PAUSE, 0, NULL);::mciSendCommand (m_wDeviceID, MCI_SEEK,MCI_TO | MCI_WAIT,(DWORD)(LPVOID) &SeekParms);// Change format back to track, minutes, secondsSetParms.dwTimeFormat = MCI_FORMAT_TMSF;::mciSendCommand (m_wDeviceID, MCI_SET,MCI_WAIT | MCI_SET_TIME_FORMAT,(DWORD)(LPVOID) &SetParms);// Restart the audioif (m_bPlaying && !m_bPaused)Play ();}}
//void CCDAudio::SkipBack (int nSeconds){if (m_bOpened){// Change format to millisecondsMCI_SET_PARMS SetParms;SetParms.dwTimeFormat = MCI_FORMAT_MILLISECONDS;::mciSendCommand (m_wDeviceID, MCI_SET,MCI_WAIT | MCI_SET_TIME_FORMAT,(DWORD)(LPVOID) &SetParms);// Get the current positionMCI_STATUS_PARMS StatusParms;DWORD dwPos;StatusParms.dwItem = MCI_STATUS_POSITION;::mciSendCommand (m_wDeviceID, MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM,(DWORD)(LPVOID) &StatusParms);dwPos = StatusParms.dwReturn;// Skip forward n millisecondsdwPos -= (DWORD) nSeconds * 1000;// Pause & seek toMCI_SEEK_PARMS SeekParms;SeekParms.dwTo = dwPos;if (m_bPlaying && !m_bPaused)::mciSendCommand (m_wDeviceID, MCI_PAUSE, 0, NULL);::mciSendCommand (m_wDeviceID, MCI_SEEK,MCI_TO | MCI_WAIT,(DWORD)(LPVOID) &SeekParms);// Change format back to track, minutes, secondsSetParms.dwTimeFormat = MCI_FORMAT_TMSF;::mciSendCommand (m_wDeviceID, MCI_SET,MCI_WAIT | MCI_SET_TIME_FORMAT,(DWORD)(LPVOID) &SetParms);// Restart the audioif (m_bPlaying && !m_bPaused)Play ();}}
//OpenDrive (void){
::mciSendCommand (m_wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, NULL);}}
//CloseDrive (void){   ::mciSendCommand (m_wDeviceID, MCI_SET,  MCI_SET_DOOR_CLOSED, NULL);}