CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VB >  基础类

我想做一个串口通讯,查看串口,请帮忙

楼主monkst(monkst)2002-07-30 14:50:41 在 VB / 基础类 提问

我想像超级终端那样,列出当前的可用端口,并可配置,这应是用API可以实现,但用什么API?可以指点一下吗? 问题点数:100、回复次数:12Top

1 楼david1979210(蓝钻骑士)回复于 2002-07-30 14:52:21 得分 5

用VB的通讯控件,可以设置端口啊?Top

2 楼daviddivad(你真行,居然比我还快! Scorpio)回复于 2002-07-30 14:57:15 得分 60

枚举注册表下的值:  
  HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM  
  ,用API也行,但他会列出所有的端口(包括并口)。  
  【VB声明】  
      Private   Declare   Function   EnumPorts   Lib   "winspool.drv"   Alias   "EnumPortsA"   (ByVal   pName   As   String,   ByVal   Level   As   Long,   ByVal   lpbPorts   As   Long,   ByVal   cbBuf   As   Long,   pcbNeeded   As   Long,   pcReturned   As   Long)   As   Long  
   
  【别名】  
      EnumPortsA  
   
  【说明】  
      枚举一个系统可用的端口    
   
  【返回值】  
      Long,非零表示成功,零表示失败。会设置GetLastError    
   
  【备注】  
      参考AddPort函数,了解进一步的情况  
   
  【参数表】  
      pName   ----------     String,指定服务器的名字。用vbNullString指定本地系统  
   
      Level   ----------     Long,1或2(1用于NT   3.51),分别指定PORT_INFO_1   或   PORT_INFO_2  
   
      lpbPorts   -------     Long,包含PORT_INFO_1   或   PORT_INFO_2结构的缓冲区  
   
      cbBuf   ----------     Long,lpbPorts缓冲区中的字符数量  
   
      pcbNeeded   ------     Long,指向一个Long型变量的指针,该变量用于保存请求的缓冲区长度,或者实际读入的字节数量  
   
      pcReturned   -----     Long,载入缓冲区的结构数量(用于那些能返回多个结构的函数)  
   
  '==============================================  
  Private   Type   PORT_INFO_2  
          pPortName   As   String  
          pMonitorName   As   String  
          pDescription   As   String  
          fPortType   As   Long  
          Reserved   As   Long  
  End   Type  
  Private   Type   API_PORT_INFO_2  
          pPortName   As   Long  
          pMonitorName   As   Long  
          pDescription   As   Long  
          fPortType   As   Long  
          Reserved   As   Long  
  End   Type  
  Private   Declare   Function   EnumPorts   Lib   "winspool.drv"   Alias   "EnumPortsA"   (ByVal   pName   As   String,   ByVal   Level   As   Long,   ByVal   lpbPorts   As   Long,   ByVal   cbBuf   As   Long,   pcbNeeded   As   Long,   pcReturned   As   Long)   As   Long  
  Private   Declare   Function   lstrlenW   Lib   "kernel32"   (ByVal   lpString   As   Long)   As   Long  
  Private   Declare   Sub   CopyMem   Lib   "kernel32"   Alias   "RtlMoveMemory"   (pTo   As   Any,   uFrom   As   Any,   ByVal   lSize   As   Long)  
  Private   Declare   Function   HeapAlloc   Lib   "kernel32"   (ByVal   hHeap   As   Long,   ByVal   dwFlags   As   Long,   ByVal   dwBytes   As   Long)   As   Long  
  Private   Declare   Function   GetProcessHeap   Lib   "kernel32"   ()   As   Long  
  Private   Declare   Function   HeapFree   Lib   "kernel32"   (ByVal   hHeap   As   Long,   ByVal   dwFlags   As   Long,   lpMem   As   Any)   As   Long  
  Dim   Ports(0   To   100)   As   PORT_INFO_2  
  Public   Function   TrimStr(strName   As   String)   As   String  
          'Finds   a   null   then   trims   the   string  
          Dim   x   As   Integer  
          x   =   InStr(strName,   vbNullChar)  
          If   x   >   0   Then   TrimStr   =   Left(strName,   x   -   1)   Else   TrimStr   =   strName  
  End   Function  
  Public   Function   LPSTRtoSTRING(ByVal   lngPointer   As   Long)   As   String  
          Dim   lngLength   As   Long  
          'Get   number   of   characters   in   string  
          lngLength   =   lstrlenW(lngPointer)   *   2  
          'Initialize   string   so   we   have   something   to   copy   the   string   into  
          LPSTRtoSTRING   =   String(lngLength,   0)  
          'Copy   the   string  
          CopyMem   ByVal   StrPtr(LPSTRtoSTRING),   ByVal   lngPointer,   lngLength  
          'Convert   to   Unicode  
          LPSTRtoSTRING   =   TrimStr(StrConv(LPSTRtoSTRING,   vbUnicode))  
  End   Function  
  'Use   ServerName   to   specify   the   name   of   a   Remote   Workstation   I.e.   "//WIN95WKST"  
  'or   leave   it   blank   ""   to   get   the   ports   of   the   local   Machine  
  Public   Function   GetAvailablePorts(ServerName   As   String)   As   Long  
          Dim   ret   As   Long  
          Dim   PortsStruct(0   To   100)   As   API_PORT_INFO_2  
          Dim   pcbNeeded   As   Long  
          Dim   pcReturned   As   Long  
          Dim   TempBuff   As   Long  
          Dim   I   As   Integer  
          'Get   the   amount   of   bytes   needed   to   contain   the   data   returned   by   the   API   call  
          ret   =   EnumPorts(ServerName,   2,   TempBuff,   0,   pcbNeeded,   pcReturned)  
          'Allocate   the   Buffer  
          TempBuff   =   HeapAlloc(GetProcessHeap(),   0,   pcbNeeded)  
          ret   =   EnumPorts(ServerName,   2,   TempBuff,   pcbNeeded,   pcbNeeded,   pcReturned)  
          If   ret   Then  
                  'Convert   the   returned   String   Pointer   Values   to   VB   String   Type  
                  CopyMem   PortsStruct(0),   ByVal   TempBuff,   pcbNeeded  
                  For   I   =   0   To   pcReturned   -   1  
                          Ports(I).pDescription   =   LPSTRtoSTRING(PortsStruct(I).pDescription)  
                          Ports(I).pPortName   =   LPSTRtoSTRING(PortsStruct(I).pPortName)  
                          Ports(I).pMonitorName   =   LPSTRtoSTRING(PortsStruct(I).pMonitorName)  
                          Ports(I).fPortType   =   PortsStruct(I).fPortType  
                  Next  
          End   If  
          GetAvailablePorts   =   pcReturned  
          'Free   the   Heap   Space   allocated   for   the   Buffer  
          If   TempBuff   Then   HeapFree   GetProcessHeap(),   0,   TempBuff  
  End   Function  
  Private   Sub   Form_Load()  
          'KPD-Team   2000  
          'URL:   http://www.allapi.net/  
          'E-Mail:   KPDTeam@Allapi.net  
          Dim   NumPorts   As   Long  
          Dim   I   As   Integer  
          'Get   the   Numbers   of   Ports   in   the   System  
          'and   Fill   the   Ports   Structure  
          NumPorts   =   GetAvailablePorts("")  
          'Show   the   available   Ports  
          Me.AutoRedraw   =   True  
          For   I   =   0   To   NumPorts   -   1  
                  Me.Print   Ports(I).pPortName  
          Next  
  End   SubTop

