337上位机VC MFC获取有效串口
获取有效串口
功能展示
串口是我们工业控制中必用的通讯口,使用串口前第一要设置的就是使用哪个串口,我们当前例程实现获取系统当前可能串口的功能,效果如图,点击<获取系统串口>可以获取系统中存在的串口并显示出来,点击另一方法可以获取全部串口,被占用串口,可用串口,点击测试,程序会占用串口4;
要点提示
检查系统串口的方法有很多种,我们当前例程使用效率高且方便的两种方法,一种是查询注册表法,另一种是调用API函数法。查询注册表的方法是比较常见的方法,通过查看“ HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM ”项来获取串口信息;
另一种是调用函数CreateFile()函数打开窗口,系统最多有1—256,共255个串口,所以可以此函数依次打开串口,失败时错误代码为ERROR_ACCESS_DENIED表示串口存在但被占用,成功时表示串口可用;
实现功能
1.新建基于对话框的应用程序
2.依照例程添加组合框IDC_COMBO1,IDC_COMBO2,IDC_COMBO3用于显示串口,添加按钮<获取系统串口(方法一)><获取系统串口(方法二)><测试>用于执行不同功能,关联点击函数
#include<Afxtempl.h>
void CGkbc8Dlg::OnGet()
{
CArray<CString,CString> comarray; //可设置为全局变量,随时使用
comarray.RemoveAll();
HKEY hKey=NULL;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"),0,KEY_READ,&hKey)!=ERROR_SUCCESS)
{
return ;
}
CString valuename,databuffer;
DWORD valuenamebufferlength=200,valuetype,databuddersize=200;
int i=0;
while(RegEnumValue(hKey,i++,valuename.GetBuffer(200),&valuenamebufferlength,NULL,&valuetype,(BYTE*)databuffer.GetBuffer(200),&databuddersize) != ERROR_NO_MORE_ITEMS)
{
comarray.Add(CString(databuffer));
databuddersize=200;
valuenamebufferlength=200;
}
RegCloseKey(hKey);
//<>显示已获取的串口
CComboBox *pCombo = (CComboBox *)GetDlgItem(IDC_COMBO3);
pCombo->ResetContent();
int nNum=comarray.GetSize();
for(i=0;i<nNum;i++)
{
pCombo->AddString(comarray.GetAt(i));
}
pCombo->SetCurSel(0);
}
void CGkbc8Dlg::OnGet2()
{
CComboBox* pCombo1=(CComboBox*)GetDlgItem(IDC_COMBO1);
CComboBox* pCombo2=(CComboBox*)GetDlgItem(IDC_COMBO2);
CComboBox* pCombo3=(CComboBox*)GetDlgItem(IDC_COMBO3);
pCombo1->ResetContent();
pCombo2->ResetContent();
pCombo3->ResetContent();
//<>
CUIntArray Ports, PortsSpair, PortsUsed;
EnumerateSerialPorts(Ports,PortsSpair,PortsUsed);
int nNum,nIndex,i;
CString sCom;
nNum = PortsSpair.GetSize();//空闲串口
if(nNum>0)
{
for(i=0;i<nNum;i++)
{
nIndex = PortsSpair.ElementAt(i);
sCom.Format(_T("COM%d "),nIndex);
pCombo1->AddString(sCom);
}
pCombo1->SetCurSel(0);
}
//<>
nNum = PortsUsed.GetSize();//被占用串口
if(nNum>0)
{
for(i=0;i<nNum;i++)
{
nIndex = PortsUsed.ElementAt(i);
sCom.Format(_T("COM%d "),nIndex);
pCombo2->AddString(sCom);
}
pCombo2->SetCurSel(0);
}
//<>
nNum = Ports.GetSize();///系统全部串口
if(nNum>0)
{
for(i=0;i<nNum;i++)
{
nIndex = Ports.ElementAt(i);
sCom.Format(_T("COM%d "),nIndex);
pCombo3->AddString(sCom);
}
pCombo3->SetCurSel(0);
}
}
void CGkbc8Dlg::OnTest()
{
CString sPort;
int i=4;//测试占用串口4
sPort.Format(_T("\\\\.\\COM%d"), i);
HANDLE hPort = ::CreateFile(sPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
}
3.添加自定义函数EnumerateSerialPorts()
我们来演示下功能实现的整个过程
如果您认可,可联系功能定制! 如果您着急,充值会员可直接联系发您资料!
|