CD-ROM 挿入/取り出しの通知を取得する方法


概要


一部のアプリケーションでは、メディアの変更を監視することなしに、コンパクト ディスクや DVD が CD-ROM ドライブに挿入されたことや、CD-ROM ドライブから取り出されたことを検出する必要があります。Windows では、それらのアプリケーションが WM_DEVICECHANGE メッセージを通して通知する方法を提供しています。この資料では、CD-ROM や DVD メディアの変更を検出するための、WM_DEVICECHANGE メッセージの扱い方について説明します。

詳細


Windows は、新しいデバイスやメディアが追加され利用可能になったときや、それらのデバイスやメディアが取り出されたときに、すべてのトップ レベル ウィンドウに WM_DEVICECHANGE メッセージを送信します。それぞれの WM_DEVICECHANGE メッセージには、変更を示すために関連付けられたイベント、および変更に関する詳細情報を提供する構造体が含まれています。


構造体は、イベントに依存しないヘッダーに続いて、イベントに依存する構造体で構成されています。イベントに依存する構造体部分は、イベントがどのデバイスで発生したかを示します。この構造体を使用するために、アプリケーションは最初にイベントの種類とデバイスの種類を特定します。その後で、それぞれのイベントに適した構造体を使用できます。


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


ユーザーが CD-ROM ドライブからコンパクト ディスクや DVD を取り出したとき、アプリケーションは DBT_DEVICEREMOVECOMPLETE イベントと共に WM_DEVICECHANGE メッセージを受け取ります。上記の 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');
}
このサンプル コードは、新しいメディアの挿入によるボリュームの到着を単にチェックするだけですが、他の種類に対する他のハードウェア イベントの通知を取得するように拡張することも可能です。これを行うには、他のデバイスのイベントに関する case 文を追加して、それぞれのイベントに関して別のデバイスを扱うようにします。

関連情報


Microsoft Platform SDK ドキュメント「Device Management」の概要の章