cSerialPort Serial Communication Development Documentation
🚀 cSerialPort - Pure Win32 API VB6 serial communication class, fully encapsulating Windows serial communication capabilities
📖 Table of Contents
- Overview
- Core Features
- Comparison with MSComm Control
- Architecture Design
- Quick Start
- Documentation Index
Overview
cSerialPort is a serial communication class provided by VBManLib, directly calling Win32 API to implement complete serial communication functionality. Compared to the traditional MSComm control, it has no OCX dependency, supports ports above COM10, and allows precise control of low-level parameters, making it suitable for industrial control, device communication, Modbus, and other scenarios.
✨ Main Features
- 🔌 Pure API Implementation - No MSComm OCX control required, zero external dependencies
- 🎯 Complete Encapsulation - Covers open/close, read/write, configuration, signal lines, error handling, buffer management
- 📡 Event-Driven - Asynchronous polling monitoring, does not block UI thread
- 🔧 Precise Configuration - Complete DCB/COMMTIMEOUTS parameters, supports flow control, timeout presets
- 📊 Signal Line Control - Full set of DTR/RTS/Break/XON/XOFF signal line operations
- 🔍 Port Enumeration - Automatically scans available serial ports on the system
- 📦 Binary and Text - Supports both byte array and text read/write
- 🛡️ Error Diagnosis - Chinese error descriptions, complete status queries
Core Features
1️⃣ No OCX Dependency 🔌
The traditional MSComm control requires registration of MSCOMM32.OCX, which is cumbersome to deploy and cannot be used for ports above COM10. cSerialPort directly calls kernel32 API with zero dependencies.
2️⃣ Asynchronous Event Monitoring 📡
Uses Win32 Timer to periodically poll the buffer, automatically triggering the DataReceived event when new data is detected, without blocking the UI thread:
Dim WithEvents sp As cSerialPort
Private Sub Start()
Set sp = New cSerialPort
sp.PortName = "COM3"
sp.OpenPort
sp.StartMonitoring 50 ' 50ms polling
End Sub
Private Sub sp_DataReceived(ByVal BytesCount As Long)
Debug.Print "Received: " & sp.ReadExisting()
End Sub3️⃣ Complete Signal Line Control 📊
Supports manual DTR/RTS/Break control, as well as CTS/DSR/RING/CD status queries:
sp.SetDTR True ' Set DTR
sp.SetRTS True ' Set RTS
sp.SetBreak True ' Send Break signal
Debug.Print sp.CtsHolding ' Query CTS status4️⃣ Flexible Timeout Configuration ⏱️
Provides three preset modes, or manual precise control of each timeout parameter:
sp.Config.SetNonBlockingRead ' Non-blocking: return immediately
sp.Config.SetBlockingRead ' Blocking: wait for specified byte count
sp.Config.SetReadTimeout 2000 ' With timeout: 2 seconds5️⃣ Mode String Compatibility 🔤
Supports mode strings compatible with the BuildCommDCB API:
sp.Config.FromModeString "baud=9600 parity=N data=8 stop=1"6️⃣ Data Framing 🧩
Solve the "packet concatenation" problem caused by device continuous transmission, identifying the boundary of each frame:
- Plan B (Frame Interval Timeout): Set the
FrameIntervalproperty to automatically frame data using the pause after the device finishes sending one frame - Plan C (Protocol Frame Parser): The
cSerialFrameParserclass precisely splits by delimiter/start-end markers/length field/fixed length
' Plan B: 30ms no new data = one frame ends
sp.FrameInterval = 30
sp.StartMonitoring 20
Private Sub sp_FrameReceived(FrameData() As Byte)
Debug.Print "Received frame: " & StrConv(FrameData, vbUnicode)
End SubSee Framing Protocol Guide for details
Comparison with MSComm Control
| Feature | MSComm Control | cSerialPort Class |
|---|---|---|
| Dependency | Requires MSCOMM32.OCX registration | Pure API, zero dependencies |
| Port Limitation | Only COM1~COM9 | Supports COM10 and above |
| Event Model | OnComm event + CommEvent | Independent events (DataReceived, etc.) |
| Signal Line Control | DTREnable/RTSEnable properties | SetDTR/SetRTS/SetBreak methods |
| Timeout Control | None (only InputLen/Threshold) | Complete COMMTIMEOUTS five parameters |
| Flow Control | Handshaking property (limited) | Complete RTS/CTS, DTR/DSR, XON/XOFF |
| Buffer Management | InBufferCount/OutBufferCount | Same + PurgeRx/PurgeTx/PurgeAll |
| Error Diagnosis | No detailed errors | Chinese error descriptions + status strings |
| Binary Support | Input property | ReadData/WriteData byte arrays |
| Baud Rate | Up to 115200 | Up to 256000 (eBaudRate enum) |
| Data Framing | None (only RThreshold triggers) | FrameInterval + cSerialFrameParser, solve packet concatenation |
| Port Enumeration | None | EnumSerialPorts auto scan |
Architecture Design
Class Hierarchy
cSerialPort (Public Class)
├── m_Config: cSerialConfig (Configuration Object)
├── m_Handle: Long (Serial Port Handle)
├── m_TimerID: Long (Monitoring Timer)
└── Events: DataReceived, ErrorOccurred, PinChanged, TxEmpty, BreakDetected, RingDetectedSubmodule Classes
| Class/Module | File | Responsibility |
|---|---|---|
cSerialConfig | cSerialConfig.cls | Serial port configuration: encapsulates DCB and COMMTIMEOUTS, provides type-safe access; defines configuration enums (eBaudRate/eParity/eStopBits/eDtrControl/eRtsControl/eFlowControl) |
cSerialPort | cSerialPort.cls | Serial port main class; defines communication enums (eCommEvent/eCommError/eModemStatus) |
modSerialPortAPI | modSerialPortAPI.bas | API declarations, constants, types, helper functions |
Note: All
Public Enumare defined in class modules (not standard modules), because VB6 standard modulePublic Enumare not exported with the DLL type library. Moving them to class modules allows external projects referencing the DLL to use enum constants likebr115200,EV_RXCHAR,CE_RXOVER. Helper functions insidemodSerialPortAPI(such asGetCommErrorString) use underlying numeric values to avoid circular references with class modules.
Object Relationship Diagram
cSerialPort
├── Config (cSerialConfig)
│ ├── BuildDCB() → DCB structure
│ ├── BuildTimeouts() → COMMTIMEOUTS structure
│ └── Preset methods → Non-blocking/Blocking/Timeout modes
├── Handle (Serial Port Handle)
│ ├── ReadFile / WriteFile
│ ├── GetCommModemStatus (Signal Lines)
│ ├── ClearCommError (Errors/Status)
│ └── PurgeComm (Buffers)
└── Timer (Monitoring Timer)
└── Poll() → Triggers DataReceived eventWorkflow
1. Create cSerialConfig configuration parameters
2. cSerialPort.OpenPort() to open serial port
3. (Optional) StartMonitoring() to start event monitoring
4. WriteText/WriteData to send data
5. DataReceived event / ReadExisting to read data
6. ClosePort() to close serial portQuick Start
Minimal Send/Receive Example
Dim sp As New cSerialPort
sp.PortName = "COM3"
sp.Config.BaudRate = br115200
If sp.OpenPort() Then
sp.WriteText "Hello"
Debug.Print sp.ReadExisting()
sp.ClosePort
End IfEvent-Driven Send/Receive Example
Private WithEvents m_Port As cSerialPort
Private Sub Form_Load()
Set m_Port = New cSerialPort
m_Port.PortName = "COM3"
m_Port.Config.BaudRate = br9600
If m_Port.OpenPort() Then
m_Port.StartMonitoring 50
End If
End Sub
Private Sub m_Port_DataReceived(ByVal BytesCount As Long)
Debug.Print "Received: " & m_Port.ReadExisting()
End Sub
Private Sub Form_Unload(Cancel As Integer)
m_Port.ClosePort
End SubFor a more complete example, see Quick Start
Documentation Index
| Document | Description |
|---|---|
| Quick Start | Minimal reference, common scenario code examples |
| Properties Reference | Description, type, and usage of all properties |
| Methods Reference | Parameters, return values, and usage examples of all methods |
| Events Reference | Detailed description and usage examples of all events |
| Framing Protocol | Solve packet concatenation: frame interval framing + protocol frame parser |
| Advanced | Flow control, timeout strategies, binary protocols, virtual serial ports, etc. |
| FAQ | Common questions and solutions |
Last Updated: 2026-07-05