3 楼mazhayang(蚂蚱先生)回复于 2002-07-30 16:32:48 得分 5

Public   Declare   Function   CommConfigDialog   Lib   "kernel32"   Alias   "CommConfigDialogA"   (ByVal   lpszName   As   String,   ByVal   hWnd   As   Long,   lpCC   As   COMMCONFIG)   As   Long  
   
  Private   Sub   Command1_Click()  
  Dim   comm   As   COMMCONFIG  
  comm.dwSize   =   10000  
  Debug.Print   comm.dwSize  
  CommConfigDialog   "COM1",   Me.hWnd,   comm  
  Debug.Print   comm.dwSize  
  End   SubTop

4 楼CityBird(鹰扬九洲——只有想不到的,没有做不到的)回复于 2002-07-30 16:54:36 得分 5

CreateFile、ReadFild、WriteFile、WaitCommEvent、SetupComm  
   
  SetCommStat、BuildCommDCB、SetCommMask、GetCommState、ClearCommError  
   
  CommConfigDialog、PurgeComm………………Top

5 楼monkst(monkst)回复于 2002-07-31 09:09:57 得分 0

感谢   daviddivad,  
        我测试了你的程序,但与我的想像还有一点距离,我要找的是可用的COM口,我的本机能用的COM口是COM1但它出现了COM1到COM4以及FILE,LPT1到LPT4。  
   
    mazhayang(蚂蚱先生):  
      我好像不能使用你的程序,COMMCONFIG如何定义,还请帮忙。  
    我想的是与windows的超级终端一样的功能,所列出的COM口必须能进行COM通讯,有人有方法吗?Top

6 楼Pipi0714(老顽童)回复于 2002-07-31 09:20:10 得分 5

vb的控件足以Top

7 楼monkst(monkst)回复于 2002-07-31 17:39:38 得分 0

MSCOMM无法提供一个检查可用端口的方法,我也试过使用错误处理,可是好像不是十分的好,WINDOWS对超级终端肯定提供了相应的API,如TAPI的lineTranslateDialog.有人对此有了解吗?Top

8 楼monkst(monkst)回复于 2002-07-31 17:41:42 得分 0

枚举注册表下的值:  
  HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM  
  这个说法好像可行,可怎么做?Top

