WM_DEVICECHANGE消息的详细用法

WM_DEVICECHANGE消息是一个当电脑插入或者拔出其他设备时,发出的一个消息(如:usb,相机等)下面程序通过设备的GUID对WM_DEVICECHANGE进行详细操作,使其能获取更准确的消息。
创作不易。转载请附上原文链接

using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace M400C
{
    /// 
    /// Interaction logic for MainWindow.xaml
    /// 
    public partial class MainWindow : Window
    {
        const int WM_DEVICECHANGE = 0x0219;
        const int DBT_DEVICEARRIVAL = 0x8000;
        const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
        const int DBT_DEVTYP_DEVICEINTERFACE = 0x00000005;
        const int DEVICE_NOTIFY_WINDOW_HANDLE = 0;
        private static readonly Guid GuidDevinterfaceUSBDevice = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED");
        [StructLayout(LayoutKind.Sequential)]
        internal class DEV_BROADCAST_HDR
        {
            public int dbch_size;
            public int dbch_devicetype;
            public int dbch_reserved;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct DEV_BROADCAST_DEVICEINTERFACE
        {
            public int dbcc_size;
            public int dbcc_devicetype;
            public int dbcc_reserved;
            public Guid dbcc_classguid;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
            public string dbcc_name;
        }

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr RegisterDeviceNotification(IntPtr IntPtr, IntPtr NotificationFilter, Int32 Flags);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern uint UnregisterDeviceNotification(IntPtr hHandle);

        public IntPtr hMainWnd = IntPtr.Zero;
        private static IntPtr notificationHandle = IntPtr.Zero;

        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += MainWindow_Loaded;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            hMainWnd = new WindowInteropHelper(this).Handle;
            HwndSource hwnd = HwndSource.FromHwnd(hMainWnd);
            if (null != hwnd)
            {
                hwnd.AddHook(new HwndSourceHook(this.WndProc));
            }
            RegisterUsbDeviceNotification(hMainWnd);
        }

        protected IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            if (msg == WM_DEVICECHANGE)
            {
                if (lParam != IntPtr.Zero)
                {
                    string sDeviceAction = string.Empty;
                    sDeviceAction = ((int)wParam == DBT_DEVICEARRIVAL) ? " insert!" : " remove!";
                    MessageBox.Show(sDeviceAction);

                    DEV_BROADCAST_DEVICEINTERFACE pdbch = (DEV_BROADCAST_DEVICEINTERFACE)Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_DEVICEINTERFACE));
                    string sHardwareId = pdbch.dbcc_name;
                    sHardwareId.ToUpper();
//这可以依据pdbch.dbcc_name判断是什么usb设备里面的什么设备,
                    if((SHardwareID.Contains("设备的PID,VID如:"VID_0951&PID_1666"))
                    {
                       //表明是这种类型的设备在插拔
                    }
                }
            }

            return IntPtr.Zero;
        }

        private void RegisterUsbDeviceNotification(IntPtr windowHandle)
        {
            DEV_BROADCAST_DEVICEINTERFACE deviceInterface = new DEV_BROADCAST_DEVICEINTERFACE();
            int size = Marshal.SizeOf(deviceInterface);
            deviceInterface.dbcc_size = size;
            deviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
            deviceInterface.dbcc_classguid = GuidDevinterfaceUSBDevice;
            IntPtr buffer = default(IntPtr);
            buffer = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(deviceInterface, buffer, true);
            notificationHandle = RegisterDeviceNotification(hMainWnd, buffer, DEVICE_NOTIFY_WINDOW_HANDLE);
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            if (notificationHandle != IntPtr.Zero)
            {
                UnregisterDeviceNotification(notificationHandle);
                notificationHandle = IntPtr.Zero;
            }
        }
    }
}

下面是微软官网的链接
https://docs.microsoft.com/en-us/windows/win32/api/dbt/ns-dbt-dev_broadcast_deviceinterface_a

你可能感兴趣的:(WPF,c#,wpf,c++,windows)