Tải bản đầy đủ (.pdf) (10 trang)

USB Complete fourth- P30 ppsx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (170.19 KB, 10 trang )

Chapter 10
266
to receive notifications about a device interface class, and classguid is the GUID
of the device interface class (myGuid in the example).
When the WM_DEVICECHANGE messages are no longer of interest, the
application should call UnregisterDeviceNotification as described later in this
chapter.
8$ Definitions
Friend Const DBT_DEVTYP_DEVICEINTERFACE As Int32 = 5
Friend Const DEVICE_NOTIFY_WINDOW_HANDLE As Int32 = 0
Friend Const DIGCF_PRESENT As Int32 = 2
Friend Const DIGCF_DEVICEINTERFACE As Int32 = &H10
Friend Const WM_DEVICECHANGE As Int32 = &H219
<StructLayout(LayoutKind.Sequential)> _
Friend Class DEV_BROADCAST_DEVICEINTERFACE
Friend dbcc_size As Int32
Friend dbcc_devicetype As Int32
Friend dbcc_reserved As Int32
Friend dbcc_classguid As Guid
Friend dbcc_name As Int16
End Class
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Shared Function RegisterDeviceNotification _
(ByVal hRecipient As IntPtr, _
ByVal NotificationFilter As IntPtr, _
ByVal Flags As Int32) _
As IntPtr
End Function
Table 10-3: These functions enable an application to request to receive or stop
receiving notifications about device attachment and removal.
#2+(WPEVKQP & 2WTRQUG


RegisterDeviceNotification user32 Request to receive device notifications
UnregisterDeviceNotification user32 Request to stop receiving device
notifications
Detecting Devices
267
Use
Place this statement in the _Load event for the form that will receive
device-change messages:
frmMy = Me
Dim devBroadcastDeviceInterface As DEV_BROADCAST_DEVICEINTERFACE = _
New DEV_BROADCAST_DEVICEINTERFACE()
Dim devBroadcastDeviceInterfaceBuffer As IntPtr
Dim deviceNotificationHandle As IntPtr
Dim size As Int32
' frmMy is the form that will receive device-change messages.
Friend frmMy As frmMain
size = Marshal.SizeOf(devBroadcastDeviceInterface)
devBroadcastDeviceInterface.dbcc_size = size
devBroadcastDeviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE
devBroadcastDeviceInterface.dbcc_reserved = 0
devBroadcastDeviceInterface.dbcc_classguid = myGuid
devBroadcastDeviceInterfaceBuffer = Marshal.AllocHGlobal(size)
Marshal.StructureToPtr _
(devBroadcastDeviceInterface, _
devBroadcastDeviceInterfaceBuffer, _
True)
deviceNotificationHandle = RegisterDeviceNotification _
(frmMy.Handle, _
devBroadcastDeviceInterfaceBuffer, _
DEVICE_NOTIFY_WINDOW_HANDLE)

