0

我使用 Windows MCI(“媒体控制接口”)编写了一些基本的 C++ 程序,特别是用于播放 MIDI 和 MP3 文件。它们曾经在 Windows XP 上完美运行。最近我搬到了 Windows 10,现在它们有时可以工作(我不知道在什么条件下),但大多数情况下它们会立即终止,而不播放 MP3 或 MIDI 文件。奇怪的是我没有收到错误指示(非零返回码)。我确保在所有相关调用中都包含 MCI_WAIT 选项。这些程序是命令行程序,而不是图形程序。请帮忙!

好的,这是可读性更好的 PLAYSIM(PLE) 代码(抱歉,我不经常使用 stackoverflow)。你会注意到主线是非常基础的。这个实现中的设备类型是从文件类型推断出来的——它总是工作得很好(不正确或不受支持的文件类型会导致一条消息,而不是“静默失败”)。我试图在 OPEN 之前加上 CLOSE,但这是不允许的。我还寻找了某种“MCI(重新)初始化调用”,但没有找到——而且以前从未需要它。

--->>> 更简单的版本见最后。该版本应该在任何 Windows 系统上都是“可编译的”。

我怎样才能提醒微软修复这个错误???

// ╔══════════════════════════════════════════════╗
// ║..............................................║
// ║.┌────┐.┌┐.....┌────┐.┌┐..┌┐.┌────┐.┌┐.┌────┐.║
// ║.│┌──┐│.││.....│┌──┐│.││..││.│┌───┘.││.│┌┐┌┐│.║
// ║.│└──┘│.││.....│└──┘│.│└──┘│.│└───┐.││.││││││.║
// ║.│┌───┘.││.....│┌──┐│.└─┐┌─┘.└───┐│.││.││└┘││.║
// ║.││.....│└───┐.││..││...││...┌───┘│.││.││..││.║
// ║.└┘.....└────┘.└┘..└┘...└┘...└────┘.└┘.└┘..└┘.║ Reinier Bakels
// ║..............................................║ 17 January 2016
// ╚══════════════════════════════════════════════╝
/*
\borland\bcc55\include\.h
\borland\bcc55\include\mmsystem.h
\borland\bcc55\include\winbase.h
*/
   #define NAME_COMMANDS
#include "\rbb\boilerpl.h"
#include "\rbb\dis.h"
#include "\rbb\print.h"
#include "\rbb\ps.h"
#include "\rbb\gct.h" // getCurrentTime()
#include <windows>
#include <mmsystem>
#include <io>

#ifdef NAME_COMMANDS
const char * commandNames[] = {
   ""           , // 0x0800
   ""           , // 0x0801
   ""           , // 0x0802
   "Open"       , // 0x0803
   "Close"      , // 0x0804
   "Escape"     , // 0x0805
   "Play"       , // 0x0806
   "Seek"       , // 0x0807
   "Stop"       , // 0x0808
   "Pause"      , // 0x0809
   "Info"       , // 0x080A
   "GetDevCaps" , // 0x080B
   "Spin"       , // 0x080C
   "Set"        , // 0x080D
   "Step"       , // 0x080E
   "Record"     , // 0x080F
   "Sysinfo"    , // 0x0810
   "Break"      , // 0x0811
   ""           , // 0x0812
   "Save"       , // 0x0813
   "Status"       // 0x0814
};
#endif

DWORD mci( MCIDEVICEID devID , UINT uCmd , void * parms , DWORD options = 0 )
{
   DWORD rc ;
   #ifdef NAME_COMMANDS
   fputs( commandNames[ uCmd - DRV_MCI_FIRST ] , stdout ); putchar(' ');
   #endif
   if ( rc = mciSendCommand( devID , uCmd , options , (DWORD) parms )) {
      disint( rc );
      TCHAR errorMessage[MAXERRORLENGTH];
      if ( mciGetErrorString( rc , errorMessage , sizeof errorMessage )) {
         CharToOem( errorMessage , errorMessage );
         puts( errorMessage );
      } else {
         puts( "(unknown)" );
      } /* endif */
   } else {
      puts( "OK.");
   } /* endif */
   return rc ;
}


int main( int argc , char ** argv )
{
   boilerPlate();
   if ( argc < 2 ) { puts("no arg."); return 0 ; }
   char * fileName = *++argv ; disstr( fileName ); if ( access( fileName ,0 )) { say(File does not exist); return 0 ; }
   MCI_OPEN_PARMS openParms = {0};
   MCI_PLAY_PARMS playParms = {0};
   MCI_GENERIC_PARMS genericParms = {0}; // only contains dwCallback

   openParms.lpstrElementName = fileName ;
   mci(0, MCI_OPEN , & openParms , MCI_WAIT | MCI_OPEN_ELEMENT ); // MCI_OPEN_SHAREABLE not allowed!
   MCIDEVICEID devID = openParms.wDeviceID ; if ( devID != 1 ) dishex( devID ); // don't know why, but it seems to be always one

   __int64 before = getCurrentTime();
   if (! mci( devID, MCI_PLAY , & playParms , MCI_WAIT ))
   printf( "\tcompleted with zero return code in %G seconds.\n", 1e-7f * ( getCurrentTime() - before )); 

   mci( devID, MCI_CLOSE , & genericParms );

   return 0 ;
}

更简单:

// PLAYSIM even more simplified
#include <stdio>
#include <windows>
#include <mmsystem>
#include <io>

DWORD mci( const char * commandName , MCIDEVICEID devID , UINT uCmd , void * parms , DWORD options = 0 )
{
   DWORD rc = mciSendCommand( devID , uCmd , options , (DWORD) parms );
   fputs( commandName , stdout ); puts( rc ? " failed." : " OK." );      
   return rc ;
}

int main( int argc , char ** argv )
{
   if ( argc < 2 ) { puts("no arg."); return 0 ; }
   char * fileName = *++argv ; if ( access( fileName ,0 )) { puts( "File does not exist."); return 0 ; }
   MCI_OPEN_PARMS openParms = {0};
   MCI_PLAY_PARMS playParms = {0};
   MCI_GENERIC_PARMS genericParms = {0}; // only contains dwCallback

   openParms.lpstrElementName = fileName ;
   mci( "Open ",  0                   , MCI_OPEN  , & openParms , MCI_WAIT | MCI_OPEN_ELEMENT ); 
   mci( "Play " , openParms.wDeviceID , MCI_PLAY  , & playParms , MCI_WAIT ); 
   mci( "Close" , openParms.wDeviceID , MCI_CLOSE , & genericParms );

   return 0 ;
}
4

0 回答 0