duilib监测串口插拔

监测串口插拔原理:当设备被插入/拔出的时候,windows会向每个窗体发送WM_DEVICECHANGE消息,当消息的wParam 值等于 DBT_DEVICEARRIVAL时,表示设备被插入并且已经可用;如果wParam值等于DBT_DEVICEREMOVECOMPLETE,表示设备已经被移出。它们的lParam都指向一个 _DEV_BROADCAST_HDR 结构体(该结构体位于dbt.h头文件中):

struct _DEV_BROADCAST_HDR {     /* */
    DWORD       dbch_size;
    DWORD       dbch_devicetype;
    DWORD       dbch_reserved;
};

我们还需要区别设备类型,结构体_DEV_BROADCAST_HDR的成员dbch_devicetype指的是设备类型,在dbt.h头文件中发现有如下设备类型:

...

#define DBT_DEVTYP_OEM                  0x00000000  // oem-defined device type
#define DBT_DEVTYP_DEVNODE              0x00000001  // devnode number
#define DBT_DEVTYP_VOLUME               0x00000002  // logical volume
#define DBT_DEVTYP_PORT                 0x00000003  // serial, parallel
#define DBT_DEVTYP_NET                  0x00000004  // network resource

#if(WINVER >= 0x040A)
#define DBT_DEVTYP_DEVICEINTERFACE      0x00000005  // device interface class
#define DBT_DEVTYP_HANDLE               0x00000006  // file system handle
#endif /* WINVER >= 0x040A */

#if(WINVER >= _WIN32_WINNT_WIN7)
#define DBT_DEVTYP_DEVINST              0x00000007  // device instance

...

当有串口插拔时,dbch_devicetype成员变量就是DBT_DEVTYP_PORT宏定义的值。

我们还需要知道插拔串口的一些信息,比如串口名,定义在_DEV_BROADCAST_PORT_A或_DEV_BROADCAST_PORT_W结构体中,可以根据程序的编码选择相对应的结构体,如下:

typedef struct _DEV_BROADCAST_PORT_A {
    DWORD       dbcp_size;
    DWORD       dbcp_devicetype;
    DWORD       dbcp_reserved;
    char        dbcp_name[1]; // 串口名
} DEV_BROADCAST_PORT_A, *PDEV_BROADCAST_PORT_A;

typedef struct _DEV_BROADCAST_PORT_W {
    DWORD       dbcp_size;
    DWORD       dbcp_devicetype;
    DWORD       dbcp_reserved;
    wchar_t     dbcp_name[1]; // 串口名
} DEV_BROADCAST_PORT_W, DBTFAR *PDEV_BROADCAST_PORT_W;

#ifdef UNICODE
typedef DEV_BROADCAST_PORT_W     DEV_BROADCAST_PORT;
typedef PDEV_BROADCAST_PORT_W    PDEV_BROADCAST_PORT;
#else
typedef DEV_BROADCAST_PORT_A     DEV_BROADCAST_PORT;
typedef PDEV_BROADCAST_PORT_A    PDEV_BROADCAST_PORT;
#endif

结合duilib的消息机制,我这里是公有继承WindowImplBase类,重写HandleCustomMessage函数。

部分实现代码

LRESULT CMainWnd::HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    switch (uMsg)
    {
    case WM_DEVICECHANGE:
    {
        PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam;
        switch (wParam)
        {
        /*
        ** 串口插入
        */
        case DBT_DEVICEARRIVAL:
        {
            /*
            ** 如果插入的设备类型是串口
            */
            if (lpdb->dbch_devicetype == DBT_DEVTYP_PORT)
            {
                PDEV_BROADCAST_PORT lpdbv = (PDEV_BROADCAST_PORT)lpdb;
                
                /*
                ** 获取串口名
                */
                CDuiString strPortName = lpdbv->dbcp_name;
                CDuiString strTipValue = _T("串口号 ");
                strPortName = strTipValue + strPortName;
                strPortName = strPortName + _T(" 被插入");
                
                /*
                ** 以提示框的形式显示
                */
                CMsgBoxWnd::MsgBox(GetHWND(), _T("提示"), strPortName);
            }
        }
            break;
        /*
        ** 串口拔出
        */
        case DBT_DEVICEREMOVECOMPLETE:
        {
            /*
            ** 如果被拔出的设备类型是串口
            */
            if (lpdb->dbch_devicetype == DBT_DEVTYP_PORT)
            {
                PDEV_BROADCAST_PORT lpdbv = (PDEV_BROADCAST_PORT)lpdb;
                
                /*
                ** 获取串口名
                */
                CDuiString strPortName = lpdbv->dbcp_name;
                CDuiString strTipValue = _T("串口号 ");
                strPortName = strTipValue + strPortName;
                strPortName = strPortName + _T(" 被拔出");
                
                /*
                ** 以提示框的形式显示
                */
                CMsgBoxWnd::MsgBox(GetHWND(), _T("提示"), strPortName);
            }
        }
            break;
        case DBT_DEVNODES_CHANGED:
            break;
        default:
            break;
        }
    }
    break;
    default:
    break;
    }

    return __super::HandleCustomMessage(uMsg, wParam, lParam, bHandled);
}

运行,看效果,串口设备插入的时候:

串口设备拔出的时候:

本人水平有限,如有错误,麻烦指出。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值