
A mellékelt példa kipróbálásához indítsa el az alkalmazást, és helyezzen el egy lemezt a számítógép CD-meghajtójában, majd vegye ki onnan.
A CD-meghajtókhoz kapcsolódó események keletkezésekor a Windows a WM_DEVICECHANGE üzenetet juttatja el a futó process-ek mindegyikéhez (broadcast üzenet).
Az üzenet objektum első paramétere (wParam) hordozza az információt arról, hogy tulajdonképpen milyen esemény is következett be a meghajtónál, a második paraméter (lParam) tartalmazza a meghajtó jellemzőit. A szükséges típusok deklarációit a Win32 osztályban helyeztük el.
A példában a WM_DEVICECHANGE üzenet figyeléséhez deklarálnunk kell egy konstanst, melyet használhatunk a Form objektumunk WndProc ablakkezelő függvényének felülírásakor.
public const int WM_DEVICECHANGE = 0x0219;
Szükségünk van egy felsorolt típusra, melynek elemei tartalmazzák a bekövetkezett esemény azonosítóját.
public enum DeviceEvent : int
{
DBT_DEVICEARRIVAL = 0x8000,
DBT_DEVICEREMOVECOMPLETE = 0x8004
}
Egy másik felsorolt típusban helyezzük el azokat a konstansokat, melyekkel beazonosítjuk majd a meghajtó-típust.
public enum DeviceType : int
{
DBT_DEVTYP_OEM = 0x00000000,
DBT_DEVTYP_DEVNODE = 0x00000001,
DBT_DEVTYP_VOLUME = 0x00000002,
DBT_DEVTYP_PORT = 0x00000003,
DBT_DEVTYP_NET = 0x00000004
}
Létrehoztunk egy struktúrát az üzenet második paraméterének lekérdezéséhez. A struktúra a DEV_BROADCAST_HDR menedzselt megfelelője.
public struct DEV_BROADCAST_HDR
{
public int dbch_size;
public DeviceType dbch_devicetype;
private int dbch_reserved;
}
És még egyet a meghajtóra vonatkozó információk részleteinek feldolgozásához.
public struct DEV_BROADCAST_VOLUME
{
public int dbcv_size;
public DeviceType dbcv_devicetype;
private int dbcv_reserved;
public int dbcv_unitmask;
public int dbcv_flags;
}
A DEV_BROADCAST_VOLUME struktúra dbcv_unitmask mezője tartalmazza majd a meghajtó betűjelére utaló bitmintát. Ennek konvertálására szolgál a MaskToDriveLetter metódusunk, mely egy string-ben adja vissza a meghajtó betűjelét.
public static string MaskToDriveLetter(int mask)
{
...
if(mask > 0)
{
Amennyiben a kapott paraméter értéke nagyobb mint nulla, akkor a bitminta kiértékelődik. A bitsorozat értéke adja meg, hogy melyik meghajtónál zajlott le esemény. Ha a bitminta első jegye 1 értékű, akkor az „A” meghajtóról van szó, stb.
for (;mask != 0;mask >>= 1)
{
A változó értékét egy bitszintű összehasonlításnak vetjük alá, hogy eldöntsük, hányadik jegy 1 értékű. A sorszám értékét hozzáadjuk a 65-höz, majd a kapott értéket karakterré konvertáljuk (ASCII kód).
if ((mask & 1)!=0)
{
ret.Append((char)(65 + _value));
ret.Append(":,");
}
_value++;
}
ret.Remove(ret.Length - 1,1);
}
return ret.ToString();
...
}
Az alkalmazás ablakának WndProc metódusában végezzük el a lényegi munkát.
if(message.Msg == Win32.WM_DEVICECHANGE)
{
Amennyiben a WM_ DEVICECHANGE üzenet érkezett az ablakhoz, akkor lekérdezzük az első paramétert.
lEvent = (Win32.DeviceEvent)message.WParam.ToInt32();
Ha a meghajtóba lemezbehelyezés történt, akkor lekérdezzük a második paramétert.
if (lEvent == Win32.DeviceEvent.DBT_DEVICEARRIVAL)
{
lBH = (Win32.DEV_BROADCAST_HDR)Marshal.PtrToStructure(message.LParam,typeof(Win32.DEV_BROADCAST_HDR));
Ha a kapott üzenet a CD-meghajtótól érkezett, akkor meghatározzuk a betűjelét is.
if(lBH.dbch_devicetype == Win32.DeviceType.DBT_DEVTYP_VOLUME)
{
lVolume = (Win32.DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(message.LParam,typeof(Win32.DEV_BROADCAST_VOLUME));
listBox1.Items.Clear();
listBox1.Items.Add("Lemezt helyeztek a(z) " + Win32.MaskToDriveLetter(lVolume.dbcv_unitmask) + " meghajtóba");
}
}
A második paraméter értéke DBT_DEVICEREMOVECOMPLETE, ha a lemez eltávolításra kerül, így a függvény másik részében ezt a feltételt értékeljük ki.
if (lEvent == Win32.DeviceEvent.DBT_DEVICEREMOVECOMPLETE)
{
...
}
}