Serial Basic Class Base (WIN32) Stability Version Version 1.0 (200412)

xiaoxiao2021-03-06  68

/ * This version is a stable version of December. Many netizens have tried it, and give me a lot of valuable comments, because more stable, it is also suitable for most applications, there will be no more changes, so I decided to position 1.0; Welcome to letter feedback; correction content: read () function is not read after reading content; new readstring () function adds content after reading content; this modification may cause the original code error Others are sporadic modifications, and will not affect the original code; if (stat.cbinque> = _dwnotifynum) Here is the original> change to> = * // * Comm Base library (Win98 / NT / 2000) VER 1.0

Compile By: BC 5; C Builder 4, 5, 6, X; VC 5, 6; Vc.Net; GCC

Copyright (C) 2004.5 - 2004.12 Llbird Wushaojian@21cn.com

Note: As the basic code, in order to ensure the correctness of the source code, do not modify the following code, there is a problem to contact directly, you can inherit the features you need * /

#ifndef _cn_comm_h_ # define _CN_COMM_H_

#pragma Warning (Disable: 4530) #pragma Warning (Disable: 4786) #pragma Warning (Disable: 4800)

#include #include #include

// to the message window WPARAM port number #define ON_COM_RECEIVE WM_USER 618 #define ON_COM_CTS WM_USER 619 // LPARAM 1 valid #define ON_COM_DSR WM_USER 621 // LPARAM 1 valid # define ON_COM_RING WM_USER 623 # define ON_COM_RLSD WM_USER 624 #define ON_COM_BREAK WM_USER 625 # define ON_COM_TXEMPTY WM_USER 626 # define ON_COM_ERROR WM_USER 627 // LPARAM save Error ID # define DEFAULT_COM_MASK_EVENT EV_RXCHAR | EV_ERR | EV_CTS | EV_DSR | EV_BREAK | EV_TXEMPTY | EV_RING | EV_RLSD

