I like to send and receive data on the serial Inteface(COM1) of the PC using
a VB6 program.
I know that the easiest way to do this would be to use the MSCOMM Control
but I would like to do this WITHOUT any activex control, just by calling
WINAPI functions.
In VB help I could find the function 'Createfile' together with several
other communication functions like 'SetCommConfig' or 'SetupComm' that
should reside in kernel32.lib.
Question: Does anyone has an example source code that shows how the com port
can be programmed in this way?
Even C code would also help.
Kind Regards
Peter
I have example code that uses the Win32API in my book. See below.
BTW, for a number of reasons, I MUCH prefer to use MSComm for my own
applications. I describe these reasons in the book, too.
--
Richard Grier (Microsoft Visual Basic MVP)
Hard & Software
12962 West Louisiana Avenue
Lakewood, CO 80228
303-986-2179 (voice)
303-986-3143 (fax)
Author of Visual Basic Programmer's Guide to Serial Communications, 2nd
Edition ISBN 1-890422-25-8 (355 pages).
For information look on my homepage at http://www.hardandsoftware.net.
Use the Books link to order. For faster service contact the publisher at
http://www.mabry.com/vbpgser.
-----Original Message-----
Dear API-Specialists
Kind Regards
Peter
.
Carlos Andres Becerra B.
"P.Hernández" <_remove_M...@coiim.es> escribió en el mensaje
news:59a601c0f8a2$e98f31c0$9be62ecf@tkmsftngxa03...
_________________________________________________________
Module: SerialPort.bas
_________________________________________________________
Option Explicit
Global ComNum As Long
Global bRead(255) As Byte
Type COMSTAT
fCtsHold As Long
fDsrHold As Long
fRlsdHold As Long
fXoffHold As Long
fXoffSent As Long
fEof As Long
fTxim As Long
fReserved As Long
cbInQue As Long
cbOutQue As Long
End Type
Type COMMTIMEOUTS
ReadIntervalTimeout As Long
ReadTotalTimeoutMultiplier As Long
ReadTotalTimeoutConstant As Long
WriteTotalTimeoutMultiplier As Long
WriteTotalTimeoutConstant As Long
End Type
Type DCB
DCBlength As Long
BaudRate As Long
fBinary As Long
fParity As Long
fOutxCtsFlow As Long
fOutxDsrFlow As Long
fDtrControl As Long
fDsrSensitivity As Long
fTXContinueOnXoff As Long
fOutX As Long
fInX As Long
fErrorChar As Long
fNull As Long
fRtsControl As Long
fAbortOnError As Long
fDummy2 As Long
wReserved As Integer
XonLim As Integer
XoffLim As Integer
ByteSize As Byte
Parity As Byte
StopBits As Byte
XonChar As Byte
XoffChar As Byte
ErrorChar As Byte
EofChar As Byte
EvtChar As Byte
End Type
Type OVERLAPPED
Internal As Long
InternalHigh As Long
offset As Long
OffsetHigh As Long
hEvent As Long
End Type
Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Declare Function GetLastError Lib "kernel32" () As Long
Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As
Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long,
lpOverlapped As Long) As Long
Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As
Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long,
lpOverlapped As Long) As Long
Declare Function SetCommTimeouts Lib "kernel32" (ByVal hFile As Long,
lpCommTimeouts As COMMTIMEOUTS) As Long
Declare Function GetCommTimeouts Lib "kernel32" (ByVal hFile As Long,
lpCommTimeouts As COMMTIMEOUTS) As Long
Declare Function BuildCommDCB Lib "kernel32" Alias "BuildCommDCBA" (ByVal
lpDef As String, lpDCB As DCB) As Long
Declare Function SetCommState Lib "kernel32" (ByVal hCommDev As Long, lpDCB
As DCB) As Long
Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal
lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As
Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As
Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As
Long
Declare Function FlushFileBuffers Lib "kernel32" (ByVal hFile As Long) As
Long
Function fin_com()
fin_com = CloseHandle(ComNum)
End Function
Function FlushComm()
FlushFileBuffers (ComNum)
End Function
Function Init_Com(ComNumber As String, Comsettings As String) As Boolean
On Error GoTo handelinitcom
Dim ComSetup As DCB, Answer, Stat As COMSTAT, RetBytes As Long
Dim retval As Long
Dim CtimeOut As COMMTIMEOUTS, BarDCB As DCB
' Open the communications port for read/write (&HC0000000).
' Must specify existing file (3).
ComNum = CreateFile(ComNumber, &HC0000000, 0, 0&, &H3, 0, 0)
If ComNum = -1 Then
MsgBox "Com Port " & ComNumber & " not available. Use Serial
settings (on the main menu) to setup your ports.", 48
Init_Com = False
Exit Function
End If
'Setup Time Outs for com port
CtimeOut.ReadIntervalTimeout = 20
CtimeOut.ReadTotalTimeoutConstant = 1
CtimeOut.ReadTotalTimeoutMultiplier = 1
CtimeOut.WriteTotalTimeoutConstant = 10
CtimeOut.WriteTotalTimeoutMultiplier = 1
retval = SetCommTimeouts(ComNum, CtimeOut)
If retval = -1 Then
retval = GetLastError()
MsgBox "Unable to set timeouts for port " & ComNumber & " Error: " &
retval
retval = CloseHandle(ComNum)
Init_Com = False
Exit Function
End If
retval = BuildCommDCB(Comsettings, BarDCB)
If retval = -1 Then
retval = GetLastError()
MsgBox "Unable to build Comm DCB " & Comsettings & " Error: " &
retval
retval = CloseHandle(ComNum)
Init_Com = False
Exit Function
End If
retval = SetCommState(ComNum, BarDCB)
If retval = -1 Then
retval = GetLastError()
MsgBox "Unable to set Comm DCB " & Comsettings & " Error: " & retval
retval = CloseHandle(ComNum)
Init_Com = False
Exit Function
End If
Init_Com = True
handelinitcom:
Exit Function
End Function
Function ReadCommPure() As String
On Error GoTo handelpurecom
Dim RetBytes As Long, i As Integer, ReadStr As String, retval As Long
Dim CheckTotal As Integer, CheckDigitLC As Integer
retval = ReadFile(ComNum, bRead(0), 255, RetBytes, 0)
ReadStr = ""
If (RetBytes > 0) Then
For i = 0 To RetBytes - 1
ReadStr = ReadStr & Chr(bRead(i))
Next i
Else
FlushComm
End If
'Return the string read from serial port
ReadCommPure = ReadStr
handelpurecom:
Exit Function
End Function
Function WriteCOM32(COMString As String) As Integer
On Error GoTo handelwritelpt
Dim RetBytes As Long, LenVal As Long
Dim retval As Long
If Len(COMString) > 255 Then
WriteCOM32 Left$(COMString, 255)
WriteCOM32 Right$(COMString, Len(COMString) - 255)
Exit Function
End If
For LenVal = 0 To Len(COMString) - 1
bRead(LenVal) = Asc(Mid$(COMString, LenVal + 1, 1))
Next LenVal
' bRead(LenVal) = 0
retval = WriteFile(ComNum, bRead(0), Len(COMString), RetBytes, 0)
' FlushComm
WriteCOM32 = RetBytes
handelwritelpt:
Exit Function
End Function
_________________________________________________________
RetError = Init_Com("COM2", "9600,n,8,1")
WriteCOM32 ("This is a test")
Call fin_com
I use a timer to check the inputbuffer of the comport
Private Sub TMRComm_Timer()
Me.txtInput1.Text = Me.txtInput1.Text + ReadCommPure()
FlushComm
End Sub
Succes André
das ist bestimmt das 5. Programm das ich sehe fuer diesen Zweck und jedesmal
sind die Type COMSTAT und DCB falsch deklariert.
> Type COMSTAT
> fCtsHold As Long
> fDsrHold As Long
> fRlsdHold As Long
> fXoffHold As Long
> fXoffSent As Long
> fEof As Long
> fTxim As Long
> fReserved As Long
Dies sind alles Teile einer einzelnen Long Variable und nicht alles Long
Variablen. Dieser Type ist nur 12 Byte lang und nicht wie hier angegeben 40.
Show mal genau in die Erlaeuterung zu diesem Typ. Da steht hinter fCtsHold
ein Doppelpunkt gefolgt von der Anzahl der Bits die es in dieser Long
Variable belegt.
> cbInQue As Long
> cbOutQue As Long
> End Type
>
>
> Type DCB
> DCBlength As Long
> BaudRate As Long
> fBinary As Long
> fParity As Long
> fOutxCtsFlow As Long
> fOutxDsrFlow As Long
> fDtrControl As Long
> fDsrSensitivity As Long
> fTXContinueOnXoff As Long
> fOutX As Long
> fInX As Long
> fErrorChar As Long
> fNull As Long
> fRtsControl As Long
> fAbortOnError As Long
> fDummy2 As Long
Hier genau das Gleiche wie oben.
> wReserved As Integer
> XonLim As Integer
> XoffLim As Integer
> ByteSize As Byte
> Parity As Byte
> StopBits As Byte
> XonChar As Byte
> XoffChar As Byte
> ErrorChar As Byte
> EofChar As Byte
> EvtChar As Byte
> End Type
>
Auch wenn das in diesem Beispiel keine Rolle spielt klappen andere Sachen
sonst nicht.
Viele Gruesse
Thomas
Thank you very much for your answer/correction to the declaration of
Andre's code.
I am writing in english that all other usegroup users can read it.
I understand that all these first variables of the structures COMSAT and DCB
are just single bits but if I want to use them, how does the declaration of
these two structures really look like in VB code?
Do I have to replace them with one long variable like:
Type COMSTAT
allControlbits as long
cbInQue As Long
cbOutQue As Long
End Type
or is there also a way to directly declare these bits like
Type COMSTAT
fCtsHold as "1Bit"?????
.
.
fReserved as "25Bits"?????
Another Questions:
What about the two methodes overlapped and nonoverlapped?
Which method should be used for which kind of application?
Does somebody have a sample code for overlapped mode?
Kind Regrads
Peter
"Thomas Schaefer" <thomas....@inkosoft.com> schrieb im Newsbeitrag
news:u8XaTws#AHA.1436@tkmsftngp05...
Thank you very much for your answer/correction to the declaration of
Andre's code.
I am writing in english that all other usegroup users can read it.
I understand that all these first variables of the structures COMSAT and DCB
are just single bits but if I want to use them, how does the declaration of
these two structures really look like in VB code?
Do I have to replace them with one long variable like:
Type COMSTAT
allControlbits as long
cbInQue As Long
cbOutQue As Long
End Type
or is there also a way to directly declare these bits like
Type COMSTAT
fCtsHold as "1Bit"?????
.
.
fReserved as "25Bits"?????
Another Questions:
What about the two methodes overlapped and nonoverlapped?
Which method should be used for which kind of application?
Does somebody have a sample code for overlapped mode?
Kind Regrads
Peter
"Thomas Schaefer" <thomas....@inkosoft.com> schrieb im Newsbeitrag
news:u8XaTws#AHA.1436@tkmsftngp05...
Thank you very much for your answer/correction to the declaration of
Andre's code.
I am writing in english that all other usegroup users can read it.
I understand that all these first variables of the structures COMSAT and DCB
are just single bits but if I want to use them, how does the declaration of
these two structures really look like in VB code?
Do I have to replace them with one long variable like:
Type COMSTAT
allControlbits as long
cbInQue As Long
cbOutQue As Long
End Type
or is there also a way to directly declare these bits like
Type COMSTAT
fCtsHold as "1Bit"?????
.
.
fReserved as "25Bits"?????
Another Questions:
What about the two methodes overlapped and nonoverlapped?
Which method should be used for which kind of application?
Does somebody have a sample code for overlapped mode?
Kind Regrads
Peter
"Thomas Schaefer" <thomas....@inkosoft.com> schrieb im Newsbeitrag
news:u8XaTws#AHA.1436@tkmsftngp05...
Thank you very much for your answer/correction to the declaration of
Andre's code.
I am writing in english that all other usegroup users can read it.
I understand that all these first variables of the structures COMSAT and DCB
are just single bits but if I want to use them, how does the declaration of
these two structures really look like in VB code?
Do I have to replace them with one long variable like:
Type COMSTAT
allControlbits as long
cbInQue As Long
cbOutQue As Long
End Type
or is there also a way to directly declare these bits like
Type COMSTAT
fCtsHold as "1Bit"?????
.
.
fReserved as "25Bits"?????
Another Questions:
What about the two methodes overlapped and nonoverlapped?
Which method should be used for which kind of application?
Does somebody have a sample code for overlapped mode?
Kind Regrads
Peter
"Thomas Schaefer" <thomas....@inkosoft.com> schrieb im Newsbeitrag
news:u8XaTws#AHA.1436@tkmsftngp05...
unfortunately there is no way in VB to declare bit data types. But of course
you can set the according values by OR'ing them with the Long variable. Or
you test the values by AND'ing them.
For example:
If you want to test if fCtsHold is set.
The Type looks something like:
Private Type COMSTAT
fBitMask As Long
'fCtsHold 1 Bit
'fDsrHold 1 Bit
'fRlsdHold 1 Bit
'fXoffHold 1 Bit
'fXoffSent 1 Bit
'fEof 1 Bit
'fTxim 1 Bit
'fReserved 25 Bits
cbInQue As Long
cbOutQue As Long
End Type
Dim CS as COMSTAT
If CS.fBitMask And 1 then Do Something if fCtsHold is set
or for fDsrHold
If CS.fBitMask And 2 then Do Something if fDsrHold is set
to set bits in this Type doesn't make sense.
For setting values in DCB you can use something like this.
Dim D as DCB
D.fBitMask = D.fBitMask Or 8192 ' RTS_CONTROL_HANDSHAKE
shouldn't be to hard to do to figure out which bits to set with which
values.
About the Overlapped flag.
To really use overlapping you need to subclass the form you are using to
know when the write request is finished. I don't use overlapping because
there are not a lot of circumstances that you really want that or even need
it. The MSDN holds extensive information on that topic.
Hope that answered your questions. If you have more feel free to ask.
Thomas
"Peter" <Pet...@myrealbox.com> wrote in message
news:uU8j8IL$AHA.872@tkmsftngp07...
Thank you very much for your help. I think I have learned a lot about the
COM ports from you.
Maybe you can also help me with my last COMM related question:
How can I detect how many physical,occupied and available COM-Ports I have
on my PC without using MSCOMM control(I have also posted this question
seperately on this newsgroup)?
For Example:the PC has 3 physical COM Ports in total(3 Hardware Cards
COM1-COM3).
I have Hyperterminal open and it occupies COM2, so COM2 is physically there
but my application can't use it at that time.
How can my VB program detect that COM2 is physically there but it is
occupied at the moment?
How can my VB program detect that there is no COM4 available at all?
My idea is that if there is a way to get the physical COM Ports from the
device manager(or registry) and then try to open each COM port with the
function CREATEFILE then everytime when CREATEFILE fails that COM port must
be occupied by another application?
Do you think this is the right way?
Do you know how to get the physical com ports?
Are there differences between Win9x and NT/2000 to get the physical COM
ports?
I would appreciate any help on this?
Kind Regards
Peter
"Thomas Schaefer" <thomas....@inkosoft.com> schrieb im Newsbeitrag
news:uH#cdvO$AHA.1108@tkmsftngp05...
i haven't had a close look into it but i can't remember a function to
retrieve the number of comports. The only thing i can think of and what will
work for sure is WMI. Maybe you want to try this.
Regards,
Thomas
"Peter" <Pet...@myrealbox.com> wrote in message
news:OGn0oga$AHA.1896@tkmsftngp03...
Thank you very much for your answer but what is WMI?
Kind Regards
Peter
"Thomas Schaefer" <thomas....@inkosoft.com> schrieb im Newsbeitrag
news:Os$pJ$a$AHA.564@tkmsftngp03...
have a look at this..
http://msdn.microsoft.com/library/default.asp?URL=/library/psdk/wmisdk/wmist
art_5kth.htm
Regards,
Thomas
"Peter" <Pet...@myrealbox.com> wrote in message
news:uomRhOOABHA.1952@tkmsftngp03...