Cómo recibir notificación de inserción o eliminación de CD-ROM

Algunas aplicaciones necesitan saber cuándo el usuario inserta o quita un disco compacto o DVD de una unidad de CD-ROM sin sondear los cambios de medios. Windows proporciona una manera de notificar a estas aplicaciones a través del WM_DEVICECHANGE mensaje. En este artículo se explica cómo controlar el WM_DEVICECHANGE mensaje para detectar cambios en los medios de CD-ROM o DVD.

              Versión original del producto: Windows
Número de KB original: 163503

Notificación de Windows

Windows envía a todas las ventanas de nivel superior un WM_DEVICECHANGE mensaje cuando se agregan nuevos dispositivos o medios y están disponibles, y cuando se quitan los dispositivos o medios existentes. Cada WM_DEVICECHANGE mensaje tiene un evento asociado para describir el cambio y una estructura que proporciona información detallada sobre el cambio.

La estructura consta de un encabezado independiente del evento seguido de una estructura dependiente del evento. La parte dependiente del evento de la estructura describe a qué dispositivo se aplica el evento. Para usar esta estructura, las aplicaciones deben determinar primero el tipo de evento y el tipo de dispositivo. A continuación, pueden usar la estructura correcta para realizar las acciones adecuadas.

Cuando el usuario inserta un nuevo disco compacto o DVD en una unidad, las aplicaciones reciben un WM_DEVICECHANCE mensaje con un DBT_DEVICEARRIVAL evento. La aplicación debe comprobar el evento para asegurarse de que el tipo de dispositivo que llega es un volumen (DBT_DEVTYP_VOLUME) y que la marca multimedia del evento (DBTF_MEDIA) está establecida.

Cuando el usuario quita un disco compacto de una unidad de CD-ROM o DVD, las aplicaciones recibirán un WM_DEVICECHANCE mensaje con un DBT_DEVICEREMOVECOMPLETE evento. Al igual que con DBT_DEVICEARRIVAL lo anterior, la aplicación debe comprobar el evento para asegurarse de que el dispositivo que se quita es un volumen y de que la marca multimedia del evento está establecida.

Código de ejemplo

En el código siguiente se muestra cómo usar el WM_DEVICECHANGE mensaje para comprobar la inserción o eliminación de discos compactos o DVD.

#include <windows.h>
#include <dbt.h>

char FirstDriveFromMask (ULONG unitmask);  //prototype
/*----------------------------------------------------------------------
   Main_OnDeviceChange (hwnd, wParam, lParam)
   Description
   Handles WM_DEVICECHANGE messages sent to the application's top-level window.
   ----------------------------------------------------------------------*/
void Main_OnDeviceChange (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
   PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam;
   char szMsg[80];

   switch(wParam)
   {
      case DBT_DEVICEARRIVAL:
      // See if a CD-ROM or DVD was inserted into a drive.
      if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
      {
         PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;

         if (lpdbv -> dbcv_flags & DBTF_MEDIA)
         {
            wsprintf (szMsg, "Drive %c: arrived\n",
                     FirstDriveFromMask(lpdbv ->dbcv_unitmask));
            MessageBox (hwnd, szMsg, "WM_DEVICECHANGE", MB_OK);
         }
      }
      break;

      case DBT_DEVICEREMOVECOMPLETE:
      // See if a CD-ROM was removed from a drive.
      if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
      {
         PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;

         if (lpdbv -> dbcv_flags & DBTF_MEDIA)
         {
            wsprintf (szMsg, "Drive %c: was removed\n",
                     FirstDriveFromMask(lpdbv ->dbcv_unitmask));
            MessageBox (hwnd, szMsg, "WM_DEVICECHANGE", MB_OK);
         }
      }
      break;

      default:
     /*
       Other WM_DEVICECHANGE notifications get sent for other devices or 
       reasons; we don't care about them here.  If they were important, we 
       would check for them and act accordingly.
    */
     ;
   }
}
/*----------------------------------------------------------------------
   FirstDriveFromMask (unitmask)
   Finds the first valid drive letter from a mask of drive letters. 
   The mask must be in the format bit 0 = A, bit 1 = B, bit 3 = C, etc.
   A valid drive letter is defined when the corresponding bit is set to 1.
   Returns the drive letter that was first found.
   ----------------------------------------------------------------------*/
char FirstDriveFromMask (ULONG unitmask)
{
   char i;

   for (i = 0; i < 26; ++i)
   {
      if (unitmask & 0x1)
            break;
      unitmask = unitmask >> 1;
   }
   return (i + 'A');
}

Aunque este código de ejemplo solo comprueba si hay llegadas de volumen debido a la inserción de nuevos medios, también se puede ampliar para recibir notificaciones de otros eventos de hardware para otros tipos. Para ello, debe agregar casos para otros eventos de dispositivo y controlar diferentes tipos de dispositivos para cada evento.