Class cncomm {public:

// --------------------------------------------------------------------------------------------------------------------------------------- ---------------- // The first parameter is to start the monitoring thread when opening the serial port, and the second parameter is an IO method blocking method (0) / asynchronous overlap mode (Default) CNCOMM (Bool Fautobeginthread = true, dword dwiomode = file_flag_overlapped): _dwiomode (dwiomode), _fautobeginthread (fautobeginthread) {init ();

Virtual ~ cncomm () {close (); uninit ();

// ----------------------------------------- --------------------- // Judgment the serial port is or open Inline Bool Isopen () {return_hcommhandle! = Invalid_Handle_Value;} // Judgment the serial port is or open Operator Bool () {Return_HCOMMHANDLE! = Invalid_Handle_Value;} // Get serial port {return_hcommmmmhandle;} // get serial port} _hcommhandle;} // Get serial parameter DCB DCB * GetState () {RETURN Isopen () &&: getcommstate (_HCOMMHANDLE, & _DCB)? & _Dcb: null;} // Set serial parameter DCB BOOL setState (DCB * PDCB = NULL) {RETURN ISOPEN ()? :: setcommstate (_hcommhandle, PDCB == NULL? & _DCB: PDCB) == True: false;} // Setting serial parameters: baud rate, stop bit, etc. Support setting string "9600, 8, n, 1" BOOL setState (char * szsetstr) { IF (isopen ()) {if (! :: getcommstate (_hcommhandle, & _dcb)) Return False; if (! :: buildcommdcb (szsetstr, & _dcb)) Return false; return :: setcommstate (_hcommhandle, & _dcb) == True; } Return False;} // Setting serial parameters: baud rate, stop bit, etc. BOOL setState (DWORD DWBAUDRATE, DWORD DWPARIZE = 8, DWORD DWPARITY = Noparity, DWORD DWSTOPBI ts = ONESTOPBIT) {if (IsOpen ()) {if (:: GetCommState (_hCommHandle, & _DCB!)) return false; _DCB.BaudRate = dwBaudRate; _DCB.ByteSize = (unsigned char) dwByteSize; _DCB.Parity = (unsigned char ) dwParity; _DCB.StopBits = (unsigned char) dwStopBits; return :: SetCommState (_hCommHandle, & _DCB) == TRUE;} return false;} // get timeout structure LPCOMMTIMEOUTS GetTimeouts (void) {return IsOpen () && :: GetCommTimeouts (_HCOMMHANDLE, & _CO)? & _CO: NULL;} // Set timeout bool setTimeouts (lpcommtimeouts lpco) {RETURN ISOPEN ()? :: setcommtimeouts (_hcommmtimeouts (_hcommmhandle, lpco) ==

True: false;} // Set the serial port I / O buffer size Bool setBuffersize (DWOT DWINPUTSIZE, DWORD DWOUTPUTSIZE) {RETURN ISOPEN ()? :: setupcomm (_hcommhandle, dwinputsize, dwoutputsize) == true: false;} // Window Handle of Related Messages Inline Void SetWnd (HWND HWND) {Assert (:: Iswindow (HWND)); _HNOTIFYWND = HWND;} // Set send notification, accept character minimum inline void setNotifyNum (DWORD dwnum) {_dwnotifynum = dwnum } // thread Whether running inline Bool IsthreadRunning () {return_hthreadhandle! = Null;} // Get the thread handle inline handle getthread () {return_hthreadhandle;} // Set the event to monitor, open the valid Void setmaskevent before opening DWORD dwEvent = DEFAULT_COM_MASK_EVENT) {_dwMaskEvent = dwEvent;} // get the number of characters read buffer int GetInputSize () {COMSTAT Stat; DWORD dwError; return :: ClearCommError (_hCommHandle, & dwError, & Stat) Stat.cbInQue: (DWORD)? -1L;}

// ------------------------------------------------- --------------------- // Open the serial outlet 9600, 8, n, 1 BOOL Open (DWord dwport) {Return Open (dwport, 9600); // Open the serial port default BAUD_RATE, 8, N, 1 BOOL OPEN (DWORD DWPORT, DWORD DWBAUDRATE) {IF (DWPORT <1 | DWPORT> 1024) Return False;

Bindcommport (dwport);

IF (! OpenCommport ()) Return False;

IF (! setupport ()) Return False;

Return setState (DWBAUDRATE);} // Open the serial port, use a set string similar to "9600, 8, n, 1" to set the serial BOOL Open (DWord DWPort, Char * Szsetstr) {if (DWPORT <1 || dwport> 1024 Return False;

Bindcommport (dwport);

IF (! OpenCommport ()) Return False;

IF (! setupport ()) Return False;

Return setState (SZSTSTAT);} // Read serial port dwbufferLength characters to buffer Returns the number of characters read (LPVOID BUFFER, DWORD DWBufferLength, dword dwaittime = 20) {if (! iSopen ()) Return 0;

COMSTAT Stat; DWORD DWERROR;

IF (:: Clearcommorror (_hcommmhandle, & dwrror, & stat) && dwerror> 0) {:: purgeComm (_hcommhandle, purge_rxabort | purge_rxclear); return 0;}}}}} (! stat.cbinque) // Buffer countless RETURN 0;

Unsigned long ureadlength = 0;

DWBufferLength = dwbufferlength> stat.cbinque? stat.cbinque: dwbufferlength;