Marshal.FreeHGlobal (devBroadcastDeviceInterfaceBuffer)
8%
Definitions
internal const Int32 DBT_DEVTYP_DEVICEINTERFACE = 5;
internal const Int32 DEVICE_NOTIFY_WINDOW_HANDLE = 0;
internal const Int32 DIGCF_PRESENT = 2;
internal const Int32 DIGCF_DEVICEINTERFACE = 0X10;
internal const Int32 WM_DEVICECHANGE = 0X219;
Chapter 10
268
[ StructLayout( LayoutKind.Sequential ) ]
internal class DEV_BROADCAST_DEVICEINTERFACE
{
internal Int32 dbcc_size;
internal Int32 dbcc_devicetype;
internal Int32 dbcc_reserved;
internal Guid dbcc_classguid;
internal Int16 dbcc_name;
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern IntPtr RegisterDeviceNotification
(IntPtr hRecipient,
IntPtr NotificationFilter,
Int32 Flags);
Use
Place this statement in the _Load event for the form that will receive
device-change messages:
frmMy = this;
DEV_BROADCAST_DEVICEINTERFACE devBroadcastDeviceInterface =
new DEV_BROADCAST_DEVICEINTERFACE();

IntPtr devBroadcastDeviceInterfaceBuffer;
IntPtr deviceNotificationHandle;
Int32 size = 0;
// frmMy is the form that will receive device-change messages.
internal frmMain frmMy;
size = Marshal.SizeOf( devBroadcastDeviceInterface );
devBroadcastDeviceInterface.dbcc_size = size;
devBroadcastDeviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
devBroadcastDeviceInterface.dbcc_reserved = 0;
devBroadcastDeviceInterface.dbcc_classguid = myGuid;
devBroadcastDeviceInterfaceBuffer = Marshal.AllocHGlobal( size );
Marshal.StructureToPtr
( devBroadcastDeviceInterface,
devBroadcastDeviceInterfaceBuffer,
true );
Detecting Devices
269
deviceNotificationHandle = RegisterDeviceNotification
( frmMy.Handle,
devBroadcastDeviceInterfaceBuffer,
DEVICE_NOTIFY_WINDOW_HANDLE );
Marshal.FreeHGlobal( devBroadcastDeviceInterfaceBuffer );
&GVCKNU
The device-notification functions use several constants defined in header files.
The Marshal.SizeOf method retrieves the size of the
DEV_BROADCAST_DEVICEINTERFACE structure for passing to the
structure’s dbcc_size member.
Marshal.AllocGlobal allocates memory for a buffer that will hold the
DEV_BROADCAST_DEVICEINTERFACE structure.
The Marshal.StructureToPointer method copies the structure into the buffer.

The application is then ready to call RegisterDeviceNotification, passing the
handle to a form that will receive the notifications and a pointer to the buffer.
When finished using devBroadcastDeviceInterfaceBuffer, the application can
use Marshal.FreeHGlobal to free the memory allocated for it by AllocHGlobal.
%CRVWTKPI&GXKEG%JCPIG/GUUCIGU
The WndProc function processes messages received by a form, dialog box, or
other window.
8$ Protected Overrides Sub WndProc(ByRef m As Message)
If m.Msg = WM_DEVICECHANGE Then
OnDeviceChange(m)
End If
MyBase.WndProc(m)
End Sub
Chapter 10
270
8% protected override void WndProc( ref Message m )
{
if ( m.Msg == WM_DEVICECHANGE )
{
OnDeviceChange( m );
}
base.WndProc( ref m );
}
On receiving a WM_DEVICECHANGE message, the method calls the appli-
cation’s OnDeviceChange method, which can examine the message and take
action, and then passes the message to the WndProc method in the form’s base
class.
4GCFKPI&GXKEG%JCPIG/GUUCIGU
A device-change message contains two pointers: lParam and wParam. The
wParam property is a code that indicates device arrival, removal, or another

event. The lParam property is a device management structure. There are several
defined types of device-management structures, but each begins with the same
DEV_BROADCAST_HDR structure. The structure’s dbch_devicetype mem-
ber indicates the type of device-management structure that lParam points to.
If dbch_devicetype = DBT_DEVTYP_DEVICEINTERFACE, the structure is
a DEV_BROADCAST_DEVICEINTERFACE and the application can
retrieve the complete structure, read the device path name in the dbcc_name
member, and compare the name to the device path name of the device of inter-
est.
This example detects device arrival and removal:
8$ Definitions
Friend Const DBT_DEVICEARRIVAL As Int32 = &H8000
Friend Const DBT_DEVICEREMOVECOMPLETE As Int32 = &H8004
Detecting Devices
271
Use
Friend Sub OnDeviceChange(ByVal m as Message)
If (m.WParam.ToInt32 = DBT_DEVICEARRIVAL) Then
' Find out if the device path name matches wParam.
' If yes, perform any tasks required on device arrival.
ElseIf (m.WParam.ToInt32 = DBT_DEVICEREMOVECOMPLETE) Then
' Find out if the device path name matches wParam.
' If yes, perform any tasks required on device removal.
End If
End Sub
8%
Definitions
internal const Int32 DBT_DEVICEARRIVAL = 0X8000;
internal const Int32 DBT_DEVICEREMOVECOMPLETE = 0X8004;
Use

internal void OnDeviceChange( Message m )
{
if ( ( m.WParam.ToInt32() == DBT_DEVICEARRIVAL ) )
{
// Find out if the device path name matches wParam.
// If yes, perform any tasks required on device arrival.
}
else if ( ( m.WParam.ToInt32() == DBT_DEVICEREMOVECOMPLETE ) )
{
// Find out if the device path name matches wParam.
// If yes, perform any tasks required on device removal.
}
}
4GVTKGXKPIVJG&GXKEG2CVJ0COGKPVJG/GUUCIG
If the message indicates a device arrival or removal (or another event of inter-
est), the application can investigate further.
In the structure that lParam points to, if dbch_devicetype contains
DBT_DEVTYP_DEVICEINTERFACE, the event relates to a device interface.
Chapter 10
272
Thus lParam contains a DEV_BROADCAST_DEVICEINTERFACE struc-
ture, which begins with a DEV_BROADCAST_HDR structure. The
dbcc_name member contains the device path name of the device the message
applies to. The application can compare this device path name with the device
path name of the device of interest. On a match, the application can take any
desired actions.
This example code uses two declarations for the
DEV_BROADCAST_DEVICEINTERFACE structure. The first declaration,
presented earlier, is used when calling RegisterDeviceNotification. A second
declaration, DEV_BROADCAST_DEVICEINTERFACE_1, enables marshal-

ing the data in dbcc_name and classguid.
8$ Definitions
<StructLayout(LayoutKind.Sequential)> _
Friend Class DEV_BROADCAST_HDR
Friend dbch_size As Int32
Friend dbch_devicetype As Int32
Friend dbch_reserved As Int32
End Class
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Friend Class DEV_BROADCAST_DEVICEINTERFACE_1
Friend dbcc_size As Int32
Friend dbcc_devicetype As Int32
Friend dbcc_reserved As Int32
<MarshalAs(UnmanagedType.ByValArray, _
ArraySubType:=UnmanagedType.U1, _
SizeConst:=16)> _
Friend dbcc_classguid() As Byte
<MarshalAs(UnmanagedType.ByValArray,
sizeconst:=255)> _
Friend dbcc_name() As Char
End Class
Use
Dim devBroadcastDeviceInterface As New DEV_BROADCAST_DEVICEINTERFACE_1()
Dim devBroadcastHeader As New DEV_BROADCAST_HDR()
Marshal.PtrToStructure(m.LParam, devBroadcastHeader)
Detecting Devices
273
If (devBroadcastHeader.dbch_devicetype = DBT_DEVTYP_DEVICEINTERFACE) Then
Dim stringSize As Int32 =
Convert.ToInt32((devBroadcastHeader.dbch_size - 32) / 2)

Array.Resize(devBroadcastDeviceInterface.dbcc_name, stringSize)
Marshal.PtrToStructure (m.LParam, devBroadcastDeviceInterface)
Dim deviceNameString As _
New String(devBroadcastDeviceInterface.dbcc_name, 0, stringSize)
If (String.Compare (deviceNameString, devicePathName, True) = 0) Then
'The name matches.
Else
'It's a different device.
End If
End If
8%
Definitions
[ StructLayout( LayoutKind.Sequential ) ]
internal class DEV_BROADCAST_HDR
{
internal Int32 dbch_size;
internal Int32 dbch_devicetype;
internal Int32 dbch_reserved;
}
[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Auto ) ]
internal class DEV_BROADCAST_DEVICEINTERFACE_1
{
internal Int32 dbcc_size;
internal Int32 dbcc_devicetype;
internal Int32 dbcc_reserved;
[ MarshalAs( UnmanagedType.ByValArray,
ArraySubType=UnmanagedType.U1,
SizeConst=16 ) ]
internal Byte[] dbcc_classguid;
[MarshalAs(UnmanagedType.ByValArray,

SizeConst = 255)]
internal Char[] dbcc_name;
}
Chapter 10
274
Use
DEV_BROADCAST_DEVICEINTERFACE_1 devBroadcastDeviceInterface =
new DEV_BROADCAST_DEVICEINTERFACE_1();
DEV_BROADCAST_HDR devBroadcastHeader = new DEV_BROADCAST_HDR();

