• C# 上位机的USB设备拔插检测


      我们做USB通信时,通信成功后,往往要检测USB设备的拔插状态,这里就USB拔插进行一下说明。

      参考:https://www.imooc.com/article/17438

      先说明一下,我这里只是用C#写上位机的自定义USB设备的检测,是调用window的DLL来实现USB设备通信的,具体通信过程说明,我会在后期补上。

      要实现USB插拔检测,就不得不说到WM_DEVICECHANGE 消息了,当设备被插入/拔出的时候,WINDOWS会向每个窗体发送WM_DEVICECHANGE 消息,而WM_DEVICECHANGE

    消息则是由窗口通过其WindowProc函数接收此消息

      Winform中WndProc 函数作用:主要用在拦截并处理系统消息和自定义消息。比如:windows程序会产生很多消息,比如你单击鼠标,移动窗口都会产生消息。这个函数就是默认的消息处

    理函数。你可以重载这个函数来制定自己的消息处理流程.在Winform程序中,可以重写WndProc函数,来捕捉所有发生的窗口消息。这样,我们就可以"篡改"传入的消息,而人为的让窗口改

    变行为。我们用C#实现检测U盘插拔的功能,是用重写C# WndProc函数来做到的。

      至于怎么操作,我们下面再说明,现在我们先来看一下微软对WindowProc函数的解析。

    WindowProc函数原型:

    LRESULT CALLBACK WindowProc(HWND   hwnd,     // handle to window 窗口句柄
                                UINT   uMsg,     // WM_DEVICECHANGE WM_DEVICECHANGE标识符
                                WPARAM wParam,   // device-change event 发生的事件值,不同的值有着不同的意义,下面会说到
                                LPARAM lParam ); // event-specific data 指向包含特定于事件的数据的结构的指针,其格式取决于wParam参数的值

    函数返回值:正确返回TRUE以授予请求,否则返回BROADCAST_QUERY_DENY以拒绝请求。

    wParam值的具体含义:

      
    含义
    DBT_CONFIGCHANGECANCELED
    0x0019
    更改当前配置(停靠或取消停靠)的请求已被取消。
    DBT_CONFIGCHANGED
    0x0018处
    由于停靠或取消停靠,当前配置已更改。
    DBT_CUSTOMEVENT
    0x8006
    发生了自定义事件。
    DBT_DEVICEARRIVAL
    为0x8000
    已插入设备或介质,现已可用。
    DBT_DEVICEQUERYREMOVE
    在0x8001
    要求许可删除设备或媒体。任何应用程序都可以拒绝此请求并取消删除。
    DBT_DEVICEQUERYREMOVEFAILED
    0x8002
    已取消删除设备或介质的请求。
    DBT_DEVICEREMOVECOMPLETE
    0x8004
    已删除设备或介质。
    DBT_DEVICEREMOVEPENDING
    0x8003
    即将移除设备或介质。不能否认。
    DBT_DEVICETYPESPECIFIC
    0x8005
    发生了特定于设备的事件。
    DBT_DEVNODES_CHANGED
    0x0007
    已在系统中添加或删除设备。
    DBT_QUERYCHANGECONFIG
    0x0017
    请求权限更改当前配置(停靠或取消停靠)。
    DBT_USERDEFINED
    为0xFFFF
    此消息的含义是用户定义的。

      看到这里你可能对怎用WM_DEVICECHANGE 消息实现USB拔插检测有一个初步了解了,具体怎么实现,下面我用个例子来说明。

    这里我先说明一下思路:

      1.重写WndProc 函数捕捉所有发生的窗口消息,重写的主要内容为2、3、4;

      2.当USB拔插时 WM_DEVICECHANGE 消息会传递到 WndProc 函数,也就是uMsg这个值;

      3.第二步是window自动完成的,这里我们要做的是读出wParam的值,根据这个值判断触发了什么对应的事件;

      4.根据第三步,判断出相应的操作后,我们就可以根据触发的对应事件,编写执行不同的操作代码了;

      5.把这个重写函数放在 private void Form1_Load(object sender, EventArgs e) { } 函数后面,不用用户去调用,在你运行窗体后,系统会自动调用的。

      重写WndProc 函数具体例程代码如下:

     /*  ======================USB 插拔检测===========================    */
            protected override void WndProc(ref Message m)
            {
                //Console.WriteLine(m.WParam.ToInt32());    //打印程序检测到的变化信息
                try
                {
                    //检测到USB口发生了变化,这里USB口变化时wParam的值是7,表示系统中添加或者删除了设备
                    if (m.WParam.ToInt32() == 7 ) 
                    {
                        UsBMethod(0);       //检测到USB口有变化时重新连接一次自己要检测的设备,连接不成功则可以判断设备已断开(个函数是USB连接函数)
    
                        if (flag == 0)    //没找到设备处理事件,我这里 flag=0 表示设备没连接成功
                        {                                        
                            Dispost();     //关闭设备,该函数的作用是关闭USB设备的连接
                            MessageBox.Show(" USB 已断开!");
                        }
                        else
                        {
                           //这里可以添加设备没有断开的处理代码
                        }
                    }
    
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);  //异常处理函数
                }
                base.WndProc(ref m);  //这个是windos的异常处理,一定要添加,不然会运行不了
            }

      好啦,到这里重写WndProc 函数就完成了,注意:要把这个函数放在 private void Form1_Load(object sender, EventArgs e) { } 函数后面就可以了,不用用户去调用,打开程序时系统就会自动后台运行了

     
    
    

      
  • 相关阅读:
    朴素贝叶斯小结
    Logistic回归小结
    线性回归小结
    Zabbix使用采坑记录
    cookie与session测试关注点
    JMeter笔记十二:逻辑控制器之事务控制器、模块控制器和吞吐量控制器
    JMeter笔记十一:逻辑控制器之随机控制器、随机顺序控制器和交替控制器
    JMeter笔记十:逻辑控制器之ForEach控制器
    JMeter笔记九:逻辑控制器之循环控制器、While控制器
    JMeter笔记八:逻辑控制器之如果(If)控制器、仅一次控制器、Switch控制器
  • 原文地址:https://www.cnblogs.com/xingboy/p/9845381.html
Copyright © 2020-2023  润新知