MCI_SEND_COMMAND play MP3

Iniciado por CarEnMDC, 13 Agosto 2013, 04:08 AM

0 Miembros y 1 Visitante están viendo este tema.

CarEnMDC

Desde hace un tiempo (varios años) he estado haciendo sonar archivos MP3 con las api de Windows utilizando MCI_SEND_COMMAND. He intentado muchas formas de escribir el código, desde todo en el EXE a librerias DLL.

El problema que se presentas es que al estar reproduciendo las canciones, cuando llega a la canción 12 ó 13 sale un error "el programa -xxxxxx- ha realizado una operación no válida".

Les paso el código y si le encuentran la solución, la suben.

Gracias.

//*******************//
#define WINVER 0x0501
#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <mmsystem.h>
#include <string.h>
#include <wchar.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#pragma comment(lib, "winmm")


char szString[255];
HWND hListbox = NULL;
int idFile;
int ret;
int nMax;
LPSTR lpmFile;
char szClassName[ ] = "RepicarApp";
ULONG WINAPI TH_PLAY_FILE(LPVOID);
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
void OpenDialog(HWND);
void LoadFile(LPSTR);

int Ajustar(HWND);

int WINAPI WinMain( HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)
{
     HWND hwnd;
     MSG messages;
     WNDCLASSEX wincl;
     LPTSTR MyIcon;
     MyIcon = MAKEINTRESOURCE(502);

     wincl.hInstance = hThisInstance;
     wincl.lpszClassName = szClassName;
     wincl.lpfnWndProc = WindowProcedure;
     wincl.style = CS_DBLCLKS;
     wincl.cbSize = sizeof(WNDCLASSEX);
     wincl.hIcon = LoadIcon(hThisInstance, MyIcon);
     wincl.hIconSm = LoadIcon(hThisInstance, MyIcon);
     wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
     wincl.cbClsExtra = 0;
     wincl.cbWndExtra = 0;
     wincl.hbrBackground = (HBRUSH)(COLOR_WINDOW);

     if (!RegisterClassEx(&wincl))
     return 0;

     hwnd = CreateWindowEx(
            0,
            szClassName,
            "Repicar con Dev C++",
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            350, 400,
            HWND_DESKTOP,
            NULL,
            hThisInstance,
            NULL);
            Ajustar(hwnd);

AnimateWindow(hwnd, 1000, AW_CENTER |
                         AW_ACTIVATE //|
                         //AW_HOR_POSITIVE |
                         //AW_HOR_NEGATIVE |
                         //AW_BLEND //|
                         //AW_SLIDE
                          );
ShowWindow (hwnd, nFunsterStil);
while (GetMessage (&messages, NULL, 0, 0))
{
      TranslateMessage(&messages);
      DispatchMessage(&messages);

}
return messages.wParam;

}

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   
   switch (message)
      {
          case WM_CREATE:
             
             CreateWindow (TEXT("button"), TEXT("Seleccionar"), WS_VISIBLE | WS_CHILD, 225, 10, 100, 30, hwnd, (HMENU) 1, NULL, NULL);
             CreateWindow (TEXT("button"), TEXT("Tocar"),       WS_VISIBLE | WS_CHILD, 225, 50, 100, 30, hwnd, (HMENU) 2, NULL, NULL);
             CreateWindow (TEXT("button"), TEXT("Pausa"),       WS_VISIBLE | WS_CHILD, 225, 90, 100, 30, hwnd, (HMENU) 3, NULL, NULL);
             CreateWindow (TEXT("button"), TEXT("Detener"),     WS_VISIBLE | WS_CHILD, 225, 130, 100, 30, hwnd, (HMENU) 4, NULL, NULL);
             hListbox =
             CreateWindow (TEXT("listbox"), "", LBS_NOINTEGRALHEIGHT |WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL | WS_HSCROLL, 10, 10, 205, 340,
                           hwnd, (HMENU) 10, NULL, NULL);
                           
/*                   CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), TEXT("Write here!"), WS_CHILD | WS_VISIBLE,
                           330, 10, 180, 300,
                           hwnd, (HMENU) 0xED, GetModuleHandle(NULL), NULL);
                   CreateWindow (TEXT("listbox"), TEXT("Carlos"),
                                WS_VISIBLE|WS_CHILD|WS_BORDER|WS_VSCROLL|WS_HSCROLL|
                                ES_MULTILINE|ES_WANTRETURN|ES_AUTOHSCROLL|ES_AUTOVSCROLL,
                                10, 10, 280, 300,
                                hwnd, (HMENU) 3, NULL, NULL);*/

               break;
                case WM_SIZE:
        {
            Ajustar(hwnd);
            return 0;
        }
              case WM_COMMAND:
                    if (LOWORD(wParam) == 1)
                   {
                       OpenDialog(hwnd);
                       
                   }
                   if (LOWORD(wParam) == 2)
                   {
                         printf("Entered In Main\n");
                  HANDLE hThread;
                  unsigned long threadID;
                  
                  /*----------------*/
                  HANDLE m_hThread;
                  DWORD m_dwThreadID;
                  HANDLE m_hEvtThreadReady;
                  HWND m_hWndNotify;
                  
                  //CPs_PlayEngine* pNewPlayEngine;

                  // Thread control object
                  //pNewPlayEngine = (CPs_PlayEngine*)malloc(sizeof(CPs_PlayEngine));
                  //pNewPlayEngine->m_hWndNotify = hWndMain;
               
                                                   
                  
                  //pNewPlayEngine->m_hThread = CreateThread(NULL, 0, CPI_Player__EngineEP, pNewPlayEngine, 0, &(pNewPlayEngine->m_dwThreadID) );
                  //CP_ASSERT(pNewPlayEngine->m_hThread);
               
                  
                  
                  /*-------------------*/
                  // Create event that will be signaled when the thread is ready for input
                  m_hEvtThreadReady = CreateEvent(NULL, FALSE, FALSE, NULL);
                  
                  // Create thread
                  hThread = CreateThread(NULL, 0, TH_PLAY_FILE, NULL, 0, &threadID);
                  //if ( hThread == NULL)
                  //   ExitProcess(hThread);
                  // Send message (callee will free string)
                  char *Item;
                        int iCurSel = (int)SendMessage(hListbox, LB_GETCURSEL, 0, 0);
                        int nItemLen = (int)SendMessage(hListbox, LB_GETTEXTLEN, iCurSel, 0);
                        if (nItemLen > 0)  {
                            Item = (char*)malloc(nItemLen);
                            SendMessage(hListbox, LB_GETTEXT, iCurSel, (LPARAM)Item);
                            SetWindowText(hwnd, Item);
                        }
                        char* pcStringCopy;
                  // Make copy of string data
                  {
                     const int iBufferLen = strlen(Item) + 1;
                     pcStringCopy = (char*)malloc(iBufferLen * sizeof(char));
                     memcpy(pcStringCopy, Item, iBufferLen);
                  }
                  PostThreadMessage(threadID, TH_PLAY_FILE, (WPARAM)pcStringCopy, 0);
                  //WaitForSingleObject(hThread, INFINITE);
                  // Wait for the engine to be ready for input
                  WaitForSingleObject(hThread, INFINITE);                  
                  CloseHandle(m_hEvtThreadReady);
                  m_hEvtThreadReady = NULL;
                  MessageBox(NULL, "Ya se Cerró el Hilo", "Aviso", MB_OK);
                       
                  /*MCI_OPEN_PARMS mciOpenParms;
                       MCI_STATUS_PARMS mciStatusParms;
                       MCI_SET_PARMS mciSetParms;
                       if (idFile != 0 )
                       {
                           ret = mciSendCommand(idFile, MCI_CLOSE, 0 ,(DWORD)(LPVOID) &mciOpenParms);
                           idFile = 0;
                        }
                       
                        char *Item;
                        int iCurSel = (int)SendMessage(hListbox, LB_GETCURSEL, 0, 0);
                        int nItemLen = (int)SendMessage(hListbox, LB_GETTEXTLEN, iCurSel, 0);
                        if (nItemLen > 0)  {
                            Item = (char*)malloc(nItemLen);
                            SendMessage(hListbox, LB_GETTEXT, iCurSel, (LPARAM)Item);
                            SetWindowText(hwnd, Item);
                        }
                       
                        mciOpenParms.lpstrDeviceType = "MPEGVideo";
                        mciOpenParms.lpstrElementName = Item;
                        ret = mciSendCommand(idFile, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_ELEMENT, (DWORD)(LPVOID) &mciOpenParms);
                        idFile = mciOpenParms.wDeviceID;
                        char strError[255];
                        mciGetErrorString(ret , strError, 255);
                        if (ret > 0)
                        {
                            MessageBox(hwnd, strError, "Error", MB_OK | MB_ICONERROR);
                            return false;
                        }
                        ret = mciSendCommand(idFile, MCI_PLAY, 0, (DWORD)(LPVOID) &mciOpenParms);
                        mciGetErrorString(ret , strError, 255);
                        if (ret > 0)
                        {
                            MessageBox(hwnd, strError, "Error", MB_OK | MB_ICONERROR);
                            return false;
                        }*/

                   }
                   if (LOWORD(wParam) == 3)
                   {
                     //AnimateWindow(hwnd, 200, AW_BLEND);
                      MessageBox(hwnd, "Presionaste Pausa", "Mensaje", MB_OK | MB_ICONINFORMATION);
                   }
                   if (LOWORD(wParam) == 4)
                   {
                     //AnimateWindow(hwnd, 200, AW_BLEND);
                      MessageBox(hwnd, "Presionaste Detener", "Mensaje", MB_OK | MB_ICONINFORMATION);
                   }
              break;

               case WM_DESTROY:
                    PostQuitMessage(0);
                    break;
               default:
                       return DefWindowProc (hwnd, message, wParam, lParam);
        }
        return 0;
}
int Ajustar(HWND hwnd)
{
    RECT rc;
    GetClientRect(hwnd, &rc);
    MoveWindow(GetDlgItem(hwnd, 1), rc.right - 110, rc.top + 10 , 100,  30, TRUE);
    MoveWindow(GetDlgItem(hwnd, 2), rc.right - 110, rc.top + 50 , 100,  30, TRUE);
    MoveWindow(GetDlgItem(hwnd, 3), rc.right - 110, rc.top + 90 , 100,  30, TRUE);
    MoveWindow(GetDlgItem(hwnd, 4), rc.right - 110, rc.top + 130 , 100,  30, TRUE);
    MoveWindow(GetDlgItem(hwnd, 10), rc.left + 10, rc.top + 10 , rc.right - 130, rc.bottom - 20, TRUE);

}
void OpenDialog(HWND hwnd)
{
  OPENFILENAME ofn;
  TCHAR szFile[65535];


  ZeroMemory(&ofn, sizeof(ofn));
  ofn.lStructSize = sizeof(ofn);
  ofn.lpstrFile = szFile;
  ofn.lpstrFile[0] = '\0';
  ofn.hwndOwner = hwnd;
  ofn.nMaxFile = sizeof(szFile);
  ofn.lpstrFilter = TEXT("All files(*.*)\0*.*\0");
  ofn.nFilterIndex = 1;
  ofn.lpstrInitialDir = NULL;
  ofn.lpstrFileTitle = NULL;
  ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_EXPLORER;
//    string filename[] = ofn.FileNames;
// int noOfSelectedFiles=ofn.FileNames.Length;
//for (i = 0; i < 1000; i++)
//{
//filename = openFileDialog.FileNames.ToString();
//}
//LPSTR filename[] = ofn.lpstrFile;
//SendMessage(hListbox, LB_ADDSTRING, 0, (LPARAM)file);

  if(GetOpenFileName(&ofn))
  {
      //LoadFile(ofn.lpstrFile);
      bool bMultipleFileSelected = (ofn.lpstrFile[ofn.nFileOffset - 1] == '\0');
        if (bMultipleFileSelected)
     {
       bool bDirectoryIsRoot = (ofn.lpstrFile[strlen(ofn.lpstrFile) - 1] == '\\');

      for
      (
         CHAR *szTemp = ofn.lpstrFile + ofn.nFileOffset;
     *szTemp;
     szTemp += (strlen(szTemp) + 1)
    )
    {
      size_t dwLen = strlen(ofn.lpstrFile) + strlen(szTemp) + 2;
      CHAR * szFile = new CHAR[dwLen];
      strcpy(szFile,  ofn.lpstrFile);
      if (!bDirectoryIsRoot)
      {
        strcat(szFile, "\\");
      }
      strcat(szFile,  szTemp);
      //::MessageBox(NULL, szFile, "A File Name", NULL);
      SendMessage(hListbox, LB_ADDSTRING, 0, (LPARAM)szFile);
      delete szFile;
       }
     }
     else
     {
       //::MessageBox(NULL, ofn.lpstrFile, "A File Name", NULL);
       SendMessage(hListbox, LB_ADDSTRING, 0, (LPARAM)ofn.lpstrFile);
     }
  }

}
void LoadFile(LPSTR file)
{
  HANDLE hFile;
  DWORD dwSize;
  DWORD dw;

  LPBYTE lpBuffer = NULL;

  hFile = CreateFile(file, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
  dwSize = GetFileSize(hFile, NULL);
  lpBuffer = (LPBYTE) HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, dwSize + 1);
  ReadFile(hFile, (LPWSTR)lpBuffer, dwSize, &dw, NULL);
  CloseHandle(hFile);
  lpBuffer[dwSize] = 0;
  SendMessage(hListbox, LB_ADDSTRING, 0, (LPARAM)file);
  HeapFree(GetProcessHeap(), 0, lpBuffer);
}