if {if (:: GetLastError () == ERROR_IO_PENDING) {WaitForSingleObject (_ReadOverlapped.hEvent, dwWaitTime) (:: ReadFile (_hCommHandle, Buffer, dwBufferLength, & uReadLength, & _ReadOverlapped)!); // end of the asynchronous I / O if (! :: GetOverlappedResult (_hCommHandle, & _ReadOverlapped, & uReadLength, false)) {! if (:: GetLastError () = ERROR_IO_INCOMPLETE) uReadLength = 0;}} else uReadLength = 0;} return uReadLength;} // reading the serial dwBufferLength - 1 th szBuffer character to return to ANSI C mode character string pointer for general communications char * ReadString (char * szBuffer, DWORD dwBufferLength, DWORD dwWaitTime = 20) {unsigned long uReadLength = Read (szBuffer, dwBufferLength - 1, dwWaitTime); szBuffer [uReadLength] = '/ 0'; RETURN SZBUFFER;} // Write serial port to write any data "abcd" or "/ x0 / x1 / x2" DWORD WRITE (LPVOID BUFFER, DWORD DWBufferLength) {if (! Isopen ()) Return 0; DWORD DWERROR;

IF (: Clearcommerror (_hcommhandle, & dwrror, null) && dwerror> 0) :: purgecomm (_hcommhandle, purge_txabort | purge_txclear);

Unsigned long uwriteLength = 0;

IF (! :: writefile (_hcommmhandle, buffer, dwbufferlength, & uwriteLength, & _writeoverlapped) if (: getLastError ()! = error_io_pending) uriteLength = 0;

Return UwriteLength;} // Write serial port Write ansi C mode string pointer DWORD WRITE (const char * szbuffer) {Assert (Szbuffer);

Return Write ((void *) szbuffer, strlen (szbuffer));} // write serial port synchronous application DWORD WRITESYNC (LPVOID BUFFER, DWORD DWBUFFERLENGTH) {if (! isopen ()) Return 0; dword dwerror; if (: clearcommorror (_hcommhandle, & dwrror, null) && dwerror> 0) :: purgeComm (_hcommhandle, purge_txabort | purge_txclear);

Unsigned long uwriteLength = 0;

:: Writefile (_HcommMhandle, Buffer, Dwbufferlength, & UwriteLength, Null;

Return UwriteLength;} // Write serial SZBuffer Output format string contains buffer length DWORD WRITE (CHAR * SZBUFFER, DWOR * SZFORMAT, ...) {if (! isopen ()) Return 0; VA_LIST VA; VA_Start (VA, SZFORMAT); _VSnprintf (Szbuffer, DwbufferLength, VA_END (VA);

Return Write (SZBuffer);} // Write serial SZBuffer can output a format string without checking the buffer length Carefully overflow DWORD WRITE (Char * szbuffer, char * szformat, ...) {if (! isopen ()) Return 0; VA_LIST VA; VA_START (VA, SZFORMAT); vSprintf (Szbuffer, Szformat, VA); VA_END (VA);

Return Write (SZBuffer);} // Close the serial port while closing the associated thread Virtual Void Close () {if (iSopen ()) {purgecomm (_hcommmhandle, purge_txabort | purge_txclear);

Endthread (); :: closehandle;

_hCommHandle = INVALID_HANDLE_VALUE;}} // DTR level control bool SetDTR (bool OnOrOff) {return IsOpen () EscapeCommFunction (_hCommHandle, OnOrOff SETDTR: CLRDTR?): false;} // RTS level control bool SetRTS (bool OnOrOff)? {? return IsOpen () EscapeCommFunction (? _hCommHandle, OnOrOff SETRTS: CLRRTS): false;} // bool SetBreak (bool OnOrOff) {return IsOpen () EscapeCommFunction (_hCommHandle, OnOrOff SETBREAK: CLRBREAK?):? false;} // Auxiliary thread control construction monitoring thread BOOL Beginthread () {i (! Isthreadrunning ()) {_frunflag = true; _hthreadhandle = null;

DWORD ID;

_hthreadhandle = :: CreateThread (Null, 0, CommthreadProc, this, 0, & id);

return (! _hThreadHandle = NULL);} return false;} // pause monitoring thread inline bool SuspendThread () {return IsThreadRunning () :: SuspendThread (_hThreadHandle) = 0xFFFFFFFF:?! false;} // resume monitoring thread inline bool ResumeThread () {return IsThreadRunning () :: ResumeThread (_hThreadHandle) = 0xFFFFFFFF:?! false;} // terminate the thread bool EndThread (DWORD dwWaitTime = 100) {if (IsThreadRunning ()) {_fRunFlag = false; :: SetCommMask (_hCommHandle , 0); :: SetEvent (_WaitOverlapped.hEvent); if (:: WaitForSingleObject (_hThreadHandle, dwWaitTime) = WAIT_OBJECT_0) if (:: TerminateThread (_hThreadHandle, 0!)) return false; :: CloseHandle (_hThreadHandle);!: : ResetEvent (_waitoverlapped.hevent);

