在串口编程中经常需要知道串口号,用来配置串口,可是没有好的办法,只能进到设备管理器中去看,那么如何能够实现软件的自动检测串口号,并且可支持热插拔检测那?

下面将讲述两种方法来实现这种效果:一种是遍历设备列表中的所有串口0-255,二是通过读去注册表来实现检测

在这篇文章中将只讲述循环遍历方法的实现,在下一篇文章中将讲述利用注册表方法的实现

---------------------------------------------------

第一种方法是一种比较简单也比较笨的方法,对于每一个串口一个一个的去试,试完了也就知道了,计算机一般支持0-255即256个串口,可是利用CreateFile创建串口,只能成功创建COM0-COM9串口设备,而COM10及以上的串口创建CreateFile就会返回-1,因为10及以上已经超出的设备的命名规范,需要使用\$device\COM10方式,作为参数传递给CreateFile。

You   can   use   paths   longer   than   MAX_PATH   characters   by   calling   the   wide   (W)   version   of   CreateFile   and   prepending   "\\?\"   to   the   path.   The   "\\?\"   tells   the   function   to   turn   off   path   parsing.   This   lets   you   use   paths   that   are   nearly   32,000   Unicode   characters   long.   However,   each   component   in   the   path   cannot   be   more   than   MAX_PATH   characters   long.   You   must   use   fully-qualified   paths   with   this   technique.   This   also   works   with   UNC   names.   The   "\\?\"   is   ignored   as   part   of   the   path.   For   example,   "\\?\C:\myworld\private"   is   seen   as   "C:\myworld\private",   and   "\\?\UNC\tom_1\hotstuff\coolapps"   is   seen   as   "\\tom_1\hotstuff\coolapps".

1.遍历所有串口源码:

OnInitDialog初始化窗口

BOOL CDetectComDlg::OnInitDialog()
{CDialog::OnInitDialog();ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}SetIcon(m_hIcon, TRUE);           // 设置大图标SetIcon(m_hIcon, FALSE);        // 设置小图标DWORD sStyle = m_ListShow.GetExtendedStyle();sStyle |= LVS_EX_GRIDLINES;sStyle |= LVS_EX_FULLROWSELECT;m_ListShow.SetExtendedStyle(sStyle);m_ListShow.InsertColumn(0,_T("索引"),LVCFMT_LEFT,100);m_ListShow.InsertColumn(1,_T("串口号"),LVCFMT_LEFT,100);TraversalCom(); //遍历Com口return TRUE;
}

TraversalCom函数

void CDetectComDlg::TraversalCom(void)
{EnumerateSerialPorts(ports,portse,portsu);unsigned short Counter;unsigned short Setcom;CString str;//获取可用串口个数Counter = portse.GetSize(); //如果个数大于0if(Counter > 0){//初始化串口列表框for(int i=0; i<Counter; i++){Setcom = portse.ElementAt(i);str.Format("%d",i);m_ListShow.InsertItem(i,str);str.Format(_T("COM%d "),Setcom);m_ListShow.SetItemText(i,1,str);}}
}

EnumerateSerialPorts函数

void CDetectComDlg::EnumerateSerialPorts(CUIntArray& ports, CUIntArray& portse, CUIntArray& portsu)
{//清除串口数组内容ports.RemoveAll();portse.RemoveAll();portsu.RemoveAll();//因为至多有255个串口,所以依次检查各串口是否存在//如果能打开某一串口,或打开串口不成功,但返回的是 ERROR_ACCESS_DENIED错误信息,//都认为串口存在,只不过后者表明串口已经被占用,否则串口不存在for (int i=1; i<256; i++){//Form the Raw device nameCString sPort;sPort.Format(_T("\\\\.\\COM%d"), i);//Try to open the portBOOL bSuccess = FALSE;HANDLE hPort = ::CreateFile(sPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);if (hPort == INVALID_HANDLE_VALUE){DWORD dwError = GetLastError();if (dwError == ERROR_ACCESS_DENIED){bSuccess = TRUE;portsu.Add(i);       //已占用的串口}}else{//The port was opened successfullybSuccess = TRUE;portse.Add(i);      可用的串口//Don't forget to close the port, since we are going to do nothing with it anywayCloseHandle(hPort);}//Add the port number to the array which will be returnedif (bSuccess)ports.Add(i);   //所有存在的串口}
}

这时再刚登陆窗口时便可罗列出可用串口。

2.检测串口的热插拔

这里主要利用Cwnd的ON_WM_DEVICECHANGE消息来处理。
ON_WM_DEVICECHANGE消息在VS是通过手动添加的

注意:此消息只有顶层窗口可以捕获到
因此,首先得手动添加ON_WM_DEVICECHANGE消息:
第一步:在消息映射BEGIN_MESSAGE_MAP(Ctbox_debug_viewDlg, CDialogEx)中添加:

afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD dwData);

第二步:在cpp文件中添加函数声明

afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD dwData);

第三步:实现

BOOL CDetectComDlg::OnDeviceChange(UINT nEventType,DWORD dwData)
{//DEV_BROADCAST_DEVICEINTERFACE* dbd = (DEV_BROADCAST_DEVICEINTERFACE*) dwData;switch (nEventType){case DBT_DEVICEREMOVECOMPLETE://移除设备case DBT_DEVICEARRIVAL://添加设备ReDetectCom();//刷新列表框的内容break;default:break;}return TRUE;
}

ReDetectCom的内容

void CDetectComDlg::ReDetectCom(void)
{m_ListShow.DeleteAllItems();TraversalCom();
}

第四步包含头文件

由于DEV_BROADCAST_DEVICEINTERFACE,DBT_DEVICEREMOVECOMPLETE,DBT_DEVICEARRIVAL这几个东东在头文件Dbt.h中定义的,所以包含Dbt.h头文件

