2010-08-03 53 views
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; 
     } 
} 

回答

0

設備驅動程序負責廣播WM_DEVICECHANGE。請確保您有該設備的更新驅動程序,並驗證該設備支持Windows 7

+0

我改變了代碼,使用形式的WndProc得到WM_DEVICECHANGE,它只是正常工作,但在使用組件時IMessageFilter沒有。我猜設備驅動程序確實在Windows 7 64bit下廣播WM_DEVICECHANGE。 – Allex 2010-08-03 03:11:23

1

代碼項目的文章指出,這是不可能的處理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); 
    } 
}