VB -> PB conversion

Windows specific forum
ABBKlaus
Addict
Addict
Posts: 1143
Joined: Sat Apr 10, 2004 1:20 pm
Location: Germany

Post by ABBKlaus »

here is my approach :

Code: Select all

Structure API_PORT_INFO_2 
  PortName.s
  MonitorName.s
  Description.s
  PortType.l
  Reserved.l
EndStructure

Global NewList Portinfos.API_PORT_INFO_2()

Procedure.l GetAvailablePorts(ServerName.s="")
;http://www.purebasic.fr/english/viewtopic.php?p=215002#215002
  Protected res.l
  Protected pcbNeeded.l
  Protected pcReturned .l
  Protected *TempBuff
  Protected i.l
  Protected *pName
  
  If ServerName=""
    *pName=0
  Else
    *pName=@ServerName
  EndIf
  
  ;Dim PortsStruct(0 To 100) As API_PORT_INFO_2 
  
  ;Get the number of bytes needed To contain the Data returned by the API call 
  ret = EnumPorts_(*pName, 2, 0, 0, @pcbNeeded, @pcReturned) 
  If pcbNeeded
    Debug "pcbNeeded = "+Str(pcbNeeded)+" Bytes"
    *TempBuff = AllocateMemory(pcbNeeded) ; Allocate the Buffer 
    ret = EnumPorts_(*pName, 2, *TempBuff, pcbNeeded, @pcbNeeded, @pcReturned) 
    If ret
      Debug "Ports received = "+Str(pcReturned)
      ;Conversion is not needed, PB makes it ;-)
      For i = 0 To pcReturned - 1 
        ;set structure over the memory area
        *strPortinfos.PORT_INFO_2=*TempBuff+(i*SizeOf(PORT_INFO_2))
        AddElement(Portinfos())
        Portinfos()\PortName=PeekS(*strPortinfos\pPortName)
        Portinfos()\MonitorName=PeekS(*strPortinfos\pMonitorName)
        Portinfos()\Description=PeekS(*strPortinfos\pDescription)
        Portinfos()\PortType=*strPortinfos\fPortType
      Next
    EndIf
    ;Free the Heap Space allocated for the Buffer 
    If *TempBuff
      FreeMemory(*TempBuff)
    EndIf 
  EndIf
  
  ProcedureReturn pcReturned 
EndProcedure

If GetAvailablePorts("\\Klaus-Core2")
  ForEach Portinfos()
    Debug Portinfos()\PortName
    Debug Portinfos()\MonitorName
    Debug Portinfos()\Description
    Debug Portinfos()\PortType
    Debug "-------------------------------------------------------------"
  Next
EndIf
User avatar
dhouston
Enthusiast
Enthusiast
Posts: 430
Joined: Tue Aug 21, 2007 2:44 pm
Location: USA (Cincinnati)
Contact:

Post by dhouston »

Thank you.

Now, I'll try to work through it and understand the how and why of your conversion. I think this is the last major thing I needed get a handle on in order to start converting several VB apps to PB.
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Post by TerryHough »

Take a look here in my PureBasic web are too
http://elfecc.no-ip.info/purebasic/#Info_SerialPorts

Something I did long ago to check out the COM ports. Might help you.
User avatar
dhouston
Enthusiast
Enthusiast
Posts: 430
Joined: Tue Aug 21, 2007 2:44 pm
Location: USA (Cincinnati)
Contact:

Post by dhouston »

@TerryHough

I spent a few weeks reading the forums and cruising all the code archives I could find, bookmarking posts and web pages that looked helpful for the things I knew I would need to do. I bookmarked your page with the intention of returning to steal as much as I could carry but I haven't been able to connect to it since then until just now when the link worked fine. I have now downloaded your serial port, device enumeration, and atomic clock examples and will look them over. Thanks.
User avatar
dhouston
Enthusiast
Enthusiast
Posts: 430
Joined: Tue Aug 21, 2007 2:44 pm
Location: USA (Cincinnati)
Contact:

Post by dhouston »

Here's the debug output from my VB app followed by my partially converted PB app. COM1, COM3 & COM5 are valid serial ports.

Code: Select all

COM5          Virtual Serial Port          5 
COM3          USB to Serial Port           3 
COM1          Communications Port          1 
LPT1          EPSON Printer Port           1 
COM4          Infrared Serial (COM) Port   4 
LPT3          Infrared Printing (LPT) Port 3 
D-Link LPT port      Print Server          0 
FILE          Unknown Local Port           0 
FILE          Creates a file on disk       0 
COM5          Virtual Serial Port          5 
COM3          USB to Serial Port           3 
COM1          Communications Port          1 
LPT1          EPSON Printer Port           1 
COM4          Infrared Serial (COM) Port   4 
LPT3          Infrared Printing (LPT) Port  

pcbNeeded = 889 Bytes
Ports received = 15
COM5:    Local Port    Virtual Serial Port                1
-------------------------------------------------------------
COM3:    Local Port    USB to Serial Port                1
-------------------------------------------------------------
COM1:    Local Port    Communications Port           1
-------------------------------------------------------------
LPT1:      Local Port    EPSON Printer Port               3
-------------------------------------------------------------
COM4:    Local Port    Infrared Serial (COM) Port    1
-------------------------------------------------------------
LPT3:      Local Port    Infrared Printing (LPT) Port   3
-------------------------------------------------------------
D-Link LPT port     Local Port     Print Server           1
-------------------------------------------------------------
FILE:       Local Port    Unknown Local Port              1
-------------------------------------------------------------
FILE:       Local Port    Creates a file on disk           1
-------------------------------------------------------------
COM5:     Local Port    Virtual Serial Port                3
-------------------------------------------------------------
COM3:     Local Port    USB to Serial Port                3
-------------------------------------------------------------
COM1:     Local Port    Communications Port           3
-------------------------------------------------------------
LPT1:       Local Port    EPSON Printer Port              3
-------------------------------------------------------------
COM4:     Local Port    Infrared Serial (COM) Port   3
-------------------------------------------------------------
LPT3:       Local Port    Infrared Printing (LPT) Port  3
-------------------------------------------------------------
RichardL
Enthusiast
Enthusiast
Posts: 532
Joined: Sat Sep 11, 2004 11:54 am
Location: UK

Post by RichardL »

@dhouston
I have been trying to put a solution together to find all the real and virtual comm ports on a machine into a list; and stumbled on your code. After a bit of work I managed to get a list of ports that are supposed to be on my machine, but there seems to be too many :?

Did you ever take your code through to the bitter end? The problem I have is that some of the machines I run code on have a ton of Bluetooth virtual com ports and when I try to probe them to look for expected hardware I might as well go out for a beer it takes so long.

Any tips to stop me becoming an alcoholic?

Cheers
RichardL
User avatar
dhouston
Enthusiast
Enthusiast
Posts: 430
Joined: Tue Aug 21, 2007 2:44 pm
Location: USA (Cincinnati)
Contact:

Post by dhouston »

RichardL wrote:Did you ever take your code through to the bitter end? The problem I have is that some of the machines I run code on have a ton of Bluetooth virtual com ports and when I try to probe them to look for expected hardware I might as well go out for a beer it takes so long.
This code works well for me (under Windows) but I don't have any Bluetooth ports so it may need modification for them.

Code: Select all

;========================================================
;
; SerialPorts.pbi
;
;========================================================

Structure API_PORT_INFO_2
  PortName.s
  MonitorName.s
  Description.s
  PortType.l
  Reserved.l
EndStructure

#BufferIn = 1024
#BufferOut = 1024

Global ports.s,ComPort.s
Global NumPorts,ComID

Procedure.l GetAvailablePorts(ServerName.s="")
  NewList Portinfos.API_PORT_INFO_2()
  NewList ComPorts()
  Protected item.s,SaveSetting.s
  Protected res.l, pcbNeeded.l,pcReturned .l,i.l,ret.l
  Protected *TempBuff,*pName,*strPortinfos.PORT_INFO_2
  
  If ServerName=""
    *pName=0
  Else
    *pName=@ServerName
  EndIf
  
  ;Get the number of bytes needed To contain the Data returned by the API call
  ret=EnumPorts_(*pName,2,0,0,@pcbNeeded,@pcReturned)
  If pcbNeeded
    ;Debug "pcbNeeded = "+Str(pcbNeeded)+" Bytes"
    *TempBuff=AllocateMemory(pcbNeeded) ; Allocate the Buffer
    ret=EnumPorts_(*pName,2,*TempBuff,pcbNeeded,@pcbNeeded,@pcReturned)
    If ret
      ;Debug "Ports received = "+Str(pcReturned)
      For i = 0 To pcReturned - 1
        ;set structure over the memory area
        *strPortinfos.PORT_INFO_2=*TempBuff+(i*SizeOf(PORT_INFO_2))
        AddElement(Portinfos())
        Portinfos()\PortName=PeekS(*strPortinfos\pPortName)
        Portinfos()\MonitorName=PeekS(*strPortinfos\pMonitorName)
        Portinfos()\Description=PeekS(*strPortinfos\pDescription)
        Portinfos()\PortType=*strPortinfos\fPortType
;Debug Portinfos()\Description
;Debug Portinfos()\PortName
;Debug Portinfos()\PortType
;Debug Portinfos()\MonitorName
;Debug "-------------"
        If Not FindString(LCase(Portinfos()\Description),"infrared",1)
          If Not FindString(LCase(Portinfos()\Description),"modem",1)
            If Not FindString(ports,Portinfos()\PortName,1)
              If Left(Portinfos()\PortName,3)="COM" And FindString(Portinfos()\Description," Port",1)
                ComPort=RemoveString(Portinfos()\PortName,":")
                ComID=OpenSerialPort(#PB_Any,ComPort,19200,#PB_SerialPort_NoParity,8,1,#PB_SerialPort_NoHandshake,1024,1024)                                          
                If IsSerialPort(ComID)
                  AddElement(ComPorts())
                  ComPorts()=Val(Mid(Portinfos()\PortName,4,3))  ;COM1-COM256
                  CloseSerialPort(ComID):Delay(25)
                EndIf  
              EndIf  
            EndIf
          EndIf
        EndIf
      Next
    EndIf
    ComID=0:ports=""    
    SortList(ComPorts(),0)
    ForEach ComPorts()
      item="COM"+Str(ComPorts())+":"
      If FindString(ports,item,1)=0   ;avoid duplicates
        ports+item
        numPorts+1
      EndIf
    Next
;Debug ports    
    ;Free the Heap Space allocated For the Buffer
    If *TempBuff
      FreeMemory(*TempBuff)
    EndIf
  EndIf
  OpenPreferences("roZetta.prf"):PreferenceGroup("Global")
    ComPort=ReadPreferenceString("ComPort","COM1")
  ClosePreferences()
  ProcedureReturn pcReturned
EndProcedure
Any tips to stop me becoming an alcoholic?
You can send me the booze instead of drinking it yourself. :P
RichardL
Enthusiast
Enthusiast
Posts: 532
Joined: Sat Sep 11, 2004 11:54 am
Location: UK

Post by RichardL »

@dhouston

Hi, thanks for your assistance, I have delved into your code and modified it to make a simpler version for my purposes, which is to establish a list of available serial ports. I was quite surprised by the results when I tested it with various serial adaptors.

I have started a new thread with the title "Discovering ports with EnumPorts()", not in any way because your thread is a bad choice in which to continue, but to move under a more relevant title.

Again, thanks for your help.

RichardL
Post Reply