#include <Dbt.h>

至此遍历方法实现检测串口的方法已经实现,在下一篇中将介绍如何读取注册表实现串口的自动检测

源码:遍历方法的实现:遍历方法的实现

VC++ 动态检测串口的热插拔(一)通过遍历实现相关推荐

  1. 计算机安全模型研究与应用,软件哨兵安全动态检测模型的研究与实现-计算机应用研究.PDF...

    软件哨兵安全动态检测模型的研究与实现-计算机应用研究 第29卷第8期 计 算 机 应 用 研 究 Vol.29No.8 2012年8月 ApplicationResearchofComputers A ...

  2. 编译内核启用KASan动态检测内核内存错误功能(ubuntu16.04 4.4.0内核编译升级到linux-4.4.252版本)

    目录 一.编译内核并配置支持KAsan 1.下载源码 2.安装编译内核必须的库 3.清理之前内核编译生成及相关配置 4.配置内核参数 5.开始编译 6.模块(驱动)安装 7.安装新编译的内核 8.修改 ...

  3. 实验四:文件状态测试--动态检测指定文件的状态信息,当文件的大小发生改变时,给出提示信息,并继续前进检测。当文件的大小的变化次数或持续检查无变化次数达到一定值时,退出检查--操作系统原理和实践

    实验目的 熟悉UNIX的基本SHELL程序设计方法,包括: 命令行参数检测 变量设置 文件状态检测与特定信息读取 程序运行控制 实验内容 编写一个SHELL程序,动态检测指定文件的状态信息,当文件的大 ...

  4. 动态新增表字段_G347枞阳段货运车辆超限超载动态检测监控卡点 进入调试阶段...

    关注"安徽公路"获得更多精彩内容 日前 铜陵市G347枞阳段 货运车辆超限超载动态检测监控卡点项目 已顺利完成设备安装工作 进入设备调试阶段 G347枞阳段货运车辆超限超载动态检测 ...

  5. Qt实现定时自动检测串口

    Qt实现定时自动检测串口 在学Qt串口使用时,参考了CSDN上挺多的博客,大部分都讲的不错,适合初学者. 串口操作基本介绍 Qt为串口操作提供了两个类QSerialPort和QSerialPortIn ...

  6. (五)Linux 4G模块封装发送指令函数以及检测串口和SIM卡是否就绪

    文章目录 一.前言 二.发送AT指令函数:send_at_cmd() 2.1 设计思路 2.2 代码实现 三.Check系列函数--检测串口和SIM卡是否就绪 3.1check_tyy_ready() ...

  7. 实时准确高效动态检测确保铁路运行安全——TFDS、TVDS、TEDS检测系统

    自1825年世界第一条铁路在英国出现以来,铁路成为了人们出行的重要交通方式,铁路检测系统也成为铁路运输中不可或缺的重要组成部分.传统的铁路检测一直是依靠人工和静态检测,这种检测缺乏实时性和准确性,且效 ...

  8. 演练 动态数组存储学生对象 并且实现遍历 0119

    演练 动态数组存储学生对象 并且实现遍历 0119 需求 编码实现 参考代码

  9. 动态检测内存错误利器ASan

    ASan,即Address Sanitizer,是一个适用于c/c++程序的动态内存错误检测器,它由一个编译器检测模块(LLVM pass)和一个替换malloc函数的运行时库组成,在性能及检测内存错 ...

最新文章

  1. 《异步处理在分布式系统中的优化作用》学习笔记
  2. 快速索引 (对View的自定义)
  3. NAT穿透工具pwnat
  4. JQuery选择器一般方法
  5. 省市区联动三级下拉列表实现
  6. day12_oracle hint——SQL优化过程中常见Oracle中HINT的30个用法
  7. 沈逸老师ubuntu速学笔记(2)-- ubuntu16.04下 apache2.4和php7结合编译安装,并安裝PDOmysql扩展...
  8. Java Integer类highestOneBit()方法与示例
  9. 生活中有哪些越早明白越好的道理
  10. 如何在矩池云上安装java
  11. 7-1 字符串的冒泡排序 (20 分)
  12. Servlet期末复习笔记3
  13. c g位置服务器,C32/G34平台铺路 AMD为十二核CPU蓄势
  14. 举例说明计算机在现实应用中的作用,【举例说明多媒体技术的应用】_论多媒体技术在日常工作生活中的应用...
  15. python Click库知识点汇总
  16. 一本书让你知道互联网思维 个人总结
  17. plc虚拟服务器,VMware软件虚拟机和PLC通讯的连接方法
  18. ubuntu搭建vpn步骤
  19. html怎么设置一个表格的宽度一样吗,html表格单元格大小 怎样在html中设置所有表格大小一样...
  20. 请每一个恋爱中的人耐心地看下去

热门文章

  1. KDD CUP 2022 风能预测赛题冠军方案分享
  2. 【建议收藏】Android初级开发者怎样快速提高开发技能?这20个开源APP能帮到你
  3. 在OCC7.6中,gp_vector和gp_dir和gp_axis有什么区别
  4. 计算机端口com1,访问端口“COM1”被拒绝(Access to the port “COM1” is denied)
  5. rz安装 xshell_Linux与windows之间文件传输工具RZSZ安装(Xshell或CRT)
  6. 数字华容道 逆时针
  7. mmdetection训练自己的COCO数据集及常见问题
  8. 【计算机毕业设计】018母婴商城系统
  9. 链接:https://pan.baidu.com/s/1joRvLQ7nbti0Wp4t2CkX5w 提取码:ZMTD
  10. UnityShader入门精要-屏幕后处理效果 亮度饱和度对比度、边缘检测、高斯模糊、bloom效果、运动模糊