2010-08-03 3 views
0

Nous travaillons sur un programme de périphérique USB. L'extrait de code suivant est ma classe UsbComponent. Cela fonctionne très bien sous Windows XP ou même Windows 64 32bit. Mais sous Windows 7 64bit, PreFilterMessage n'est jamais saisi chaque fois que je branche/enlève notre périphérique USB. Est-ce que j'ai manqué quelque chose pour faire du code suivant fonctionnant sous Windows 7 64bit?L'utilisation de IMessageFilter ne fonctionne pas sous Windows 7 64bit (C#, .net 2.0)

using System; 
using System.ComponentModel; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Text; 
using System.Windows.Forms; 

public partial class UsbComponent : Component, IMessageFilter { 
     private const int WM_DEVICECHANGE = 0x219; 

     public UsbComponent() { 
     InitializeComponent(); 
     Application.AddMessageFilter(this); 
     } 

     public UsbComponent(IContainer container) { 
     container.Add(this); 
     InitializeComponent(); 
     Application.AddMessageFilter(this); 
     } 

     bool IMessageFilter.PreFilterMessage(ref Message m) { 
     if(m.Msg == WM_DEVICECHANGE) { 
      MessageBox.Show("device changed"); 
      return true; 
     } 
     return false; 
     } 
} 

Répondre

0

Il est de la responsabilité du pilote de périphérique pour diffuser WM_DEVICECHANGE. Assurez-vous que vous avez les pilotes mis à jour pour ce périphérique et vérifiez que l'appareil prend en charge Windows 7

+0

j'ai changé le code à utiliser WndProc de formulaire pour obtenir WM_DEVICECHANGE, et il fonctionne très bien, mais pas lors de l'utilisation IMessageFilter dans le composant. Je suppose que le pilote de périphérique a diffusé WM_DEVICECHANGE sous Windows 7 64bit. – Allex

1

Un article dans le projet de code a déclaré qu'il est impossible de gérer WM_DEVICECHANGE messages avec IMessageFilter Interface, il suggère d'utiliser la méthode WndProc qui est disponible dans System.Windows.Forms contrôles.

La classe suivante est une classe privée dans ma classe, elle effectue le travail dont j'ai besoin à partir des messages, puis elle monte un événement pour me parler du résultat. Je dois en faire un objet dans ma classe et gérer son événement.

Ce code détecte l'insertion ou le retrait de périphériques USB de classe HID.

private class MyControl : Form, IMessageFilter 
{ 
    Guid InterfaceClassGuid = new Guid(0x4d1e55b2, 0xf16f, 0x11cf, 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30); 

    //Constant definitions for certain WM_DEVICECHANGE messages 
    private const uint WM_DEVICECHANGE = 0x0219; 
    private const uint DBT_DEVICEARRIVAL = 0x8000; 
    private const uint DBT_DEVICEREMOVEPENDING = 0x8003; 
    private const uint DBT_DEVICEREMOVECOMPLETE = 0x8004; 
    private const uint DBT_CONFIGCHANGED = 0x0018; 

    //Other constant definitions 
    private const uint DBT_DEVTYP_DEVICEINTERFACE = 0x05; 
    private const uint DEVICE_NOTIFY_WINDOW_HANDLE = 0x00; 

    private struct DEV_BROADCAST_DEVICEINTERFACE 
    { 
     internal uint dbcc_size;   //DWORD 
     internal uint dbcc_devicetype;  //DWORD 
     internal uint dbcc_reserved;  //DWORD 
     internal Guid dbcc_classguid;  //GUID 
     internal char[] dbcc_name;   //TCHAR array 
    } 

    //Need this function for receiving all of the WM_DEVICECHANGE messages. See MSDN documentation for 
    //description of what this function does/how to use it. Note: name is remapped "RegisterDeviceNotificationUM" to 
    //avoid possible build error conflicts. 
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
    private static extern IntPtr RegisterDeviceNotification(
     IntPtr hRecipient, 
     IntPtr NotificationFilter, 
     uint Flags); 

    public MyControl() 
    { 
     //Register for WM_DEVICECHANGE notifications. This code uses these messages to detect plug and play connection/disconnection events for USB devices 
     DEV_BROADCAST_DEVICEINTERFACE DeviceBroadcastHeader = new DEV_BROADCAST_DEVICEINTERFACE(); 
     DeviceBroadcastHeader.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; 
     DeviceBroadcastHeader.dbcc_size = (uint)Marshal.SizeOf(DeviceBroadcastHeader); 
     DeviceBroadcastHeader.dbcc_reserved = 0; //Reserved says not to use... 
     DeviceBroadcastHeader.dbcc_classguid = InterfaceClassGuid; 

     //Need to get the address of the DeviceBroadcastHeader to call RegisterDeviceNotification(), but 
     //can't use "&DeviceBroadcastHeader". Instead, using a roundabout means to get the address by 
     //making a duplicate copy using Marshal.StructureToPtr(). 
     IntPtr pDeviceBroadcastHeader = IntPtr.Zero; //Make a pointer. 
     pDeviceBroadcastHeader = Marshal.AllocHGlobal(Marshal.SizeOf(DeviceBroadcastHeader)); //allocate memory for a new DEV_BROADCAST_DEVICEINTERFACE structure, and return the address 
     Marshal.StructureToPtr(DeviceBroadcastHeader, pDeviceBroadcastHeader, false); //Copies the DeviceBroadcastHeader structure into the memory already allocated at DeviceBroadcastHeaderWithPointer 
     RegisterDeviceNotification(this.Handle, pDeviceBroadcastHeader, DEVICE_NOTIFY_WINDOW_HANDLE); 
    } 

    public event EventHandler DeviceConnected; 

    protected override void WndProc(ref Message m) 
    { 
     if (m.Msg == WM_DEVICECHANGE) 
     { 
      if (((int)m.WParam == DBT_DEVICEARRIVAL) || ((int)m.WParam == DBT_DEVICEREMOVEPENDING) || ((int)m.WParam == DBT_DEVICEREMOVECOMPLETE) || ((int)m.WParam == DBT_CONFIGCHANGED)) 
      { 
       //Rise the event, more processing is needed to check for a certain device. 
       DeviceConnected(this, null); 
      } 
     } 

     base.WndProc(ref m); 
    } 
} 
Questions connexes