自己开发一个串口通信应用,运行时需要检测当前PC机上有多少个串口,设备插入或者拔出时都能在Combo Box中显示出来,下面将进行以下汇总:
在对话框的OnInitDialog函数内做如下操作
BOOL COnshowDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
AddCom();//向组合框中添加串口设备
m_CombolPort.SetCurSel(0);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
AddCom函数如下定义:
void COnshowDlg::AddCom(void)
{
ports.RemoveAll();
portse.RemoveAll();
portsu.RemoveAll();
//因为至多有255个串口,所以依次检查各串口是否存在
//如果能打开某一串口,或打开串口不成功,但返回的是 ERROR_ACCESS_DENIED错误信息,
//都认为串口存在,只不过后者表明串口已经被占用
//否则串口不存在
for (int i=1; i<256; i++)
{
//Form the Raw device name
CString sPort;
sPort.Format(_T("\\\\.\\COM%d"), i);
//Try to open the port
BOOL 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 successfully
bSuccess = TRUE;
portse.Add(i); 可用的串口
//Don't forget to close the port, since we are going to do nothing with it anyway
CloseHandle(hPort);
}
//Add the port number to the array which will be returned
if (bSuccess)
ports.Add(i); //所有存在的串口
}
unsigned short uicounter;
unsigned short uisetcom;
CString str;
//获取可用串口个数
uicounter = portse.GetSize();
//如果个数大于0
if(uicounter > 0)
{
//初始化串口列表框
for(int i=0; i<uicounter; i++)
{
uisetcom = portse.ElementAt(i);
str.Format(_T("COM%d "),uisetcom);
m_CombolPort.AddString(str);
}
}
}
完成以上内容就能把检测到的串口添加到Combo Box中。
3 串口热拔插时检测串口
这里主要利用Cwnd的ON_WM_DEVICECHANGE消息来处理。
ON_WM_DEVICECHANGE消息在VS2010中好像只能通过手动来添加,因此,首先得手动添加ON_WM_DEVICECHANGE消息:
第一步:在消息映射BEGIN_MESSAGE_MAP(Ctbox_debug_viewDlg, CDialogEx)中添加:
ON_WM_DEVICECHANGE()
第二步:在头文件中添加函数声明:
afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD dwData);
第三步:实现函数:
BOOL COnshowDlg::OnDeviceChange(UINT nEventType,DWORD dwData)
{
//DEV_BROADCAST_DEVICEINTERFACE* dbd = (DEV_BROADCAST_DEVICEINTERFACE*) dwData;
switch (nEventType)
{
case DBT_DEVICEREMOVECOMPLETE://移除设备
case DBT_DEVICEARRIVAL://添加设备
RefreshCom();//刷新组合框的内容
break;
default:
break;
}
return TRUE;
}
void COnshowDlg::RefreshCom(void)
{
int count =m_CombolPort.GetCount();
for(int i=0;i<count;i++)
{
m_CombolPort.DeleteString(count -1 -i);
}
AddCom();
m_CombolPort.SetCurSel(0);
}
第四步:在.cpp中加入头文件
#include <Dbt.h>
这是因为DEV_BROADCAST_DEVICEINTERFACE,DBT_DEVICEREMOVECOMPLETE,DBT_DEVICEARRIVAL这几个东东在头文件Dbt.h中定义的,这样才能编译通过。