ULONG WINAPI TH_PLAY_FILE(LPVOID lpFile)
{
   MCI_OPEN_PARMS mciOpenParms;
   MCI_STATUS_PARMS mciStatusParms;
   MCI_SET_PARMS mciSetParms;
   if (idFile != 0 )
   {
      ret = mciSendCommand(idFile, MCI_CLOSE, 0 ,(DWORD)(LPVOID) &mciOpenParms);
      idFile = 0;
   }
   MessageBox(NULL, lpFile, "File", MB_OK);
   /*char *Item;
   int iCurSel = (int)SendMessage(hListbox, LB_GETCURSEL, 0, 0);
   /*int nItemLen = (int)SendMessage(hListbox, LB_GETTEXTLEN, iCurSel, 0);
   /*if (nItemLen > 0)
   {
      Item = (char*)malloc(nItemLen);
      SendMessage(hListbox, LB_GETTEXT, iCurSel, (LPARAM)Item);
      //SetWindowText(hwnd, Item);
   }
   
   /*mciOpenParms.lpstrDeviceType = "MPEGVideo";
   mciOpenParms.lpstrElementName = Item;
   ret = mciSendCommand(idFile, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_ELEMENT, (DWORD)(LPVOID) &mciOpenParms);
   idFile = mciOpenParms.wDeviceID;
   char strError[255];
   mciGetErrorString(ret , strError, 255);
   if (ret > 0)
   {
      MessageBox(NULL, strError, "Error", MB_OK | MB_ICONERROR);
      return false;
   }
   
   ret = mciSendCommand(idFile, MCI_PLAY, 0, (DWORD)(LPVOID) &mciOpenParms);
   mciGetErrorString(ret , strError, 255);
   if (ret > 0)
   {
      MessageBox(NULL, strError, "Error", MB_OK | MB_ICONERROR);
      return false;
   }*/
   Sleep (500);
   return 0;
}
//**********//

