Since there are so many people asking this style, Beibei wrote it to Visual C ++ 4.2.
Window 95 serial communication function set (only applicable to 32 bits)
It should be noted that this is part of my program, so there are some parts irrelevant to the specific application.
But I think the key is the principle, not the program itself. I will introduce it later to help you understand this long program.
Header file (. H)
# Include "StdAfx. h"
# Define GWL_PGPSINFO 0
# Define GPSEXTRABYTES sizeof (LONG)
# Define MAXPORTS 4
# Define CN_SEND wm_user+ 100
# Define RXQUEUE 4096
# Define TXQUEUE 4096
// Cursor states
# Define CS_HIDE 0x00
# Define CS_SHOW 0x01
// Flow control flags
# Define FC_DTRDSR 0x01
# Define FC_RTSCTS 0x02
# Define FC_XONXOFF 0x04
// Ascii definitions
# Define ASCII_BEL 0x07
# Define ASCII_BS 0x08
# Define ASCII_LF 0x0A
# Define ASCII_CR 0x0D
# Define ASCII_XON 0x11
# Define ASCII_XOFF 0x13
// Data structures
Typedef struct tagGPSINFO
{
HANDLE idComDev;
BYTE bPort;
BOOL fConnected;
BYTE bByteSize, bParity, bStopBits;
DWORD dwBaudRate;
HANDLE hPostEvent, hWatchThread, hWatchEvent;
HWND implements mwnd;
DWORD dwThreadID;
OVERLAPPED osWrite, osRead;
} GPSINFO, * PGPSINFO;
# Define COMDEV (x) (x-> idComDev)
# Define PORT (x) (x-> bPort)
# Define CONNECTED (x) (x-> fConnected)
# Define BYTESIZE (x) (x-> bByteSize)
# Define PARITY (x) (x-> bParity)
# Define STOPBITS (x) (x-> bStopBits)
# Define BAUDRATE (x) (x-> dwBaudRate)
# Define POSTEVENT (x) (x-> hPostEvent)
# Define HTHREAD (x) (x-> hWatchThread)
# Define THREADID (x) (x-> dwThreadID)
# Define WRITE_ OS (x) (x-> osWrite)
# Define READ_ OS (x) (x-> osRead)
// Function prototypes (private)
Lresult near CreateGPSInfo (HWND, BYTE nPort = 1 );
Bool near DestroyGPSInfo ();
Int NEAR ReadCommBlock (LPSTR, int );
Bool near WriteCommBlock (LPSTR, DWORD );
Bool near OpenConnection ();
Bool near SetupConnection ();
Bool near CloseConnection ();
// Function prototypes (public)
Dword far pascal CommWatchProc (LPSTR );
For specific implementation, please refer to the following (for this article, I have broken the line twice)
CPP implementation:
# Include "StdAfx. h"
# Include "Com. h"
HWND hGPSWnd = NULL;
Pgpsinfo npgpsinfo = NULL;
Lresult near creategpsinfo (hwnd, byte nport)
{
If (null = (npgpsinfo = (pgpsinfo) localalloc (lptr, sizeof (gpsinfo ))))
Return (lresult)-1 );
Hgpswnd = hwnd;
Comdev (npgpsinfo) = 0;
Connected (npgpsinfo) = false;
Port (npgpsinfo) = nport;
Baudrate (npgpsinfo) = cbr_9600;
Bytesize (npgpsinfo) = 8;
Parity (npgpsinfo) = noparity;
Stopbits (npgpsinfo) = onestopbit;
Write_ OS (npgpsinfo). offset = 0;
Write_ OS (npgpsinfo). offsethigh = 0;
Read_ OS (npgpsinfo). offset = 0;
Read_ OS (npgpsinfo). offsethigh = 0;
// Create I/O event used for overlapped reads/writes
Read_ OS (npgpsinfo). hevent = createevent (null, true, false, null );
If (read_ OS (npgpsinfo). hevent = NULL)
{LocalFree (npGPSInfo );
Return (-1 );
}
WRITE_ OS (npGPSInfo). hEvent = CreateEvent (NULL, TRUE, FALSE, NULL );
If (NULL = WRITE_ OS (npGPSInfo). hEvent)
{CloseHandle (READ_ OS (npGPSInfo). hEvent );
LocalFree (npGPSInfo );
Return (-1 );
}
Return (LRESULT) TRUE );
}
Bool near DestroyGPSInfo ()
{
If (! NpGPSInfo) return (FALSE );
If (CONNECTED (npGPSInfo) CloseConnection ();
CloseHandle (READ_ OS (npGPSInfo). hEvent );
CloseHandle (WRITE_ OS (npGPSInfo). hEvent );
CloseHandle (POSTEVENT (npGPSInfo ));
LocalFree (npGPSInfo );
Return (TRUE );
}
Bool near OpenConnection ()
{
Char szPort [15];
Bool fretval;
Hcursor holdcursor, hwaitcursor;
Handle hcommwatchthread;
DWORD dwthreadid;
Commtimeouts;
If (! Npgpsinfo) Return (false );
Hwaitcursor = loadcursor (null, idc_wait );
Holdcursor = setcursor (hwaitcursor );
Wsprintf (szport, "Com % d", port (npgpsinfo ));
If
(Comdev (npgpsinfo) = createfile (szport, generic_read | generic_write,
0, null, open_existing, file_attribute_normal | file_flag_overlapped,
Null) = (handle)-1)
Return (false );
Else
{Setcommmask (comdev (npgpsinfo), ev_rxchar );
Setupcomm (comdev (npgpsinfo), 4096,4096 );
Purgecomm (comdev (npgpsinfo), purge_txabort | purge_rxabort | purge_txclear | purge_r
Xclear );
Commtimeouts. readintervaltimeout = 0 xffffffff;
Commtimeouts. readtotaltimeoutmultiplier = 0;
Commtimeouts. readtotaltimeoutconstant = 1000;
Commtimeouts. writetotaltimeoutmultiplier = 0;
Commtimeouts. writetotaltimeoutconstant = 1000;
Setcommtimeouts (comdev (npgpsinfo), & commtimeouts );
}
Fretval = setupconnection ();
If (fretval)
{Connected (npgpsinfo) = true;
If
(Null = (hcommwatchthread = createthread (lpsecurity_attributes) null,
0, (lpthread_start_routine) commwatchproc,
(Lpvoid) null, 0, & dwthreadid )))
{Connected (npgpsinfo) = false;
Closehandle (comdev (npgpsinfo ));
Fretval = false;
}
Else
{Threadid (npgpsinfo) = dwthreadid;
HTHREAD (npGPSInfo) = hCommWatchThread;
EscapeCommFunction (COMDEV (npGPSInfo), SETDTR );
}
}
Else
{CONNECTED (npGPSInfo) = FALSE;
CloseHandle (COMDEV (npGPSInfo ));
}
SetCursor (hOldCursor );
Return (fRetVal );
}
Bool near SetupConnection ()
{BOOL fRetVal;
DCB dcb;
If (! NpGPSInfo) return (FALSE );
Dcb. DCBlength = sizeof (DCB );
GetCommState (COMDEV (npGPSInfo), & dcb );
Dcb. BaudRate = BAUDRATE (npGPSInfo );
Dcb. ByteSize = BYTESIZE (npGPSInfo );
Dcb. Parity = PARITY (npGPSInfo );
Dcb. StopBits = STOPBITS (npGPSInfo );
Dcb. fOutxDsrFlow = FALSE;
Dcb. fDtrControl = DTR_CONTROL_ENABLE;
Dcb. fOutxCtsFlow = FALSE;
Dcb. fRtsControl = RTS_CONTROL_ENABLE;
Dcb. fInX = dcb. fOutX = FALSE;
Dcb. fBinary = TRUE;
Dcb. fParity = TRUE;
FRetVal = SetCommState (COMDEV (npGPSInfo), & dcb );
Return (fRetVal );
}
Bool near CloseConnection ()
{
If (! NpGPSInfo) return (FALSE );
CONNECTED (npGPSInfo) = FALSE;
SetCommMask (COMDEV (npGPSInfo), 0 );
While (THREADID (npGPSInfo )! = 0 );
EscapeCommFunction (COMDEV (npGPSInfo), CLRDTR );
PurgeComm (COMDEV (npGPSInfo), PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR );
CloseHandle (COMDEV (npGPSInfo ));
Return (TRUE );
}
Int NEAR ReadCommBlock (LPSTR lpszBlock, int nMaxLength)
{
Bool freadstat;
COMSTAT;
DWORD dwerrorflags;
DWORD dwlength;
DWORD dwerror;
If (! Npgpsinfo) Return (false );
Clearcommerror (comdev (npgpsinfo), & dwerrorflags, & COMSTAT );
Dwlength = min (DWORD) nmaxlength, COMSTAT. cbinque );
If (dwlength> 0)
{Freadstat = readfile (comdev (npgpsinfo), lpszblock,
Dwlength, & dwlength, & read_ OS (npgpsinfo ));
If (! Freadstat)
{If (getlasterror () = error_io_pending)
{Outputdebugstring ("Io pending ");
While (! Getoverlappedresult (comdev (npgpsinfo), & read_ OS (npgpsinfo), & dwlength, tr
UE ))
{Dwerror = getlasterror ();
If (dwerror = error_io_incomplete)
Continue;
}
}
Else
{Dwlength = 0;
Clearcommerror (comdev (npgpsinfo), & dwerrorflags, & COMSTAT );
}
}
}
Return (dwlength );
}
Bool near writecommblock (lpstr lpbyte, DWORD dwbytestowrite)
{Bool fwritestat;
DWORD dwbyteswritten;
DWORD dwerrorflags;
DWORD dwerror;
COMSTAT;
If (! Npgpsinfo) Return (false );
Fwritestat = writefile (comdev (npgpsinfo), lpbyte, dwbytestowrite,
& Dwbyteswritten, & write_ OS (npgpsinfo ));
If (! Fwritestat)
{If (getlasterror () = error_io_pending)
{While (! Getoverlappedresult (comdev (npgpsinfo ),
& Write_ OS (npgpsinfo), & dwbyteswritten, true ))
{Dwerror = getlasterror ();
If (dwError = ERROR_IO_INCOMPLETE)
Continue;
Else
{
ClearCommError (COMDEV (npGPSInfo), & dwErrorFlags, & ComStat );
Break;
}
}
}
Else
{
ClearCommError (COMDEV (npGPSInfo), & dwErrorFlags, & ComStat );
Return (FALSE );
}
}
Return (TRUE );
}
Dword far pascal CommWatchProc (LPSTR)
{DWORD dwEvtMask;
OVERLAPPED OS;
Int nLength;
BYTE abIn [1024];
Memset (& OS, 0, sizeof (OVERLAPPED ));
// Create I/O event used for overlapped read
OS. hEvent = CreateEvent (NULL, TRUE, FALSE, NULL );
If (OS. hEvent = NULL)
{MessageBox (NULL, "Failed to create event for thread! "," GPS
Error! ", MB_ICONEXCLAMATION | MB_ OK );
Return (FALSE );
}
If (! SetCommMask (COMDEV (npGPSInfo), EV_RXCHAR) return (FALSE );
While (CONNECTED (npGPSInfo ))
{DwEvtMask = 0;
WaitCommEvent (COMDEV (npGPSInfo), & dwEvtMask, NULL );
If (dwEvtMask & EV_RXCHAR) = EV_RXCHAR)
{Do
{If
(NLength = read commblock (LPSTR) abIn, 1024 ))
{
// WriteCommBlock (LPSTR) abIn, nLength );
* (AbIn + nLength) = 0;
: SendMessage (hGPSWnd, CN_SEND, nLength, (LONG) (LPSTR) abIn );
}
}
While (nLength> 0) & (CONNECTED (npGPSInfo )));
}
}
CloseHandle (OS. hEvent );
THREADID (npGPSInfo) = 0;
HTHREAD (npGPSInfo) = NULL;
Return (TRUE );
}
That's all. I hope it will be helpful to anyone who asks these questions!
Generally, the following sequence is used:
CreateGPSInfo (the notified window handle, serial port number 1 or 2 );
OpenConnection (); // establish a connection and it will call SetupConnection
DestroyGPSInfo (); // call CloseConnection to cancel the connection.
You can use ReadCommBlock/WriteCommBlock to read/write serial ports.
CommWatchProc is a thread that monitors the serial port and is established by OpenConnection.
When there is data in the serial port, it will notify the message (custom) that the window data of the 'notified window hander' is transmitted)
SendMessage (hGPSWnd, CN_SEND, nLength, (LONG) (LPSTR) abIn );
Okay, the article is over! Hope to help you!