使用IMessageFilter不能在Windows 7 64位(C#,.net 2.0)下工作

问题描述:

我们正在研究USB设备程序。以下代码片段是我的UsbComponent类。 它可以在Windows XP或Windows 64 32位下正常工作。 但是在Windows 7 64bit下,无论何时插入/移除我们的USB设备,PreFilterMessage都不会进入。我错过了什么使下面的代码在Windows 7 64位下工作?使用IMessageFilter不能在Windows 7 64位(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; 
     } 
} 

设备驱动程序负责广播WM_DEVICECHANGE。请确保您有该设备的更新驱动程序,并验证该设备支持Windows 7

+0

我改变了代码,使用形式的WndProc得到WM_DEVICECHANGE,它只是正常工作,但在使用组件时IMessageFilter没有。我猜设备驱动程序确实在Windows 7 64bit下广播WM_DEVICECHANGE。 – Allex 2010-08-03 03:11:23

代码项目的文章指出,这是不可能的处理WM_DEVICECHANGE消息与IMessageFilter接口方面,它建议使用WndProc方法是可用在System.Windows.Forms控件。

以下班级是我班内的私人班级,它执行我从邮件中需要的工作,然后发起一个活动来告诉我有关结果。我必须在我的课堂内创建一个对象并处理它的事件。

此代码检测插入或移除HID类USB设备。

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