_hthreadhandle = NULL;

Return true;} Return False;

protected:

Volatile dword _dwport; // Serial number volatile handle _hcommhandle; // serial handle char _szcommstr [20]; // Save Com 1 similar string

DCB _DCB; // baud rate, stop bit, etc. CommTimeouts _CO; // timeout structure

DWORD _DWIOMODE; // 0 Synchronous Default File_Flag_Overlapped overlap I / O Asynchronous Overlapped _Readoverlapped, _WriteOverlapped; // overlap I / O

volatile HANDLE _hThreadHandle; // secondary thread volatile HWND _hNotifyWnd; // notification window volatile DWORD _dwNotifyNum; // how many bytes accepted (> = _ dwNotifyNum) to send notification messages volatile DWORD _dwMaskEvent; // monitor events volatile bool _fRunFlag; // thread Run loop sign BOOL _FAUTOBEGINTHREAD; // open () Automatic BeginThread (); overlapped_waitoverlapped; // Waitcommevent Use

// Initialization void init () {MEMSET (_Szcommstr, 0, 20); Memset (& _ DCB, 0, SIZEOF (_dcb)); _dcb.dcblength = sizeof (_dcb); _hcommhandle = invalid_handle_value;

Memset (& _ Readoverlapped, 0, Sizeof (_Readoverlapped); MEMSET (& _ WriteOverlapped, 0, sizeof (_writeoverlapped);

_ReadOverlapped.hEvent = :: CreateEvent (NULL, true, false, NULL); assert (! _ReadOverlapped.hEvent = INVALID_HANDLE_VALUE); _WriteOverlapped.hEvent = :: CreateEvent (NULL, true, false, NULL); assert (_WriteOverlapped.hEvent! = INVALID_HANDLE_VALUE); _ hNotifyWnd = Null; _dwnotifynum = 0; _dwmaskevent = default_com_mask_event; _hthreadHandle = NULL;

memset (& _ WaitOverlapped, 0, sizeof (_WaitOverlapped)); _WaitOverlapped.hEvent = :: CreateEvent (NULL, true, false, NULL); assert (_WaitOverlapped.hEvent = INVALID_HANDLE_VALUE!);} // destructor void UnInit () {if (_Readoverlapped.hevent! = Invalid_handle_value) CloseHandle (_Readoverlapped.hevent);

IF (_WriteOverlapped.hevent! = invalid_handle_value) CloseHandle (_WriteOverlapped.hevent);

IF (_waitoverlapped.hevent! = invalid_handle_value) CloseHandle (_Waitoverlapped.hevent);} // Bind serial Void Bindcommport (dword dwport) {assert (dwport> = 1 && dwport <= 1024);

Char P [5];

_dwport = dwport; strcpy (_szcommstr, ".//com"); LTOA (_dwport, p, 10); strcat (_szcommstr, p);} // Open serial port Virtual Bool Opencommport () {if (isopen ()) Close ();

_hcommhandle = :: createfile (_szcommstr, generic_read | generic_write, 0, null, open_existing, file_attribute_normal | _dwiomode, null);

IF (_fautobeginthread) {if (isopen () && beginthread ()) return true; else {close (); // Create thread failed Return False;}} Return isopen ();} // Set serial port Virtual Bool setupport ()} IF (! isopen ()) Return False;

IF (! :: setupcomm (_hcommmhandle, 4096, 409)) Return False;

if (:: GetCommTimeouts (_hCommHandle, & _CO)!) return false; _CO.ReadIntervalTimeout = 0xFFFFFFFF; _CO.ReadTotalTimeoutMultiplier = 0; _CO.ReadTotalTimeoutConstant = 0; _CO.WriteTotalTimeoutMultiplier = 0; _CO.WriteTotalTimeoutConstant = 2000; if (::! Setcommtimeouts (_hcommmhandle, & _co)) Return False; if (! :: purgeComm (_hcommmhandle, purge_txabort | purge_rxabort | purge_txclear | purge_rxclear) Return False;

Return True;}

// -------------------------------------- Threads Callback ------- -------------------------------------------- // thread collection To the message, if the window handle is valid, send a message, including the serial number, all of the virtual function can extend Virtual void onRecEive () // ev_rxchar {if (: iswindow (_hNotifyWnd) :: postmessage (_HNOTIFYWND) :: postmessage , ON_COM_RECEIVE, WPARAM (_dwPort), LPARAM (0));} virtual void OnDSR () {if (:: IsWindow (_hNotifyWnd)) {DWORD Status; if (GetCommModemStatus (_hCommHandle, & Status)) :: PostMessage (_hNotifyWnd, ON_COM_DSR , Wparam (_dwport), LPARAM (status & ms_dsr_on)? 1: 0));}} Virtual void oncts () {if (: iswindow (_hnotifywnd)) {DWORD Status; if (GetcommmodemStatus (_hcommmmodemstatus) :: PostMessage (_hNotifyWnd, ON_COM_CTS, WPARAM (_dwPort), LPARAM ((Status & MS_CTS_ON) 1:? 0));}} virtual void OnBreak () {if (:: IsWindow (_hNotifyWnd)) {:: PostMessage (_hNotifyWnd , ON_COM_BREAK, WPARAM (_DWport), LParam (0));}} Virtual Void ONTXEMPTY () {=:10window (_HNOTIFYWND)) :: PostMessage (_HNOTIFYWND, ON_COM_TXEMPTY, WPARAM (_dwPort), LPARAM (0));} virtual void OnError () {DWORD dwError; :: ClearCommError (_hCommHandle, & dwError, NULL); if (:: IsWindow (_hNotifyWnd)) :: PostMessage (_hNotifyWnd, ON_COM_ERROR, WPARAM (_dwport);} Virtual void Onring () {if (: iswindow (_HNOTIFYWND)) :: PostMessage (_HNOTIFYWND, ON_COM_RING, WPARAM (_dwport), lparam (0));} Virtual Void Onrlsd ) {if (:: IsWindow (_hNotifyWnd)) :: PostMessage (_hNotifyWnd, ON_COM_RLSD, WPARAM (_dwPort), LPARAM (0));} virtual DWORD ThreadFunc (!) {if (:: SetCommMask (_hCommHandle, _dwMaskEvent)) { Char szbuffer [256]; _SnPrintf (SZBuffer, 255, "% s (% d): COM% D Call WinAPI setcommmask (% x,% x) fail, Thread Work INVALID! getLastError () =% D;"

, __File__, __line__, _dwport, _hcommhandle, _dwmaskevent, getLastError ()); MessageBox (Null, Szbuffer, "CLASS CNCOMMMMMMMM, MB_OK); Return 1;} comstat stat; dword dwerror;

for (DWORD dwLength, dwMask = 0; _fRunFlag && IsOpen (); dwMask = 0) {if (! :: WaitCommEvent (_hCommHandle, & dwMask, & _WaitOverlapped)) {if (:: GetLastError () == ERROR_IO_PENDING) // asynchronous: : GetoverlappedResult (_HcommMhandle, & _WaitoverLapped, & DwLength, true); else continue;}

IF (dwmask == 0) Continue;

Switch (dwmask) {copy ev_rxchar: :: clearcommerror (_hcommhandle, & dwerror, & stat); if (stat.cbinque> = _dwnotifynum) onRecEVE ()

Case EV_TXEMPTY: ONTXEMPTY (); BREAK;

Case EV_CTS: onCTS (); BREAK;

Case EV_DSR: ONDSR (); Break; Case EV_RING: OnRING ();

Case EV_RLSD: OnRlsd (); Break;

Case ev_break: Onbreak (); Break;

Case ev_err: Onerror (); Break;} // case} // for return 0;} private: // the function protected

CNCOMM (const cncomm &); const cncomm & operator = (const cncomm);

// Base Function for Thread Static DWORD WINAPI CommthreadProc (LPVOID LPPAR) {Return ((cncomm *) lppara) -> threadfunc ();}};

#ENDIF / / _ CN_COMM_H_

转载请注明原文地址:https://www.9cbs.com/read-91889.html

New Post(0)