9 楼Mailbomb(网络咖啡http://blog.csdn.net/mailbomb)回复于 2002-07-31 18:24:31 得分 5

学习Top

10 楼daviddivad(你真行,居然比我还快! Scorpio)回复于 2002-08-01 10:02:46 得分 10

临时写了个例子,你新建一个工程,把以下代码复制进去就行了,该程序连MODEM的端口都检测出来了,你可根据你的要求把它去掉也行。  
   
  WIN2000+VB6+SP5   测试通过。  
   
  Option   Explicit  
   
  Const   HKEY_CURRENT_CONFIG   =   &H80000005  
  Const   HKEY_LOCAL_MACHINE   =   &H80000002  
  Const   REG_SZ   =   1  
  Private   Declare   Function   RegCloseKey   Lib   "advapi32.dll"   (ByVal   hKey   As   Long)   As   Long  
  Private   Declare   Function   RegOpenKey   Lib   "advapi32.dll"   Alias   "RegOpenKeyA"   (ByVal   hKey   As   Long,   ByVal   lpSubKey   As   String,   phkResult   As   Long)   As   Long  
  Private   Declare   Function   RegEnumKeyEx   Lib   "advapi32.dll"   Alias   "RegEnumKeyExA"   (ByVal   hKey   As   Long,   ByVal   dwIndex   As   Long,   ByVal   lpName   As   String,   lpcbName   As   Long,   ByVal   lpReserved   As   Long,   ByVal   lpClass   As   String,   lpcbClass   As   Long,   lpftLastWriteTime   As   Any)   As   Long  
  Private   Declare   Function   RegEnumValue   Lib   "advapi32.dll"   Alias   "RegEnumValueA"   (ByVal   hKey   As   Long,   ByVal   dwIndex   As   Long,   ByVal   lpValueName   As   String,   lpcbValueName   As   Long,   ByVal   lpReserved   As   Long,   lpType   As   Long,   lpData   As   Byte,   lpcbData   As   Long)   As   Long  
  Private   Declare   Function   RegQueryValueEx   Lib   "advapi32.dll"   Alias   "RegQueryValueExA"   (ByVal   hKey   As   Long,   ByVal   lpValueName   As   String,   ByVal   lpReserved   As   Long,   lpType   As   Long,   lpData   As   Any,   lpcbData   As   Long)   As   Long  
  Private   Sub   Form_Paint()  
          Dim   hKey   As   Long,   Cnt   As   Long,   sSave   As   String  
          Dim   strRet   As   String  
          Dim   lRet   As   Long  
          Me.Cls  
          Me.Print   "RegEnumValue:"  
          RegOpenKey   HKEY_LOCAL_MACHINE,   "HARDWARE\DEVICEMAP\SERIALCOMM",   hKey  
          Cnt   =   0  
          Do  
                  sSave   =   String(255,   0)  
                  If   RegEnumValue(hKey,   Cnt,   sSave,   255,   0,   ByVal   0&,   ByVal   0&,   ByVal   0&)   <>   0   Then   Exit   Do  
                  strRet   =   StripTerminator(sSave)  
                  Me.Print   strRet   &   vbTab;  
                  sSave   =   String(255,   0)  
                  If   RegQueryValueEx(hKey,   strRet,   0,   REG_SZ,   ByVal   sSave,   255)   =   0   Then  
                          strRet   =   StripTerminator(sSave)  
                          Me.Print   strRet  
                  End   If  
                  Cnt   =   Cnt   +   1  
          Loop  
          RegCloseKey   hKey  
  End   Sub  
  Private   Function   StripTerminator(sInput   As   String)   As   String  
          Dim   ZeroPos   As   Integer  
          ZeroPos   =   InStr(1,   sInput,   vbNullChar)  
          If   ZeroPos   >   0   Then  
                  StripTerminator   =   Left$(sInput,   ZeroPos   -   1)  
          Else  
                  StripTerminator   =   sInput  
          End   If  
  End   Function  
  Top

11 楼monkst(monkst)回复于 2002-08-01 13:13:18 得分 0

谢谢,太感谢了。  
  我还有一个问题,我想调用WINDOWS的配置窗口,可以吗?不行只好自己写了。  
  Top

12 楼daviddivad(你真行,居然比我还快! Scorpio)回复于 2002-08-01 13:37:26 得分 5

没试过,自己写不是更好,可以去除掉一些不需要配置的参数。设置返回也好控制啊。Top

相关问题

  • 串口通讯
  • 串口通讯!!!
  • 串口通讯
  • 串口通讯
  • 请教串口通讯问题
  • 请教VB串口通讯读数据
  • 串口通讯高手请进!!!!!!!!!!!!
  • 请帮帮忙:串口通讯
  • 串口通讯?[Delphi]
  • spcomm串口通讯

关键词

  • .net
  • 端口
  • com
  • hardware
  • stripterminator
  • byval
  • ssave
  • lpbports
  • zeropos
  • long

得分解答快速导航

  • 帖主:monkst
  • david1979210
  • daviddivad
  • mazhayang
  • CityBird
  • Pipi0714
  • Mailbomb
  • daviddivad
  • daviddivad

相关链接

  • Visual Basic类图书
  • Visual Basic类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo