首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用在64位windows 7 (C#、.net 2.0)下不起作用的IMessageFilter

使用在64位windows 7 (C#、.net 2.0)下不起作用的IMessageFilter
EN

Stack Overflow用户
提问于 2010-08-03 09:51:28
回答 2查看 2.1K关注 0票数 0

我们正在开发一个USB设备程序。下面的代码片段是我的UsbComponent类。它在windows XP甚至windows6432位下都能正常工作。但是在windows764位操作系统下,每当我插入/移除我们的USB设备时,PreFilterMessage都不会进入。我是不是错过了让下面的代码在windows7 64位下工作的地方?

代码语言:javascript
复制
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;
      }
}
EN

回答 2

Stack Overflow用户

发布于 2011-08-17 07:18:27

代码项目中的一篇文章指出,使用IMessageFilter接口处理WM_DEVICECHANGE消息是不可能的,建议使用System.Windows.Forms控件中提供的WndProc方法。

下面的类是我的类中的一个私有类,它从消息中执行我需要的工作,然后引发一个事件来告诉我结果。我必须在我的类中创建它的一个对象并处理它的事件。

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

代码语言:javascript
复制
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);
    }
}
票数 1
EN

Stack Overflow用户

发布于 2010-08-03 10:20:24

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3393093

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档