天天看點

MFC中序列槽通信的一些方法

項目中需要使用序列槽通信,一開始使用的方法為判斷CreateFile()方法的傳回值來進行序列槽的打開選擇。方法為

HANDLE hCom;
CString str;
((CComboBox *)GetDlgItem(I
DC_COMBO_DEBUG_COMPORT_PORT_SELECT))->ResetContent();//清除下拉框内容
for (int i = 1;i <= 16;i++)
{//此程式支援16個序列槽
    str.Format(_T("\\\\.\\COM%d"),i);
    hCom = CreateFile(str, 0, 0, 0, 
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    if(INVALID_HANDLE_VALUE != hCom )
    {//能打開該序列槽,則添加該序列槽
        CloseHandle(hCom);
        str = str.Mid(4);
        ((CComboBox *)GetDlgItem(IDC_COMBO_DEBUG_COMPORT_PORT_SELECT))->AddString(str);
    }
}
if (((CComboBox *)GetDlgItem(IDC_COMBO_DEBUG_COMPORT_PORT_SELECT))->GetCount()== 0)
{//若找不到可用序列槽則禁用“打開序列槽”功能
    ((CComboBox *)GetDlgItem(IDC_COMBO_DEBUG_COMPORT_PORT_SELECT))->AddString(_T("請選擇COM口"));
    ((CButton *)GetDlgItem(IDC_BUTTON_DEBUG_COMPORT_OPERATION))->EnableWindow(FALSE);
}
else
{
    ((CButton *)GetDlgItem(IDC_BUTTON_DEBUG_COMPORT_OPERATION))->EnableWindow(TRUE);
    ((CComboBox *)GetDlgItem(IDC_COMBO_DEBUG_COMPORT_PORT_SELECT))->SetCurSel(0);
}
           

此方法雖然可以查找到可以打開的COM口,但是顯示的序列槽名字隻有COM加序列槽号,并不能顯示全部的序列槽資訊,對于同時有多個序列槽打開時顯得不是很友善,于是通過上網查詢,查找到利用SetupAPI函數集的方法.參考 在序列槽通信開發中實作自動查找序列槽端口的方法

使用該方法要在你的程式中,添加“ EnumSerial.cpp ”和“ EnumSerial.h ”兩個檔案,并且将 Setupapi.lib 包含進你的工程,方法在項目屬性-配置屬性-連接配接器-輸入-附加依賴項中添加setupapi.lib,然後在EnumSerial.cpp中添加包含"setupapi.h" ,你的應用程式添加包含EnumSerial.h頭檔案就行了.

((CComboBox *)GetDlgItem(IDC_COMBO_DEBUG_COMPORT_PORT_SELECT))->ResetContent();
int m_nSerialPortNum(0);// 序列槽計數 
CString str;
CString str1;
CString str2;
CArray<SSerInfo,SSerInfo&> asi; 
EnumSerialPorts(asi,TRUE);// 參數為 TRUE 時枚舉目前可以打開的序列槽, 
m_nSerialPortNum = asi.GetSize(); 
for (int i=0;i<m_nSerialPortNum;i++)
{
    str = asi[i].strFriendlyName;    //因為此方法獲得的名字為USB-SERIAL CH340 (COM10)這樣的,我想要COM10在前面顯示,是以進行了下面的代碼處理
    str1 = str.Left(str.Find(_T("("))-1);  
    str2 = str.Left(str.Find(_T(")")));
    str2 = str2.Right(str2.GetLength()-str2.Find(_T("("))-1);
    str.Format(_T("%s:%s"),str2,str1);
    ((CComboBox *)GetDlgItem(IDC_COMBO_DEBUG_COMPORT_PORT_SELECT))->AddString(str);
}
if (m_nSerialPortNum == 0)
{
    ((CComboBox *)GetDlgItem(IDC_COMBO_DEBUG_COMPORT_PORT_SELECT))->AddString(_T("請選擇COM口"));
    ((CComboBox *)GetDlgItem(IDC_COMBO_DEBUG_COMPORT_PORT_SELECT))->SetCurSel(0);
    ((CButton *)GetDlgItem(IDC_BUTTON_DEBUG_COMPORT_OPERATION))->EnableWindow(FALSE);
}else{
    ((CComboBox *)GetDlgItem(IDC_COMBO_DEBUG_COMPORT_PORT_SELECT))->SetCurSel(0);
    ((CButton *)GetDlgItem(IDC_BUTTON_DEBUG_COMPORT_OPERATION))->EnableWindow(TRUE);
}