Marshal.PtrToStructure( m.LParam, devBroadcastHeader );
if ( ( devBroadcastHeader.dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE ) )
{
Int32 stringSize = Convert.ToInt32( ( devBroadcastHeader.dbch_size - 32 ) / 2 );

Array.Resize(ref devBroadcastDeviceInterface.dbcc_name, stringSize);

Marshal.PtrToStructure( m.LParam, devBroadcastDeviceInterface );
String DeviceNameString =
new String(devBroadcastDeviceInterface.dbcc_name, 0, stringSize);

if ( ( String.Compare( deviceNameString, devicePathName, true ) == 0 ) )
{
// The name matches.;
}
else
{
// It’s a different device.;
}
}

&GVCKNU
MarshalPtrToStructure copies the message’s lParam property into a
DEV_BROADCAST_HDR structure. If the message relates to a device inter-
face, the application retrieves the device path name.
The name is in a Char array in unmanaged memory. The application needs to
retrieve the array and convert it to a String.
The dbch_size member of DEV_BROADCAST_HDR contains the number of
bytes in the complete DEV_BROADCAST_DEVICEINTERFACE structure.
To obtain the number of characters in the device path name stored in
dbch_name, subtract the 32 bytes in the structure that are not part of the name
and divide by 2 because there are 2 bytes per character.
Detecting Devices
275
The Array.Resize method trims dbcc_name to the size of the device path name.
Marshal.PtrToStructure copies the data from the unmanaged block in lParam
to the devBroadcastDeviceInterface structure. The Char array containing the
device path name is then stored as a String in deviceNameString, and the
String.Compare method looks for a match.
5VQRRKPI&GXKEG0QVKHKECVKQPU
To stop receiving device notifications, an application calls UnregisterDeviceNo-
tification.
8$ Definitions
<DllImport("user32.dll", SetLastError:=True)> _
Shared Function UnregisterDeviceNotification _
(ByVal Handle As IntPtr) _
As Boolean
End Function
Use
UnregisterDeviceNotification(deviceNotificationHandle)
8%

Definitions
[DllImport("user32.dll", SetLastError = true)]
internal static extern Boolean UnregisterDeviceNotification(IntPtr Handle);
Use
UnregisterDeviceNotification( deviceNotificationHandle );

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×