kongyi0
空翼0
采纳率0%
2016-05-28 03:29 阅读 1.4k

MFC中串口操作的问题,求各位大神帮忙看看

10

我想在MFC中实现当接入计算机的串口有所变化时,在组合框中改变相应列表项,并且当拔出的是当前已经选择的串口时,将打开/关闭按键的显示状态改变,同时关闭相应串口,其他情况下不改变已经选择串口的状态,但是我发现不管怎么改变插入拔出哪个串口,打开/关闭按键都会变为关闭状态(当前面是打开状态时),调试了一个早上,还是没发现问题,各位大神能不能帮忙看看怎么回事,谢谢了!

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

5条回答 默认 最新

  • kongyi0 空翼0 2016-05-28 03:30

    这个是代码,是通过捕获WM_DEVICECHANGE消息实现的,读串口是通过读注册表实现的

    点赞 评论 复制链接分享
  • kongyi0 空翼0 2016-05-28 03:38

    BOOL CSerialPortTest2Dlg::OnDeviceChange(UINT nEventType,DWORD dwData) //有串口热拔出或插入
    {
    CString str;
    int len,len1;
    m_ctrlComboCom.GetWindowText(str);
    len1 = m_ctrlComboCom.GetCount();
    /**********************************************************************************************************************/
    int i = 0; //通过注册表读取串口号
    char Name[25];
    UCHAR szPortName[25];
    LONG Status;
    DWORD dwIndex = 0;
    DWORD dwName;
    DWORD dwSizeofPortName;
    DWORD Type;
    HKEY hKey;
    CString strSerialList[256]; // 临时定义 256 个字符串组,因为系统最多也就 256 个
    LPCTSTR data_Set="HARDWARE\DEVICEMAP\SERIALCOMM\";
    dwName = sizeof(Name);
    dwSizeofPortName = sizeof(szPortName);
    //long ret0 = (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_Set, 0, KEY_READ, &hKey));
    long ret0 = RegOpenKey(HKEY_LOCAL_MACHINE, data_Set, &hKey); //打开一个制定的注册表键,成功返回ERROR_SUCCESS即“0”值
    if(ret0 == ERROR_SUCCESS)
    {
    do
    {
    Status = RegEnumValue(hKey, dwIndex++, Name, &dwName, NULL, &Type, szPortName, &dwSizeofPortName);//读取键值
    if((Status == ERROR_SUCCESS)||(Status == ERROR_MORE_DATA))
    {
    strSerialList[i] = CString(szPortName); // 串口字符串保存
    //m_ctrlComboCom.AddString(strSerialList[i]);
    i++;// 串口计数
    }
    //每读取一次dwName和dwSizeofPortName都会被修改
    //注意一定要重置,否则会出现很离奇的错误,本人就试过因没有重置,出现先插入串口号大的(如COM4),再插入串口号小的(如COM3),此时虽能发现两个串口,但都是同一串口号(COM4)的问题,同时也读不了COM大于10以上的串口
    dwName = sizeof(Name);
    dwSizeofPortName = sizeof(szPortName);
    } while((Status == ERROR_SUCCESS)||(Status == ERROR_MORE_DATA));
    RegCloseKey(hKey);
    }
    /*******************************************************************************************************************************/
    len = i;
    if(len > len1) //有新的串口插入
    {
    m_ctrlComboCom.ResetContent();
    for(i=0;i<len;i++) //重新加载串口列表
    m_ctrlComboCom.AddString(strSerialList[i]);
    m_ctrlComboCom.SetWindowText(str);
    }
    else //少了一个串口,但仍然有串口存在
    {
    if(len == 0) //热拔出后不再有串口存在
    {
    m_ctrlComboCom.ResetContent();
    }
    else //热拔出后仍有串口存在
    {
    for(i=0;i<len;i++)
    {
    if(strSerialList[i] == str)
    break;
    }
    m_ctrlComboCom.ResetContent();
    int j;
    for(j=0;j<len;j++) //重新加载串口列表
    m_ctrlComboCom.AddString(strSerialList[j]);
    if(i == len)
    {//在新的串口表里没有找到编辑框中的串口
    m_ctrlComboCom.SetCurSel(0); //设置默认串口
    if(m_bSerialPortOpened == TRUE)
    {
    //m_SerialPort.StopMonitoring();
    m_SerialPort.ClosePort();
    m_ctrlBtnOpenClose.SetIcon(IDI_ICON2); //更换图标
    m_ctrlBtnOpenClose.SetFlat(FALSE);
    SetDlgItemText(IDC_BUTTON_OPEN, _T("打开串口"));
    //AfxMessageBox(_T("串口关闭成功!"));
    m_bSerialPortOpened = FALSE;
    }
    }
    else if(i<len)
    {
    m_ctrlComboCom.SetWindowText(str);
    }
    //AfxMessageBox(str);
    }
    }
    return TRUE;
    }

    
    
    点赞 评论 复制链接分享
  • kongyi0 空翼0 2016-05-28 03:44
    1. 是这样插入代码吗?
    点赞 评论 复制链接分享
  • kongyi0 空翼0 2016-05-28 03:45
     BOOL CSerialPortTest2Dlg::OnDeviceChange(UINT nEventType,DWORD dwData)     //有串口热拔出或插入
    {
        CString str;
        int len,len1;
        m_ctrlComboCom.GetWindowText(str);
        len1 = m_ctrlComboCom.GetCount();
    /**********************************************************************************************************************/
        int i = 0;                         //通过注册表读取串口号
        char Name[25]; 
        UCHAR szPortName[25]; 
        LONG Status; 
        DWORD dwIndex = 0;
        DWORD dwName;
        DWORD dwSizeofPortName;
        DWORD Type;
        HKEY hKey;
        CString strSerialList[256];  // 临时定义 256 个字符串组,因为系统最多也就 256 个 
        LPCTSTR data_Set="HARDWARE\\DEVICEMAP\\SERIALCOMM\\";
        dwName = sizeof(Name);
        dwSizeofPortName = sizeof(szPortName);
        //long ret0 = (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_Set, 0, KEY_READ, &hKey)); 
        long ret0 = RegOpenKey(HKEY_LOCAL_MACHINE, data_Set, &hKey); //打开一个制定的注册表键,成功返回ERROR_SUCCESS即“0”值
        if(ret0 == ERROR_SUCCESS) 
        {
            do
            {
                Status = RegEnumValue(hKey, dwIndex++, Name, &dwName, NULL, &Type, szPortName, &dwSizeofPortName);//读取键值
                if((Status == ERROR_SUCCESS)||(Status == ERROR_MORE_DATA))
                {
                    strSerialList[i] = CString(szPortName);       // 串口字符串保存
                    //m_ctrlComboCom.AddString(strSerialList[i]);
                    i++;// 串口计数
                }
                //每读取一次dwName和dwSizeofPortName都会被修改
                //注意一定要重置,否则会出现很离奇的错误,本人就试过因没有重置,出现先插入串口号大的(如COM4),再插入串口号小的(如COM3),此时虽能发现两个串口,但都是同一串口号(COM4)的问题,同时也读不了COM大于10以上的串口 
                dwName = sizeof(Name);
                dwSizeofPortName = sizeof(szPortName);
            } while((Status == ERROR_SUCCESS)||(Status == ERROR_MORE_DATA));
            RegCloseKey(hKey);
        }
        /*******************************************************************************************************************************/
        len = i;
        if(len > len1)             //有新的串口插入
        {
            m_ctrlComboCom.ResetContent();
            for(i=0;i<len;i++)          //重新加载串口列表
                m_ctrlComboCom.AddString(strSerialList[i]);
            m_ctrlComboCom.SetWindowText(str);
        }
        else                           //少了一个串口,但仍然有串口存在
        {
            if(len == 0)                    //热拔出后不再有串口存在
            {
                m_ctrlComboCom.ResetContent();
            }
            else                           //热拔出后仍有串口存在
            {
                for(i=0;i<len;i++)
                {
                    if(strSerialList[i] == str)
                    break;
                }
                m_ctrlComboCom.ResetContent();
                int j;
                for(j=0;j<len;j++)          //重新加载串口列表
                    m_ctrlComboCom.AddString(strSerialList[j]);
                if(i == len)
                {//在新的串口表里没有找到编辑框中的串口
                    m_ctrlComboCom.SetCurSel(0);     //设置默认串口
                    if(m_bSerialPortOpened == TRUE)
                    {
                        //m_SerialPort.StopMonitoring();
                        m_SerialPort.ClosePort();
                        m_ctrlBtnOpenClose.SetIcon(IDI_ICON2);   //更换图标
                        m_ctrlBtnOpenClose.SetFlat(FALSE);
                        SetDlgItemText(IDC_BUTTON_OPEN, _T("打开串口"));
                        //AfxMessageBox(_T("串口关闭成功!"));
                        m_bSerialPortOpened = FALSE;
                    }
                }
                else if(i<len)
                {
                    m_ctrlComboCom.SetWindowText(str);
                }
                //AfxMessageBox(str);
            }
        }
        return TRUE;
    }
    
    点赞 评论 复制链接分享
  • kongyi0 空翼0 2016-05-28 03:46

    代码终于插入进来了,求各位大神帮忙看看吧,谢谢!

    点赞 评论 复制链接分享

相关推荐