CD-ROM の挿入または削除の通知を受け取る方法

一部のアプリケーションでは、メディアの変更をポーリングせずに、CD-ROM ドライブからコンパクト ディスクまたは DVD を挿入または削除するタイミングを把握する必要があります。 Windows では、メッセージを介してこれらのアプリケーションに通知する方法が WM_DEVICECHANGE 提供されます。 この記事では、CD-ROM または DVD メディアの変更を WM_DEVICECHANGE 検出するためにメッセージを処理する方法について説明します。

元の製品バージョン: Windows
元の KB 番号: 163503

Windows 通知

Windows は、新しいデバイスまたはメディアが追加されて使用可能になったとき、および既存のデバイスまたはメディアが削除されたときに、すべての最上位ウィンドウ WM_DEVICECHANGE にメッセージを送信します。 各 WM_DEVICECHANGE メッセージには、変更を説明するためのイベントと、変更に関する詳細情報を提供する構造体が関連付けられています。

構造体は、イベントに依存しないヘッダーの後にイベントに依存する構造体で構成されます。 構造体のイベント依存部分は、イベントが適用されるデバイスを記述します。 この構造を使用するには、アプリケーションが最初にイベントの種類とデバイスの種類を決定する必要があります。 次に、適切な構造を使用して適切なアクションを実行できます。

ユーザーが新しいコンパクト ディスクまたは DVD をドライブに挿入すると、アプリケーションはイベントを含むメッセージをWM_DEVICECHANCEDBT_DEVICEARRIVAL受け取ります。 アプリケーションは、到着するデバイスの種類がボリューム () であり、イベントのメディア フラグ (DBT_DEVTYP_VOLUMEDBTF_MEDIA) が設定されていることを確認するために、イベントをチェックする必要があります。

CD-ROM ドライブまたは DVD からコンパクト ディスクを削除すると、アプリケーションはイベントを含むメッセージをWM_DEVICECHANCEDBT_DEVICEREMOVECOMPLETE受け取ります。 上記とDBT_DEVICEARRIVAL同様に、アプリケーションは、削除されるデバイスがボリュームであり、イベントのメディア フラグが設定されていることを確認するために、イベントをチェックする必要があります。

サンプル コード

次のコードは、メッセージを使用して、コンパクト ディスクまたは DVD のWM_DEVICECHANGE挿入または取り外しをチェックする方法を示しています。

#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');
}

このサンプル コードでは、新しいメディアの挿入によるボリューム到着のみを確認しますが、他の種類の他のハードウェア イベントの通知を受け取るために拡張することもできます。 そのためには、他のデバイス イベントのケースを追加し、イベントごとに異なるデバイスの種類を処理する必要があります。