Eternal Idol

No amigo, compila y enlaza con informacion de debug y despues ejecuta tu programa con un depurador (WinDbg es el mejor).
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

CarEnMDC

Gracias, ya lo probé como dices.

El programa no tiene fallas cuando se compila.
Cuando ya está en ejecución.
1. Selecciono las canciones que se agregan a una lista.
2. Se inicia la reproducción de cada canción en la lista.
3. Durante la reproducción de cada canción son operativos todos los botones y funciones del programa.
4. Cuando está reproduciendo la canción 11 ó 12 ya no puede reproducir la siguiente (Como si se llenara algo) y sale el mensaje de error del sistema operativo que debe cerrar el programa.

Cuando lo pruebo en modo depuración desde el entorno de programación, sale el error que muestra Windows y cierra todo (incluido el entorno de programación) sin mostrarse la línea del error.

Saludos.

Eternal Idol

Depuralo con WinDbg si tu IDE no es util.

¿Que pasa en WindowProcedure cuando nItemLen es 0? ¿Que hay en Item en ese caso?

Por otro lado:
LB_GETTEXT message

Gets a string from a list box.

Parameters
wParam
The zero-based index of the string to retrieve.

lParam
A pointer to the buffer that will receive the string; it is type LPTSTR which is subsequently cast to an LPARAM. The buffer must have sufficient space for the string and a terminating null character. An LB_GETTEXTLEN message can be sent before the LB_GETTEXT message to retrieve the length, in TCHARs, of the string.


LB_GETTEXTLEN message
Gets the length of a string in a list box.

Parameters
wParam
The zero-based index of the string.

lParam
This parameter is not used.

Return value

The return value is the length of the string, in TCHARs, excluding the terminating null character. Under certain conditions, this value may actually be greater than the length of the text. For more information, see the following Remarks section.


Eso significa que cuando reservas memoria para Item te falta un byte para el 0 terminador.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

CarEnMDC

Gracias por la aclaración, no había tomado en cuenta el caracter nulo final.


Eternal Idol

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón