方法一:

int C数据接收软件Dlg::GetCom() 

 { 

     int reg; 


     // CStringArray strCommArr;   

     HKEY hKey;   

     int rtn;   

     //m_cmbComm.ResetContent();   

     rtn = RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Hardware\\DeviceMap\\SerialComm",   

         NULL, KEY_READ, &hKey); // 打开串口注册表   

     if( rtn == ERROR_SUCCESS)   

     {   

         int i=0;   

         char portName[256],commName[256];   

         DWORD dwLong,dwSize;   

         while(1)   

         {   

             dwSize = sizeof(portName);   

             dwLong = dwSize;   

             rtn = RegEnumValue( hKey, i, portName, &dwLong,   

                 NULL, NULL, (PUCHAR)commName, &dwSize );   


             if( rtn == ERROR_NO_MORE_ITEMS ) // 枚举串口   

             { 

                 break;   

             } 

             // strCommArr.Add(commName);   

              

             m_ctrlComID.AddString(commName); 

             i++;   

         } 

         reg=i; 

     }   

     RegCloseKey(hKey);   

     return reg; 

 }



使用VC6.0 自动识别可用串口 添加至combox。

 

解答:

  1.新建COMMTEST3工程,添加一个combobox到界面,id设置为IDC_COMBO。

(注意:组合框(ComboBox),运行时点击其右边的小箭头拉不下来(即不出现下拉列表)。需如下设置:
这是使用VC++的人最初常遇到的问题,实际上是下拉列表的高度设置不当。组合框的高度是不能修改的,它是由系统决定的,但下拉部分的高度(即在下拉框中显示多少行)是可以设置的。在VB和Delphi中默认的高度是8行,但在VC++中默认为0。你需要在设计时,用鼠标在下拉箭头上(必须是这个位置)点一下,这时出现下图所示的方框,拉住下方的蓝块向下移动,直到一个满意的高度为止。)

2.添加如下代码到COMMTEST3Dlg.cpp    

void CCOMMTEST3Dlg::GetCom() 

  { 

      //程序启动时获取全部可用串口 

      HANDLE  hCom; 

      int i,num,k; 

      CString str; 

      BOOL flag; 

       

      ((CComboBox *)GetDlgItem(IDC_COMBO))->ResetContent(); 

      flag = FALSE; 

      num = 0; 

      for (i = 1;i <= 16;i++) 

      {//此程序支持16个串口 

          str.Format("\\\\.\\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))->AddString(str); 

              if (flag == FALSE) 

              { 

                  flag = TRUE; 

                  num = i; 

              } 

          } 

      } 

      i = ((CComboBox *)GetDlgItem(IDC_COMBO))->GetCount(); 

      if (i == 0) 

      {//若找不到可用串口则禁用“打开串口”功能 

          ((CComboBox *)GetDlgItem(IDC_COMBO))->EnableWindow(FALSE); 

     } 

     else 

      { 

          k = ((CComboBox *)GetDlgItem((IDC_COMBO)))->GetCount(); 

          ((CComboBox *)GetDlgItem(IDC_COMBO))->SetCurSel(k - 1); 

        //mCom.BindCommPort(num); 

     } 

  }



  3.OnInitDialog()中加入GetCom();

  4.头文件中加入void GetCom();

  5.执行程序,获取可用串口

 

 

  
附录:VC中如何打开Com10及以上的串口

    今天用以前的一个串口程序,发现串口怎么也打不开。因为用的串口不是常规的COM1、COM2而是大于Com10的端口,想着是很简单的增加几个选项就可以轻松搞定的,结果加上后测试,发现总是初始化失败,调试发现在CreateFile里总是失败,找到MSDN一看果然这里有区别。

   Win32 API函数CreateFile()除了可打开普通文件外,还可以打开设备,比如可用于打开串口,获得串口句柄。使用CreateFile()函数打开串口时文件共享模式应设置为0(表示独占),创建参数设置为OPEN_EXISTING,模板必须设置为NULL。

   如果为COM1至COM9,可使用“COM1”-“COM9”作为文件名传递给CreateFile()函数,函数可成功返回。但是,如果操作对象为COM10及以上的端口,以此方式命名文件名调用CreateFile()函数会返回INVALID_HANDLE_VALUE,表示端口无法打开。

   产生这种奇怪现象的原因是:微软预定义的标准设备中含有“COM1”-“COM9”。所以,“COM1”-“COM9”作为文件名传递给函数时操作系统会自动地将之解析为相应的设备。但对于COM10及以上的串口,“COM10”之类的文件名系统只视之为一般意义上的文件,而非串行设备。

   为了增加对COM10及以上串行端口的支持,微软规定,如果要访问这样的设备,应使用这样的文件名(以COM10为例):\\.COM10
   所以,对于COM10及以上的串口,CreateFile()的调用样式应调整如下:

CreateFile( 

 "\\\\.\\COM10",           // 定义串口名 

 fdwAccess,                // 存取模式(读写) 

 0,                               // 共享模式:必须设置为0,表示设备独占使用 

 NULL,                        // 保密性 

 OPEN_EXISTING,      // 必须设置为OPEN_EXISTING 

 0,                               // 文件属性,如果是异步模式,可设置为 

 NULL                         // 模版,串口设备必须设置为NULL 

 );