|
|
|
|
/*! \mainpage ComComm v1.51 <20><><EFBFBD>̴߳<DFB3><CCB4><EFBFBD>ͨѶ<CDA8><D1B6>
|
|
|
|
|
* \section About <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
*
|
|
|
|
|
* \n <EFBFBD>汾: ComComm v1.51
|
|
|
|
|
* \n <EFBFBD><EFBFBD>;: WINDOWS/WINCE <EFBFBD><EFBFBD><EFBFBD>̴߳<EFBFBD><EFBFBD><EFBFBD>ͨѶ<EFBFBD><EFBFBD>
|
|
|
|
|
* \n <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: C++ (ANSI/UNICODE)
|
|
|
|
|
* \n ƽ̨: WINDOWS(WIN98/NT/2000/XP/2003/Vista); WINCE 5.0 ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>; Pocket PC 2003 ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
|
|
|
|
|
* \n Ӳ<EFBFBD><EFBFBD>: PC<EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; USB<EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
|
|
|
|
|
* \n <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: BC++ 5(free tool); C++ BUILDER 4, 5, 6, X; EVC 4(sp4); G++ 3, 4; Intel C++ 7, 8, 9; VC++ 6(sp6), .NET, 2003, 2005;
|
|
|
|
|
* \n <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: llbird
|
|
|
|
|
* \n <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: wushaojian@21cn.com
|
|
|
|
|
* \n <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: http://blog.csdn.net/wujian53 http://www.cppblog.com/llbird
|
|
|
|
|
* \n ά<EFBFBD><EFBFBD>: 2002.10 - 2009.8
|
|
|
|
|
*
|
|
|
|
|
* \section Announce ˵<EFBFBD><EFBFBD>
|
|
|
|
|
* \n 1) <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ü<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD>뱣<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
|
|
|
|
|
* \n 2) <EFBFBD><EFBFBD><EFBFBD>Ƽ<EFBFBD>ֱ<EFBFBD><EFBFBD><EFBFBD>ڱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, Ӧͨ<EFBFBD><EFBFBD>C++<EFBFBD>̳<EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
|
|
|
|
|
* \n 3) <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD>뷢һ<EFBFBD>ݸ<EFBFBD><EFBFBD>ң<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD>ѷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸĶ<EFBFBD>;
|
|
|
|
|
* \n 4) <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>cnComm1.4<EFBFBD><EFBFBD><EFBFBD>°汾, <EFBFBD>кܴ<EFBFBD><EFBFBD>Ķ<EFBFBD><EFBFBD><EFBFBD>ͬʱҲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ComComm;
|
|
|
|
|
* \n 5) <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><EFBFBD>ϻ<EFBFBD>, ˮƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD>ӭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>ṩ<EFBFBD><EFBFBD>ComComm<EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ;
|
|
|
|
|
*
|
|
|
|
|
* \section Log <EFBFBD><EFBFBD>־
|
|
|
|
|
* \n 2009 v1.51 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>п<EFBFBD><EFBFBD>ܲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٺʹ<EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>;
|
|
|
|
|
* \n 2009 v1.5 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>÷ֿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD>WINCE<EFBFBD><EFBFBD>֧<EFBFBD><EFBFBD>(ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>²<EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>);
|
|
|
|
|
* \n 2008 v1.4 <EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD>ͬ<EFBFBD><EFBFBD>IO<EFBFBD>Ķ<EFBFBD><EFBFBD>߳<EFBFBD>֧<EFBFBD><EFBFBD>; <EFBFBD><EFBFBD><EFBFBD><EFBFBD>C++<EFBFBD>쳣<EFBFBD><EFBFBD>֧<EFBFBD><EFBFBD>; <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ComComm; Cn == C Next;
|
|
|
|
|
* \n 2007 v1.3 ϸ<EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
|
|
|
|
|
* \n 2006 v1.2 ϸ<EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
|
|
|
|
|
* \n 2005 v1.1 ϸ<EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
|
|
|
|
|
* \n 2004 v1.0 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>VC<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>), <EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD>WINDOWƽ̨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>, <EFBFBD>״ι<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>cnComm;
|
|
|
|
|
* \n 2002 v0.1 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨѶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD>ͳC++<EFBFBD>ļ̳л<EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD>ͳC<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef COM_COMM_H
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#define COM_COMM_H
|
|
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
//#include <windows.h>
|
|
|
|
|
#include <tchar.h>
|
|
|
|
|
#include <afxwin.h>
|
|
|
|
|
|
|
|
|
|
#if defined(UNDER_CE) && !defined(CN_COMM_FOR_CE)
|
|
|
|
|
#define CN_COMM_FOR_CE UNDER_CE //!< <20><><EFBFBD><EFBFBD>WINCE<43><45>֧<EFBFBD><D6A7>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef CN_COMM_FOR_CE
|
|
|
|
|
#include <mcx.h>
|
|
|
|
|
#include <process.h> // WINCEû<45><C3BB>process.h
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef ON_COM_MSG_BASE
|
|
|
|
|
#define ON_COM_MSG_BASE WM_USER + 618 //!< <20><>Ϣ<EFBFBD><CFA2><EFBFBD>ŵĻ<C5B5><C4BB><EFBFBD>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// <20>͵<EFBFBD><CDB5><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>Ϣ WPARAM COM<4F>˿ں<CBBF>
|
|
|
|
|
#define ON_COM_RECEIVE ON_COM_MSG_BASE + 0 //!< EV_RXCHAR
|
|
|
|
|
#define ON_COM_RXCHAR ON_COM_MSG_BASE + 0 //!< EV_RXCHAR
|
|
|
|
|
#define ON_COM_CTS ON_COM_MSG_BASE + 1 //!< EV_CTS LPARAM==1 CTS ON
|
|
|
|
|
#define ON_COM_DSR ON_COM_MSG_BASE + 2 //!< EV_DSR LPARAM==1 DSR ON
|
|
|
|
|
#define ON_COM_RING ON_COM_MSG_BASE + 3 //!< EV_RING LPARAM==1 RING ON
|
|
|
|
|
#define ON_COM_RLSD ON_COM_MSG_BASE + 4 //!< EV_RLSD LPARAM==1 RLSD ON
|
|
|
|
|
#define ON_COM_BREAK ON_COM_MSG_BASE + 5 //!< EV_BREAK
|
|
|
|
|
#define ON_COM_TXEMPTY ON_COM_MSG_BASE + 6 //!< EV_TXEMPTY
|
|
|
|
|
#define ON_COM_ERROR ON_COM_MSG_BASE + 7 //!< EV_ERR LPARAM Error ID
|
|
|
|
|
#define ON_COM_RXFLAG ON_COM_MSG_BASE + 8 //!< EV_RXFLAG
|
|
|
|
|
#define ON_COM_POWER ON_COM_MSG_BASE + 9 //!< EV_POWER
|
|
|
|
|
#define ON_COM_EVENT1 ON_COM_MSG_BASE + 10//!< EV_EVENT1
|
|
|
|
|
#define ON_COM_EVENT2 ON_COM_MSG_BASE + 11//!< EV_EVENT2
|
|
|
|
|
#define ON_COM_RX80FULL ON_COM_MSG_BASE + 12//!< EV_RX80FULL
|
|
|
|
|
#define ON_COM_PERR ON_COM_MSG_BASE + 13//!< EV_PERR
|
|
|
|
|
#define ON_COM_CLOSE ON_COM_MSG_BASE + 14
|
|
|
|
|
|
|
|
|
|
#ifndef CN_COMM_WAIT_EVENT
|
|
|
|
|
#ifdef CN_COMM_FOR_CE
|
|
|
|
|
#define CN_COMM_WAIT_EVENT EV_RXCHAR | EV_ERR | EV_CTS | EV_DSR | EV_BREAK | EV_TXEMPTY | EV_RING | EV_RLSD | EV_POWER //!< WINCE Ĭ<>ϵĵȴ<C4B5><C8B4>¼<EFBFBD>| EV_RXFLAG
|
|
|
|
|
#else
|
|
|
|
|
#define CN_COMM_WAIT_EVENT EV_RXCHAR | EV_ERR | EV_CTS | EV_DSR | EV_BREAK | EV_TXEMPTY | EV_RING | EV_RLSD //!< WIN32 Ĭ<>ϵĵȴ<C4B5><C8B4>¼<EFBFBD>| EV_RXFLAG
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef CN_COMM_BUFFER_MIN_BLOCK_SIZE
|
|
|
|
|
#define CN_COMM_BUFFER_MIN_BLOCK_SIZE 1024 //!< <20><><EFBFBD>建<EFBFBD><E5BBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Сֵ
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if CN_COMM_BUFFER_MIN_BLOCK_SIZE < 4
|
|
|
|
|
#error CN_COMM_BUFFER_MIN_BLOCK_SIZE must >= 4 //!< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Сֵ<D0A1><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1>4
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//#define CN_ASSERT(E) ((E) ? true: assert(E))
|
|
|
|
|
#ifndef CN_ASSERT
|
|
|
|
|
#define CN_2STR(L) _T(#L) //!< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽLת<4C><D7AA><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
|
|
|
|
#define CN_LINE(L) CN_2STR(L) //!< <20><><EFBFBD>к<EFBFBD>Lת<4C><D7AA><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
|
|
|
|
/*! <20>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>쳣<EFBFBD><ECB3A3><EFBFBD>׳<EFBFBD><D7B3>쳣 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>潫<D4B0>˳<EFBFBD> <20><><EFBFBD>а<EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD>쳣<EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>κδ<CEBA><CEB4><EFBFBD> */
|
|
|
|
|
//#define CN_ASSERT(E) ((E) ? true : ComComm::Assert(_T("CN_ASSERT(")_T(#E)_T(") failed; ComComm(")CN_LINE(__LINE__)_T("); ")))
|
|
|
|
|
#define CN_ASSERT(E) ((E) ? true : ComComm::Assert(_T("CN_ASSERT")))
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//CN_COMM_STD_EXCEPTION CN_ASSERT <20><><EFBFBD>׳<EFBFBD><D7B3><EFBFBD>C++<2B>쳣
|
|
|
|
|
#ifdef CN_COMM_STD_EXCEPTION
|
|
|
|
|
#include <stdexcept> //throw runtime_error(msg)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//CN_COMM_VCL_EXCEPTION CN_ASSERT <20><><EFBFBD>׳<EFBFBD>VCL<43>쳣(C++ Builder)
|
|
|
|
|
#if defined(CN_COMM_VCL_EXCEPTION) && defined(__BORLANDC__)
|
|
|
|
|
#include <vcl.h> //throw new Exception(msg)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//CN_COMM_MFC_EXCEPTION CN_ASSERT <20><><EFBFBD>׳<EFBFBD>MFC<46>쳣(VC++)
|
|
|
|
|
#ifdef CN_COMM_MFC_EXCEPTION
|
|
|
|
|
#include <Afx.h> //throw new MfcException(msg)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
typedef void(__stdcall *ComCallback)(int nType, void *pThis);
|
|
|
|
|
|
|
|
|
|
class ComComm
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
//! <20>ٽ<EFBFBD><D9BD><EFBFBD>
|
|
|
|
|
struct InnerLock;
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
class BlockBuffer;
|
|
|
|
|
//! MFC<46>쳣
|
|
|
|
|
class MfcException;
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ<C4A3><CABD>ö<EFBFBD><C3B6>ֵ, 32λ<32><CEBB><EFBFBD><EFBFBD>
|
|
|
|
|
enum OptionEnum
|
|
|
|
|
{
|
|
|
|
|
EN_THREAD = 0x00000001, //!< <20><><EFBFBD>ü<EFBFBD><C3BC><EFBFBD><EFBFBD>߳<EFBFBD> <20><><EFBFBD>洮<EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> WatchThread
|
|
|
|
|
EN_OVERLAPPED = 0x00000002, //!< <20><><EFBFBD><EFBFBD><EFBFBD>첽<EFBFBD>ص<EFBFBD>IO<49><4F>ʽ
|
|
|
|
|
EN_RX_BUFFER = 0x00000004, //!< <20><><EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
EN_TX_BUFFER = 0x00000008, //!< <20><><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD>
|
|
|
|
|
EN_RX_THREAD = 0x00000010, //!< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD> <20><>ʱδ<CAB1><CEB4> ReadThread
|
|
|
|
|
EN_TX_THREAD = 0x00000020, //!< <20><><EFBFBD><EFBFBD>д<EFBFBD>߳<EFBFBD> <20><><EFBFBD><EFBFBD>WINCE<43><45>˫<EFBFBD><CBAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ӧͬʱ<CDAC><CAB1><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD> <20><><EFBFBD>洮<EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> WriteThread
|
|
|
|
|
EN_SUSPEND = 0x00000040, //!< <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>ʱ<EFBFBD><CAB1>ͣ
|
|
|
|
|
EN_ABOVE_NORMAL = 0x00000080, //!< <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
EN_FLUSH = 0x00000100, //!< <20><><EFBFBD>رմ<D8B1><D5B4><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28>˿ڻ<CBBF><DABB><EFBFBD><EFBFBD><EFBFBD>) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD>
|
|
|
|
|
EN_FLUSH_ALL = 0x00000200 //!< ͬ<><CDAC>(<28><><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD>弰<EFBFBD>˿ڶ<CBBF><DAB6><EFBFBD>) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>дģ<D0B4><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB>д<EFBFBD><D0B4> <20><><EFBFBD>ܵ<EFBFBD><DCB5><EFBFBD><EFBFBD>̹߳<DFB3><CCB9><EFBFBD><EFBFBD><EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD>
|
|
|
|
|
};
|
|
|
|
|
//! <20><><EFBFBD>캯<EFBFBD><ECBAAF> <20><><EFBFBD>þ<EFBFBD><C3BE><EFBFBD>Ӧ<EFBFBD><D3A6>ģʽ \param[in] dwOption <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>OptionEnum<75><6D><EFBFBD>϶<EFBFBD><CFB6><EFBFBD>
|
|
|
|
|
#ifdef CN_COMM_FOR_CE
|
|
|
|
|
//! WINCE:Ĭ<>ϴ<CFB4><F2BFAAB4><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD> <20><><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD> <20><><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD>
|
|
|
|
|
ComComm(DWORD dwOption = EN_THREAD )
|
|
|
|
|
#else
|
|
|
|
|
//! WIN32:Ĭ<>ϴ<CFB4><F2BFAAB4><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD> <20>첽<EFBFBD>ص<EFBFBD><D8B5><EFBFBD>ʽ
|
|
|
|
|
ComComm(DWORD dwOption = EN_THREAD | EN_OVERLAPPED)
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
Init();
|
|
|
|
|
SetOption(dwOption);
|
|
|
|
|
}
|
|
|
|
|
//! <20><>һģʽ<C4A3><CABD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>cnComm1~1.3 \param[in] bThread <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD> \param[in] bOverlapped <20><><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>I/O
|
|
|
|
|
ComComm(bool bThread, bool bOverlapped)
|
|
|
|
|
{
|
|
|
|
|
DWORD dwOption = 0;
|
|
|
|
|
|
|
|
|
|
if (bThread)
|
|
|
|
|
dwOption |= EN_THREAD;
|
|
|
|
|
|
|
|
|
|
if (bOverlapped)
|
|
|
|
|
dwOption |= EN_OVERLAPPED;
|
|
|
|
|
|
|
|
|
|
Init();
|
|
|
|
|
SetOption(dwOption);
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD> <20>Զ<EFBFBD><D4B6>رմ<D8B1><D5B4><EFBFBD>
|
|
|
|
|
virtual ~ComComm()
|
|
|
|
|
{
|
|
|
|
|
Close();
|
|
|
|
|
Destroy();
|
|
|
|
|
}
|
|
|
|
|
//<2F><><EFBFBD>ûص<C3BB>
|
|
|
|
|
void SetDataCallBack(ComCallback pCb,void *pUser)
|
|
|
|
|
{
|
|
|
|
|
m_pComCb = pCb;
|
|
|
|
|
m_pUser = pUser;
|
|
|
|
|
}
|
|
|
|
|
//<2F><><EFBFBD>ûص<C3BB>
|
|
|
|
|
void SetDataCallBack(std::function<void()> _pfn)
|
|
|
|
|
{
|
|
|
|
|
m_pfn = _pfn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD>첽<EFBFBD><ECB2BD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC>ģʽ<C4A3>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>,<2C><><EFBFBD><EFBFBD><EFBFBD>ü<EFBFBD>Ĭ<EFBFBD><C4AC> <20>첽,<2C>첽ʱ<ECB2BD><CAB1><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>Ч
|
|
|
|
|
void SetWorkMode(BOOL bAsync,DWORD lReadTimeout=250)
|
|
|
|
|
{
|
|
|
|
|
m_lReadTimeout = lReadTimeout;
|
|
|
|
|
if (!bAsync)
|
|
|
|
|
{
|
|
|
|
|
DWORD dwOption = EN_THREAD;
|
|
|
|
|
SetOption(dwOption);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DWORD dwOption = EN_THREAD | EN_OVERLAPPED;
|
|
|
|
|
SetOption(dwOption);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//! <20>жϴ<D0B6><CFB4><EFBFBD><EFBFBD>ǻ<EFBFBD><C7BB><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
bool IsOpen()
|
|
|
|
|
{
|
|
|
|
|
return hComm_ != INVALID_HANDLE_VALUE;
|
|
|
|
|
}
|
|
|
|
|
//! <20>жϴ<D0B6><CFB4><EFBFBD><EFBFBD>ǻ<EFBFBD><C7BB><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
operator bool ()
|
|
|
|
|
{
|
|
|
|
|
return hComm_ != INVALID_HANDLE_VALUE;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ô<EFBFBD><C3B4>ھ<EFBFBD><DABE><EFBFBD>
|
|
|
|
|
HANDLE GetHandle()
|
|
|
|
|
{
|
|
|
|
|
return hComm_;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ô<EFBFBD><C3B4>ھ<EFBFBD><DABE><EFBFBD>
|
|
|
|
|
operator HANDLE()
|
|
|
|
|
{
|
|
|
|
|
return hComm_;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
DWORD GetPort()
|
|
|
|
|
{
|
|
|
|
|
return dwPort_;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ô<EFBFBD><C3B4><EFBFBD>ȫ<EFBFBD><C8AB>
|
|
|
|
|
LPCTSTR GetPortName()
|
|
|
|
|
{
|
|
|
|
|
return szName_;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>ComComm<6D>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><C3B2><EFBFBD> <20><><EFBFBD><EFBFBD>32λ<32><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
DWORD GetOption()
|
|
|
|
|
{
|
|
|
|
|
return dwOption_;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>ComComm<6D>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><C3B2><EFBFBD> <20>ڴ<DAB4><F2BFAAB4><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> \param[in] dwOption 32λ<32><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
void SetOption(DWORD dwOption)
|
|
|
|
|
{
|
|
|
|
|
CN_ASSERT(!IsOpen());//! <20><><EFBFBD><EFBFBD>״̬<D7B4>²<EFBFBD><C2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><C3B2><EFBFBD>
|
|
|
|
|
|
|
|
|
|
dwOption_ = dwOption;
|
|
|
|
|
|
|
|
|
|
#ifdef CN_COMM_FOR_CE
|
|
|
|
|
CN_ASSERT(!IsOverlappedMode()); //! WINCE<43><45><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD>ص<EFBFBD>IO <20><>EN_OVERLAPPED<45><44><EFBFBD><EFBFBD>
|
|
|
|
|
dwOption_ &= (~EN_OVERLAPPED);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
//! <20><EFBFBD>ComComm<6D>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><C3B2><EFBFBD> <20>ڴ<DAB4><F2BFAAB4><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> \param[in] dwRemove ɾ<><C9BE><EFBFBD><EFBFBD>32λ<32><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> \param[in] dwAdd <20><><EFBFBD>ӵ<EFBFBD>32λ<32><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
void ModifyOption(DWORD dwRemove, DWORD dwAdd)
|
|
|
|
|
{
|
|
|
|
|
CN_ASSERT(!IsOpen());//! <20><><EFBFBD><EFBFBD>״̬<D7B4>²<EFBFBD><C2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><C3B2><EFBFBD>
|
|
|
|
|
|
|
|
|
|
dwOption_ &= ~dwRemove;
|
|
|
|
|
dwOption_ |= dwAdd;
|
|
|
|
|
|
|
|
|
|
#ifdef CN_COMM_FOR_CE
|
|
|
|
|
CN_ASSERT(!IsOverlappedMode()); //! WINCE<43><45><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD>ص<EFBFBD>IO <20><>EN_OVERLAPPED<45><44><EFBFBD><EFBFBD>
|
|
|
|
|
dwOption_ &= (~EN_OVERLAPPED);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
//! <20>Ƿ<EFBFBD><C7B7>ص<EFBFBD>IOģʽ
|
|
|
|
|
bool IsOverlappedMode()
|
|
|
|
|
{
|
|
|
|
|
return dwOption_ & EN_OVERLAPPED ? true : false;
|
|
|
|
|
}
|
|
|
|
|
//! <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ
|
|
|
|
|
bool IsTxBufferMode()
|
|
|
|
|
{
|
|
|
|
|
return dwOption_ & EN_TX_BUFFER ? true : false;
|
|
|
|
|
}
|
|
|
|
|
//! <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>뻺<EFBFBD><EBBBBA><EFBFBD><EFBFBD>ģʽ
|
|
|
|
|
bool IsRxBufferMode()
|
|
|
|
|
{
|
|
|
|
|
return dwOption_ & EN_RX_BUFFER ? true : false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//! <20>趨<EFBFBD><E8B6A8><EFBFBD><EFBFBD>֪ͨ, <20><><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>Сֵ
|
|
|
|
|
void SetNotifyNum(DWORD dwNum)
|
|
|
|
|
{
|
|
|
|
|
dwNotifyNum_ = dwNum;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD>߳̾<DFB3><CCBE><EFBFBD> \param[in] iOption EN_THREAD<41><44><EFBFBD><EFBFBD>hWatchThread_ EN_RX_THREAD<41><44><EFBFBD><EFBFBD>hReadThread_ EN_TX_THREAD<41><44><EFBFBD><EFBFBD>hWriteThread_ \return HANDLE <20>߳̾<DFB3><CCBE><EFBFBD>
|
|
|
|
|
HANDLE GetThread(int iOption = EN_THREAD)
|
|
|
|
|
{
|
|
|
|
|
return iOption == EN_THREAD ? hWatchThread_ : ((iOption == EN_RX_THREAD) ? hReadThread_ : hWriteThread_);
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>ӵ<EFBFBD><D3B5>¼<EFBFBD><C2BC><EFBFBD> <20><><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч
|
|
|
|
|
void SetWaitEvent(DWORD dwEvent = CN_COMM_WAIT_EVENT)
|
|
|
|
|
{
|
|
|
|
|
CN_ASSERT(!IsOpen());///<2F><><EFBFBD><EFBFBD>״̬<D7B4>²<EFBFBD><C2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><C3B2><EFBFBD>
|
|
|
|
|
|
|
|
|
|
dwWaitEvent_ = dwEvent;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>뻺<EFBFBD><EBBBBA><EFBFBD><EFBFBD>
|
|
|
|
|
BlockBuffer& Input()
|
|
|
|
|
{
|
|
|
|
|
return I_;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
BlockBuffer& Output()
|
|
|
|
|
{
|
|
|
|
|
return O_;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD> \param[in] bInput Ϊtrue<75><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,Ĭ<><C4AC>Ϊtrue <20>ص<EFBFBD>IO<49><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Dz<EFBFBD><C7B2><EFBFBD>ȷ<EFBFBD><C8B7> <20><>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3>̨<EFBFBD><CCA8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>
|
|
|
|
|
DWORD GetCounter(bool bInput = true)
|
|
|
|
|
{
|
|
|
|
|
return bInput ? dwInCount_ : dwOutCount_;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
void ResetCounter()
|
|
|
|
|
{
|
|
|
|
|
dwInCount_ = dwOutCount_ = 0;
|
|
|
|
|
}
|
|
|
|
|
//! <20><EFBFBD><F2BFAAB4><EFBFBD> <20><>ע<EFBFBD><D7A2><EFBFBD><EFBFBD>cnComm1~1.3<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> cnComm1~1.3<EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>9600, n, 8, 1<><31><EFBFBD>ö˿<C3B6> <20><>1.5<EFBFBD><EFBFBD>ֻ<EFBFBD>˿ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵȲ<EFBFBD><EFBFBD><EFBFBD> \param[in] dwPort <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1~1024
|
|
|
|
|
bool Open(DWORD dwPort)
|
|
|
|
|
{
|
|
|
|
|
if (!CN_ASSERT(dwPort>=1 && dwPort<=1024))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
BindPort(dwPort);
|
|
|
|
|
|
|
|
|
|
if(!CN_ASSERT(OpenPort()))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if(!CN_ASSERT(SetupPort()))
|
|
|
|
|
return Close(), false;
|
|
|
|
|
|
|
|
|
|
if ((dwOption_ & (EN_THREAD|EN_RX_THREAD|EN_TX_THREAD)) && !CN_ASSERT(BeginThread()))
|
|
|
|
|
return Close(), false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
/*! \param[in] dwPort <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1~1024 \param[in] dwBaudRate <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> \param[in] btParity <20><>żУ<C5BC><D0A3> \param[in] btByteSize <20><><EFBFBD><EFBFBD>λ<EFBFBD><CEBB> \param[in] btStopBits ֹͣλ<D6B9><CEBB> */
|
|
|
|
|
//! <20><EFBFBD><F2BFAAB4><EFBFBD> ȱʡ 9600, n, 8, 1 \sa bool Open(DWORD dwPort, LPCTSTR szSetStr)
|
|
|
|
|
bool Open(DWORD dwPort, DWORD dwBaudRate, BYTE btParity = NOPARITY, BYTE btByteSize = 8, BYTE btStopBits = ONESTOPBIT)
|
|
|
|
|
{
|
|
|
|
|
if (!CN_ASSERT(dwPort>=1 && dwPort<=1024))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
BindPort(dwPort);
|
|
|
|
|
|
|
|
|
|
if (!CN_ASSERT(OpenPort()))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (!CN_ASSERT(SetState(dwBaudRate, btParity, btByteSize, btStopBits)))
|
|
|
|
|
return Close(), false;
|
|
|
|
|
|
|
|
|
|
if (!CN_ASSERT(SetupPort()))
|
|
|
|
|
return Close(), false;
|
|
|
|
|
|
|
|
|
|
if ((dwOption_ & (EN_THREAD|EN_RX_THREAD|EN_TX_THREAD)) && !CN_ASSERT(BeginThread()))
|
|
|
|
|
return Close(), false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
#ifndef CN_COMM_FOR_CE
|
|
|
|
|
/*! \param[in] dwPort <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1~1024 \param[in] szSetStr <20>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "BBBB,P,D,S" <20><>: "9600,N,8,1" "1200,O,7,2"
|
|
|
|
|
BBBBΪ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> PΪ<EFBFBD><EFBFBD>żУ<EFBFBD><EFBFBD>(E | M | N | O | S) DΪ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD>(4 ~ 8) SΪֹͣλ<EFBFBD><EFBFBD>(1 | 1.5 | 2)
|
|
|
|
|
\code Open(1, "9600,E,8,2"); \endcode \b <EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>鷵<EFBFBD><EFBFBD>ֵ
|
|
|
|
|
<EFBFBD><EFBFBD>֧<EFBFBD><EFBFBD>WINCE, ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD>д<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD>WINCEӲ<EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD>ֲ<EFBFBD>Կ<EFBFBD><EFBFBD>ܲ<EFBFBD><EFBFBD><EFBFBD>, <EFBFBD>ʴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>汾<EFBFBD><EFBFBD>ɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
|
|
//! <20><EFBFBD><F2BFAAB4><EFBFBD>, <20>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><C3B4><EFBFBD>
|
|
|
|
|
bool Open(DWORD dwPort, LPCTSTR szSetStr)
|
|
|
|
|
{
|
|
|
|
|
if (!CN_ASSERT(dwPort>=1 && dwPort<=1024))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
BindPort(dwPort);
|
|
|
|
|
|
|
|
|
|
if (!CN_ASSERT(OpenPort()))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (!CN_ASSERT(SetState(szSetStr)))
|
|
|
|
|
return Close(), false;
|
|
|
|
|
|
|
|
|
|
if (!CN_ASSERT(SetupPort()))
|
|
|
|
|
return Close(), false;
|
|
|
|
|
|
|
|
|
|
if ((dwOption_ & (EN_THREAD|EN_RX_THREAD|EN_TX_THREAD)) && !CN_ASSERT(BeginThread()))
|
|
|
|
|
return Close(), false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
/*! \param[in] dwPort <20><>ʱ<EFBFBD>ò<EFBFBD><C3B2><EFBFBD>û<EFBFBD>о<EFBFBD><D0BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>壬<EFBFBD><E5A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ֪ͨ<CDA8>б<EFBFBD><D0B1><EFBFBD><EFBFBD>˿ںţ<DABA>Ӧע<D3A6>ⲻ<EFBFBD><E2B2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˿ں<CBBF><DABA>ظ<EFBFBD>
|
|
|
|
|
\param[in] szPortName Ϊָ<EFBFBD><EFBFBD><EFBFBD>Ķ˿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>WINDOWS<EFBFBD><EFBFBD>\\\\.\\COM1<EFBFBD><EFBFBD><EFBFBD><EFBFBD>WINCE<EFBFBD><EFBFBD>COM1: , <EFBFBD><EFBFBD>Щ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
\param[in] dwBaudRate <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> \param[in] btParity <EFBFBD><EFBFBD>żУ<EFBFBD><EFBFBD> \param[in] btByteSize <EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD> \param[in] btStopBits ֹͣλ<EFBFBD><EFBFBD>
|
|
|
|
|
\code Open(9999, "COM3:", 2400); \endcode \code Open(1028, "COM3:", 9600, N, 7, ONESTOPBIT); \endcode */
|
|
|
|
|
//! ָ<><D6B8><EFBFBD>Ķ˿<C4B6><CBBF><EFBFBD><EFBFBD>ƴ<C6B4><F2BFAAB4><EFBFBD>
|
|
|
|
|
bool Open(DWORD dwPort, LPCTSTR szPortName, DWORD dwBaudRate, BYTE btParity = NOPARITY, BYTE btByteSize = 8, BYTE btStopBits = ONESTOPBIT)
|
|
|
|
|
{
|
|
|
|
|
if(!CN_ASSERT(_tcslen(szPortName) < 64 - 1))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
_tcscpy_s(szName_, szPortName);
|
|
|
|
|
dwPort_ = dwPort;//<2F><><EFBFBD><EFBFBD>֪ͨ<CDA8><D6AA>Ϣ
|
|
|
|
|
|
|
|
|
|
if (!CN_ASSERT(OpenPort()))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (!CN_ASSERT(SetState(dwBaudRate, btParity, btByteSize, btStopBits)))
|
|
|
|
|
return Close(), false;
|
|
|
|
|
|
|
|
|
|
if (!CN_ASSERT(SetupPort()))
|
|
|
|
|
return Close(), false;
|
|
|
|
|
|
|
|
|
|
if ((dwOption_ & (EN_THREAD|EN_RX_THREAD|EN_TX_THREAD)) && !CN_ASSERT(BeginThread()))
|
|
|
|
|
return Close(), false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
//! ֱ<>Ӷ<EFBFBD><D3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˿<EFBFBD> \param[out] pBuffer Ŀ<>껺<EFBFBD><EABBBA><EFBFBD><EFBFBD> \param[in] dwLength <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD> \param[in] dwWaitTime <20>ȴ<EFBFBD>ʱ<EFBFBD><CAB1>(Ĭ<><C4AC>INFINITE) \return <20><><EFBFBD><EFBFBD>ʵ<EFBFBD>ʶ<EFBFBD>ȡ<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
|
|
|
|
|
DWORD ReadPort(LPVOID pBuffer, DWORD dwLength, DWORD dwWaitTime = INFINITE)
|
|
|
|
|
{
|
|
|
|
|
if (!IsOpen())
|
|
|
|
|
{
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
COMSTAT Stat;
|
|
|
|
|
DWORD dwError, dwReadResult = 0;
|
|
|
|
|
|
|
|
|
|
if(!CN_ASSERT(IsOpen()) || !dwLength)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if(::ClearCommError(hComm_, &dwError, &Stat) && dwError > 0)
|
|
|
|
|
::PurgeComm(hComm_, PURGE_RXABORT);
|
|
|
|
|
|
|
|
|
|
#ifndef CN_COMM_FOR_CE
|
|
|
|
|
if (IsOverlappedMode())//! <20>ص<EFBFBD>I/O<><4F> dwWaitTime==INFINITE <20><><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD><C8BB>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ɳ<EFBFBD>ʱ<EFBFBD>ṹ<EFBFBD><E1B9B9><EFBFBD><EFBFBD> Ĭ<><C4AC><EFBFBD>趨0.5<EFBFBD><EFBFBD>
|
|
|
|
|
{
|
|
|
|
|
if (dwWaitTime == INFINITE)//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD><EFBFBD> ֱ<>Ӷ<EFBFBD>ȡ<EFBFBD>˿ڽ<CBBF><DABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>൱<EFBFBD><E0B5B1>ԭ<EFBFBD><D4AD>1.3<EFBFBD>汾 Read(pBuffer, dwLength, false);
|
|
|
|
|
{
|
|
|
|
|
if (!::ReadFile(hComm_, pBuffer, dwLength, &dwReadResult, &RO_))
|
|
|
|
|
{//! <20>ڽ<EFBFBD><DABD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>ComComm<6D>Ƽ<EFBFBD>ʹ<EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>dwWaitTimeָ<65><D6B8><EFBFBD><EFBFBD>ʱʱ<CAB1><CAB1>
|
|
|
|
|
if (CN_ASSERT(::GetLastError() == ERROR_IO_PENDING))
|
|
|
|
|
{
|
|
|
|
|
while (!CN_ASSERT(::GetOverlappedResult(hComm_, &RO_, &dwReadResult, TRUE)))
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else//! <20>ص<EFBFBD>I/O<><4F> dwWaitTime!=INFINITE <20><><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>dwWaitTime<6D><65><EFBFBD><EFBFBD>
|
|
|
|
|
{ //! dwWaitTime = 0 <20>൱<EFBFBD><E0B5B1>ԭ<EFBFBD><D4AD>1.3<EFBFBD>汾<EFBFBD>Ĺ<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
DWORD dwBegin = GetTickCount(), dwEnd, dwCost, uReadLength, uReadReturn;
|
|
|
|
|
|
|
|
|
|
uReadLength = Stat.cbInQue > dwLength ? dwLength : Stat.cbInQue;
|
|
|
|
|
CN_ASSERT(::ReadFile(hComm_, pBuffer, uReadLength, &uReadReturn, &RO_));
|
|
|
|
|
dwReadResult += uReadReturn;
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
if (!::ReadFile(hComm_, (LPBYTE)pBuffer + dwReadResult, 1, &uReadReturn, &RO_))
|
|
|
|
|
{
|
|
|
|
|
if (dwWaitTime > 5 && WaitForSingleObject(RO_.hEvent, dwWaitTime) == WAIT_OBJECT_0)
|
|
|
|
|
{
|
|
|
|
|
dwEnd = GetTickCount();
|
|
|
|
|
dwCost = dwEnd>=dwBegin ? dwEnd-dwBegin : DWORD(-1L)-dwBegin+dwEnd;
|
|
|
|
|
CN_ASSERT(::GetOverlappedResult(hComm_, &RO_, &uReadReturn, FALSE));
|
|
|
|
|
dwWaitTime = dwWaitTime > dwCost ? dwWaitTime-dwCost : 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
CN_ASSERT(::PurgeComm(hComm_, PURGE_RXABORT));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
while (uReadReturn && ++dwReadResult < dwLength);
|
|
|
|
|
}
|
|
|
|
|
return dwInCount_ += dwReadResult, dwReadResult;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>I/O<><4F>WinCE<43><45>I/O<><4F> dwWaitTime<6D><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ʱʱ<CAB1><CAB1><EFBFBD>ɳ<EFBFBD>ʱ<EFBFBD>ṹ<EFBFBD><E1B9B9><EFBFBD><EFBFBD> Ĭ<><C4AC><EFBFBD>趨1/4<><34>
|
|
|
|
|
CN_ASSERT(::ReadFile(hComm_, pBuffer, dwLength, &dwReadResult, NULL));
|
|
|
|
|
return dwInCount_ += dwReadResult, dwReadResult;
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD> dwLength<74><68><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD> pBuffer <20><><EFBFBD><EFBFBD>ʵ<EFBFBD>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD> <20>ɶ<EFBFBD><C9B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
DWORD Read(LPVOID pBuffer, DWORD dwLength, DWORD dwWaitTime = INFINITE)
|
|
|
|
|
{
|
|
|
|
|
if (!IsOpen())
|
|
|
|
|
{
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
CN_ASSERT(pBuffer);
|
|
|
|
|
|
|
|
|
|
if (dwOption_ & EN_RX_BUFFER)
|
|
|
|
|
{
|
|
|
|
|
BlockBuffer::InnerLock locker(&I_);
|
|
|
|
|
return I_.Read(pBuffer, dwLength);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef CN_COMM_FOR_CE
|
|
|
|
|
return ReadPort(pBuffer, dwLength, dwWaitTime);
|
|
|
|
|
#else
|
|
|
|
|
return ReadPort(pBuffer, dwLength, dwWaitTime);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD> dwLength - 1 <20><>ANSI<53>ַ<EFBFBD><D6B7><EFBFBD> szBuffer <20><><EFBFBD><EFBFBD> C ģʽ<C4A3>ַ<EFBFBD><D6B7><EFBFBD>ָ<EFBFBD><D6B8> <20>ʺ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ַ<EFBFBD>ͨѶ
|
|
|
|
|
char * ReadString(char *szBuffer, DWORD dwLength, DWORD dwWaitTime = INFINITE)
|
|
|
|
|
{
|
|
|
|
|
if (!IsOpen())
|
|
|
|
|
{
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
CN_ASSERT(szBuffer);
|
|
|
|
|
szBuffer[Read(szBuffer, dwLength - 1, dwWaitTime)] = '\0';
|
|
|
|
|
return szBuffer;
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD> dwLength - 1 <20><>UNICODE<44>ַ<EFBFBD><D6B7><EFBFBD> szBuffer <20><><EFBFBD><EFBFBD> C ģʽ<C4A3>ַ<EFBFBD><D6B7><EFBFBD>ָ<EFBFBD><D6B8> <20>ʺ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ַ<EFBFBD>ͨѶ
|
|
|
|
|
wchar_t * ReadString(wchar_t *szBuffer, DWORD dwLength, DWORD dwWaitTime = INFINITE)
|
|
|
|
|
{
|
|
|
|
|
if (!IsOpen())
|
|
|
|
|
{
|
|
|
|
|
return L"";
|
|
|
|
|
}
|
|
|
|
|
CN_ASSERT(szBuffer);
|
|
|
|
|
szBuffer[(Read(szBuffer, (dwLength - 1)*sizeof(wchar_t), dwWaitTime) +1)/ sizeof(wchar_t)] = L'\0';
|
|
|
|
|
return szBuffer;
|
|
|
|
|
}
|
|
|
|
|
//! ֱ<><D6B1>д<EFBFBD><D0B4><EFBFBD>˿<EFBFBD>
|
|
|
|
|
DWORD WritePort(LPCVOID pBuffer, DWORD dwLength)
|
|
|
|
|
{
|
|
|
|
|
if (!IsOpen())
|
|
|
|
|
{
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if(!CN_ASSERT(IsOpen()) || !dwLength)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
DWORD dwError;
|
|
|
|
|
unsigned long uWriteLength = 0;
|
|
|
|
|
|
|
|
|
|
if(::ClearCommError(hComm_, &dwError, NULL) && dwError > 0)
|
|
|
|
|
::PurgeComm(hComm_, PURGE_TXABORT);
|
|
|
|
|
|
|
|
|
|
#ifndef CN_COMM_FOR_CE
|
|
|
|
|
if (IsOverlappedMode())//! ʹ<><CAB9><EFBFBD>ص<EFBFBD>IO<49>Ƿ<EFBFBD><C7B7><EFBFBD>0<EFBFBD><30>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>Ӽ<EFBFBD><D3BC>ϴ<EFBFBD>д<EFBFBD>볤<EFBFBD>ȣ<EFBFBD><C8A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD>ɹ<EFBFBD>
|
|
|
|
|
{//! <20>ص<EFBFBD>IO<49>³<EFBFBD>ʱ<EFBFBD>ɳ<EFBFBD>ʱ<EFBFBD>ṹ<EFBFBD><E1B9B9><EFBFBD><EFBFBD> Ĭ<><C4AC>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>*1<><31><EFBFBD><EFBFBD>+10<31><30>
|
|
|
|
|
if(!::WriteFile(hComm_, pBuffer, dwLength, &uWriteLength, &WO_)
|
|
|
|
|
&& !CN_ASSERT(::GetLastError() == ERROR_IO_PENDING))
|
|
|
|
|
uWriteLength = 0;
|
|
|
|
|
else
|
|
|
|
|
dwOutCount_ += dwLength;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
//! ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IO<49><4F>WINCE<43>³ɹ<C2B3><C9B9><EFBFBD><EFBFBD><EFBFBD>0 ʧ<>ܷ<EFBFBD><DCB7><EFBFBD>ʵ<EFBFBD><CAB5>д<EFBFBD>볤<EFBFBD>ȣ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>Ӽ<EFBFBD><D3BC><EFBFBD>ʵ<EFBFBD><CAB5>д<EFBFBD>볤<EFBFBD><EBB3A4>, <20><>ʱĬ<CAB1><C4AC>1/4<><34>
|
|
|
|
|
BOOL bRet = ::WriteFile(hComm_, pBuffer, dwLength, &uWriteLength, NULL);
|
|
|
|
|
int error = ::GetLastError();
|
|
|
|
|
dwOutCount_ += uWriteLength;
|
|
|
|
|
uWriteLength = (dwLength == uWriteLength) ? uWriteLength : 0;
|
|
|
|
|
}
|
|
|
|
|
return uWriteLength;
|
|
|
|
|
}
|
|
|
|
|
//! д EN_TX_BUFFER <20><><EFBFBD><EFBFBD>д<EFBFBD>뻺<EFBFBD><EBBBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1>д<EFBFBD><D0B4><EFBFBD>˿<EFBFBD>
|
|
|
|
|
DWORD Write(LPCVOID pBuffer, DWORD dwLength)
|
|
|
|
|
{
|
|
|
|
|
if (!IsOpen())
|
|
|
|
|
{
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (dwLength && (dwOption_&EN_TX_BUFFER))
|
|
|
|
|
{
|
|
|
|
|
BlockBuffer::InnerLock locker(&O_);
|
|
|
|
|
|
|
|
|
|
O_.Write(pBuffer, dwLength);
|
|
|
|
|
|
|
|
|
|
if (dwOption_ & EN_TX_THREAD)
|
|
|
|
|
SetEvent(hWatchEvent_);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
#ifdef CN_COMM_FOR_CE
|
|
|
|
|
SetCommMask(hComm_, dwWaitEvent_);
|
|
|
|
|
#else
|
|
|
|
|
if (IsOverlappedMode())
|
|
|
|
|
SetCommMask(hComm_, dwWaitEvent_);
|
|
|
|
|
else
|
|
|
|
|
SetEvent(hWatchEvent_);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef CN_COMM_FOR_CE
|
|
|
|
|
return WritePort(pBuffer, dwLength);
|
|
|
|
|
#else
|
|
|
|
|
return WritePort(pBuffer, dwLength);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
//! д<><D0B4><EFBFBD><EFBFBD> ANSI<53>ַ<EFBFBD> дANSI C ģʽ<C4A3>ַ<EFBFBD><D6B7><EFBFBD>ָ<EFBFBD><D6B8>
|
|
|
|
|
DWORD Write(const char *szBuffer,int nBufferLen)
|
|
|
|
|
{
|
|
|
|
|
if (!IsOpen())
|
|
|
|
|
{
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
CN_ASSERT(szBuffer);
|
|
|
|
|
|
|
|
|
|
return Write((LPCVOID)szBuffer, nBufferLen);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//! ǿ<><C7BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݲ<EFBFBD><DDB2>ȴ<EFBFBD>
|
|
|
|
|
void FlushPort()
|
|
|
|
|
{
|
|
|
|
|
if(CN_ASSERT(IsOpen()))
|
|
|
|
|
FlushFileBuffers(hComm_);
|
|
|
|
|
}
|
|
|
|
|
//! ǿ<><C7BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݲ<EFBFBD><DDB2>ȴ<EFBFBD>
|
|
|
|
|
void Flush()
|
|
|
|
|
{
|
|
|
|
|
if(CN_ASSERT(IsOpen()))
|
|
|
|
|
{
|
|
|
|
|
if (dwOption_ & EN_TX_BUFFER)
|
|
|
|
|
{
|
|
|
|
|
while(O_.SafeSize())
|
|
|
|
|
Sleep(50);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FlushFileBuffers(hComm_);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>
|
|
|
|
|
bool TransmitChar(char c)
|
|
|
|
|
{
|
|
|
|
|
if (CN_ASSERT(IsOpen()))
|
|
|
|
|
{
|
|
|
|
|
if (::TransmitCommChar(hComm_, c))
|
|
|
|
|
return dwOutCount_++, true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳̿<DFB3><CCBF><EFBFBD>
|
|
|
|
|
bool BeginThread(DWORD dwThreadOption = 0)
|
|
|
|
|
{
|
|
|
|
|
DWORD dwCreationFlags;
|
|
|
|
|
|
|
|
|
|
if(CN_ASSERT(!hWatchThread_ && !hReadThread_ && !hWriteThread_))
|
|
|
|
|
{//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<D7B4>²ſ<C2B2><C5BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
|
|
|
|
|
bContinue_ = true;
|
|
|
|
|
dwCreationFlags = dwOption_ & EN_SUSPEND ? CREATE_SUSPENDED : 0;
|
|
|
|
|
|
|
|
|
|
if (dwThreadOption)//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̣߳<DFB3><CCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD>߳<EFBFBD>
|
|
|
|
|
dwOption_ |= dwThreadOption;
|
|
|
|
|
|
|
|
|
|
#if defined(_MT) && !defined(CN_COMM_FOR_CE)
|
|
|
|
|
unsigned int id, rid, wid;
|
|
|
|
|
|
|
|
|
|
if (dwOption_ & EN_THREAD)
|
|
|
|
|
hWatchThread_ = (HANDLE)_beginthreadex(NULL, 0, WatchThreadProc, this, dwCreationFlags, &id);
|
|
|
|
|
|
|
|
|
|
if (dwOption_ & EN_RX_THREAD)
|
|
|
|
|
hReadThread_ = (HANDLE)_beginthreadex(NULL, 0, ReadThreadProc, this, dwCreationFlags, &rid);
|
|
|
|
|
|
|
|
|
|
if (dwOption_ & EN_TX_THREAD)
|
|
|
|
|
hWriteThread_ = (HANDLE)_beginthreadex(NULL, 0, WriteThreadProc, this, dwCreationFlags, &wid);
|
|
|
|
|
#else
|
|
|
|
|
DWORD id, rid, wid;
|
|
|
|
|
|
|
|
|
|
if (dwOption_ & EN_THREAD)
|
|
|
|
|
hWatchThread_ = ::CreateThread(NULL, 0, WatchThreadProc, this, dwCreationFlags , &id);
|
|
|
|
|
|
|
|
|
|
if (dwOption_ & EN_RX_THREAD)
|
|
|
|
|
hReadThread_ = ::CreateThread(NULL, 0, ReadThreadProc, this, dwCreationFlags, &rid);
|
|
|
|
|
|
|
|
|
|
if (dwOption_ & EN_TX_THREAD)
|
|
|
|
|
hWriteThread_ = ::CreateThread(NULL, 0, WriteThreadProc, this, dwCreationFlags, &wid);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (dwOption_ & EN_THREAD)
|
|
|
|
|
{
|
|
|
|
|
CN_ASSERT(hWatchThread_ != NULL);
|
|
|
|
|
hWatchThreadId_ = id;
|
|
|
|
|
|
|
|
|
|
if (!hWatchThread_)
|
|
|
|
|
{
|
|
|
|
|
EndThread();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (dwOption_ & EN_ABOVE_NORMAL)
|
|
|
|
|
SetThreadPriority(hWatchThread_, THREAD_PRIORITY_ABOVE_NORMAL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dwOption_ & EN_RX_THREAD)
|
|
|
|
|
{
|
|
|
|
|
CN_ASSERT(hReadThread_ != NULL);
|
|
|
|
|
hReadThreadId_ = rid;
|
|
|
|
|
|
|
|
|
|
if (!hReadThreadId_)
|
|
|
|
|
{
|
|
|
|
|
EndThread();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (dwOption_ & EN_ABOVE_NORMAL)
|
|
|
|
|
SetThreadPriority(hReadThread_, THREAD_PRIORITY_ABOVE_NORMAL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dwOption_ & EN_TX_THREAD)
|
|
|
|
|
{
|
|
|
|
|
CN_ASSERT(hWriteThread_ != NULL);
|
|
|
|
|
hWriteThreadId_ = wid;
|
|
|
|
|
|
|
|
|
|
if (!hWriteThreadId_)
|
|
|
|
|
{
|
|
|
|
|
EndThread();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (dwOption_ & EN_ABOVE_NORMAL)
|
|
|
|
|
SetThreadPriority(hWriteThread_, THREAD_PRIORITY_ABOVE_NORMAL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ͣ<EFBFBD>߳<EFBFBD>
|
|
|
|
|
bool SuspendThread(int iOption = EN_THREAD)
|
|
|
|
|
{
|
|
|
|
|
return ::SuspendThread(GetThread(iOption)) != 0xFFFFFFFF;
|
|
|
|
|
}
|
|
|
|
|
//! <20>ָ<EFBFBD><D6B8>߳<EFBFBD>
|
|
|
|
|
bool ResumeThread(int iOption = EN_THREAD)
|
|
|
|
|
{
|
|
|
|
|
return ::ResumeThread(GetThread(iOption)) != 0xFFFFFFFF;
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ֹ<EFBFBD>߳<EFBFBD>
|
|
|
|
|
bool EndThread(DWORD dwWaitTime = 500)
|
|
|
|
|
{
|
|
|
|
|
if(hWatchThread_ || hReadThread_ || hWriteThread_)
|
|
|
|
|
{
|
|
|
|
|
if ((dwOption_&EN_FLUSH_ALL) && (dwOption_&EN_TX_BUFFER))
|
|
|
|
|
{//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>EN_FLUSH_ALL<4C><4C><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD>ȴ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>գ<EFBFBD><D5A3><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD>̲߳<DFB3><CCB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
while(O_.Size())
|
|
|
|
|
Sleep(50);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bContinue_ = false;
|
|
|
|
|
|
|
|
|
|
#ifdef CN_COMM_FOR_CE
|
|
|
|
|
::SetCommMask(hComm_, 0);
|
|
|
|
|
#else
|
|
|
|
|
if (IsOverlappedMode())
|
|
|
|
|
::SetCommMask(hComm_, 0);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (hWatchThread_)
|
|
|
|
|
{
|
|
|
|
|
SetEvent(hWatchEvent_);
|
|
|
|
|
if(::WaitForSingleObject(hWatchThread_, dwWaitTime) != WAIT_OBJECT_0)
|
|
|
|
|
if(!::TerminateThread(hWatchThread_, 0))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
::CloseHandle(hWatchThread_);
|
|
|
|
|
hWatchThread_ = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hReadThread_)
|
|
|
|
|
{
|
|
|
|
|
SetEvent(hReadEvent_);
|
|
|
|
|
if(::WaitForSingleObject(hReadThread_, dwWaitTime) != WAIT_OBJECT_0)
|
|
|
|
|
if(!::TerminateThread(hReadThread_, 0))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
::CloseHandle(hReadThread_);
|
|
|
|
|
hReadThread_ = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hWriteThread_)
|
|
|
|
|
{
|
|
|
|
|
SetEvent(hWriteEvent_);
|
|
|
|
|
if(::WaitForSingleObject(hWriteThread_, dwWaitTime) != WAIT_OBJECT_0)
|
|
|
|
|
if(!::TerminateThread(hWriteThread_, 0))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
::CloseHandle(hWriteThread_);
|
|
|
|
|
hWriteThread_ = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
//! <20>رմ<D8B1><D5B4><EFBFBD> ͬʱҲ<CAB1>رչ<D8B1><D5B9><EFBFBD><EFBFBD>߳<EFBFBD>
|
|
|
|
|
virtual void Close(DWORD dwWaitTime = 500)
|
|
|
|
|
{
|
|
|
|
|
if(IsOpen())
|
|
|
|
|
{
|
|
|
|
|
EndThread(dwWaitTime);//! ͬ<><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
|
|
|
|
|
|
|
|
|
|
if (dwOption_&EN_FLUSH || dwOption_&EN_FLUSH_ALL)
|
|
|
|
|
FlushFileBuffers(hComm_);
|
|
|
|
|
|
|
|
|
|
::PurgeComm(hComm_, PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_RXABORT);
|
|
|
|
|
::CloseHandle(hComm_);
|
|
|
|
|
hComm_ = INVALID_HANDLE_VALUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>
|
|
|
|
|
void Lock()
|
|
|
|
|
{
|
|
|
|
|
::EnterCriticalSection(&CS_);
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>
|
|
|
|
|
void Unlock()
|
|
|
|
|
{
|
|
|
|
|
::LeaveCriticalSection(&CS_);
|
|
|
|
|
}
|
|
|
|
|
//! <20>Զ<EFBFBD><D4B6><EFBFBD> <20><><EFBFBD>ں<EFBFBD><DABA><EFBFBD><EFBFBD>ڲ<EFBFBD> <20><><EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
struct InnerLock
|
|
|
|
|
{
|
|
|
|
|
ComComm* ptr;//!< ComComm <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>
|
|
|
|
|
InnerLock(ComComm* p) : ptr(p)
|
|
|
|
|
{
|
|
|
|
|
ptr->Lock();
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>
|
|
|
|
|
~InnerLock()
|
|
|
|
|
{
|
|
|
|
|
ptr->Unlock();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
//! <20><><EFBFBD>ô<EFBFBD><C3B4>ڲ<EFBFBD><DAB2><EFBFBD> DCB
|
|
|
|
|
DCB *GetState(DCB *pDcb = NULL)
|
|
|
|
|
{
|
|
|
|
|
return CN_ASSERT(IsOpen()) && ::GetCommState(hComm_, pDcb == NULL ? &DCB_ : pDcb) == TRUE ? (pDcb == NULL ? &DCB_ : pDcb) : NULL;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ô<EFBFBD><C3B4>ڲ<EFBFBD><DAB2><EFBFBD> DCB
|
|
|
|
|
bool SetState(DCB *pDcb = NULL)
|
|
|
|
|
{
|
|
|
|
|
return CN_ASSERT(IsOpen()) ? ::SetCommState(hComm_, pDcb == NULL ? &DCB_ : pDcb) == TRUE : false;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ô<EFBFBD><C3B4>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD>ֹͣλ<D6B9><CEBB><EFBFBD><EFBFBD> ***
|
|
|
|
|
bool SetState(DWORD dwBaudRate, BYTE btParity = NOPARITY, BYTE btByteSize = 8, BYTE btStopBits = ONESTOPBIT)
|
|
|
|
|
{
|
|
|
|
|
if(CN_ASSERT(IsOpen()))
|
|
|
|
|
{
|
|
|
|
|
if(::GetCommState(hComm_, &DCB_) != TRUE)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
DCB_.BaudRate = dwBaudRate;
|
|
|
|
|
DCB_.ByteSize = btByteSize;
|
|
|
|
|
DCB_.Parity = btParity;
|
|
|
|
|
DCB_.StopBits = btStopBits;
|
|
|
|
|
DCB_.fParity = (btParity != NOPARITY);
|
|
|
|
|
|
|
|
|
|
return ::SetCommState(hComm_, &DCB_) == TRUE;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
#ifndef CN_COMM_FOR_CE
|
|
|
|
|
//! <20><><EFBFBD>ô<EFBFBD><C3B4>ڲ<EFBFBD><DAB2><EFBFBD> ֧<><D6A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD> "9600, n, 8, 1"
|
|
|
|
|
bool SetState(LPCTSTR szSetStr)
|
|
|
|
|
{
|
|
|
|
|
if(CN_ASSERT(IsOpen()))
|
|
|
|
|
{
|
|
|
|
|
if(!::GetCommState(hComm_, &DCB_))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if(!BuildCommDCB(szSetStr, &DCB_))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
DCB_.fParity = (DCB_.Parity != NOPARITY);
|
|
|
|
|
BOOL bRet = ::SetCommState(hComm_, &DCB_) == TRUE;
|
|
|
|
|
|
|
|
|
|
bool smallBool = false;
|
|
|
|
|
bRet == 0 ? smallBool = false : smallBool = true;
|
|
|
|
|
return smallBool;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
//! <20><><EFBFBD>ó<EFBFBD>ʱ<EFBFBD>ṹ
|
|
|
|
|
LPCOMMTIMEOUTS GetTimeouts(LPCOMMTIMEOUTS lpCO = NULL)
|
|
|
|
|
{
|
|
|
|
|
return CN_ASSERT(IsOpen()) && ::GetCommTimeouts(hComm_, lpCO ? lpCO : &CO_) == TRUE ? (lpCO ? lpCO : &CO_) : NULL;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ó<EFBFBD>ʱ
|
|
|
|
|
bool SetTimeouts(LPCOMMTIMEOUTS lpCO = NULL)
|
|
|
|
|
{
|
|
|
|
|
return CN_ASSERT(IsOpen()) ? ::SetCommTimeouts(hComm_, lpCO ? lpCO : &CO_) == TRUE : false;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ô<EFBFBD><C3B4>ڵ<EFBFBD>I/O<><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
|
|
|
|
|
bool Setup(DWORD dwInputSize = 4096, DWORD dwOutputSize = 4096)
|
|
|
|
|
{
|
|
|
|
|
return CN_ASSERT(IsOpen()) ? ::SetupComm(hComm_, dwInputSize, dwOutputSize) == TRUE : false;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD>˿ڹ<CBBF><DAB9><EFBFBD>
|
|
|
|
|
bool Escape(DWORD dwType)
|
|
|
|
|
{
|
|
|
|
|
return CN_ASSERT(IsOpen()) ? EscapeCommFunction(hComm_, dwType) != 0 : false;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>õ<EFBFBD><C3B5>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD>״̬
|
|
|
|
|
DWORD GetModemStatus()
|
|
|
|
|
{
|
|
|
|
|
DWORD dwModemStat = 0;
|
|
|
|
|
return CN_ASSERT(IsOpen()) && GetCommModemStatus(hComm_, &dwModemStat) ? dwModemStat : 0;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ö˿ڲ<CBBF><DAB2><EFBFBD> \param[in] pCP <20>ṹָ<E1B9B9><D6B8> <20><><EFBFBD><EFBFBD>pCP==NULL, ComComm<6D><6D><EFBFBD>Ӷѷ<D3B6><D1B7><EFBFBD><EFBFBD>ڴ<EFBFBD>, <20><><EFBFBD><EFBFBD>ComComm<6D><6D><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD>, <20>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>Լ<EFBFBD><D4BC>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
|
|
|
|
|
LPCOMMPROP GetProperties(LPCOMMPROP pCP = NULL)
|
|
|
|
|
{
|
|
|
|
|
if (CN_ASSERT(IsOpen()))
|
|
|
|
|
{
|
|
|
|
|
if (!pCP)
|
|
|
|
|
{
|
|
|
|
|
#ifdef CN_COMM_FOR_CE
|
|
|
|
|
USHORT dwSize = sizeof(COMMPROP);
|
|
|
|
|
#else
|
|
|
|
|
USHORT dwSize = sizeof(COMMPROP) + sizeof(MODEMDEVCAPS);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (!pCP_)
|
|
|
|
|
pCP_ = (LPCOMMPROP) new BYTE[dwSize];
|
|
|
|
|
|
|
|
|
|
if (pCP_)
|
|
|
|
|
{
|
|
|
|
|
memset(pCP_, 0, dwSize);
|
|
|
|
|
|
|
|
|
|
pCP_->wPacketLength = dwSize;
|
|
|
|
|
#ifndef CN_COMM_FOR_CE
|
|
|
|
|
pCP_->dwProvSubType = PST_MODEM;
|
|
|
|
|
#endif
|
|
|
|
|
pCP_->dwProvSpec1 = COMMPROP_INITIALIZED;
|
|
|
|
|
pCP = pCP_;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return pCP && GetCommProperties(hComm_, pCP) ? pCP : NULL;
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ȡ<EFBFBD>¼<EFBFBD><C2BC><EFBFBD>ʶ
|
|
|
|
|
DWORD GetMask()
|
|
|
|
|
{
|
|
|
|
|
DWORD dwMask;
|
|
|
|
|
return CN_ASSERT(IsOpen()) && GetCommMask(hComm_, &dwMask) ? dwMask : 0;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD>˿ڻ<CBBF><DABB><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
bool Purge(DWORD dwPara = PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR)
|
|
|
|
|
{
|
|
|
|
|
return CN_ASSERT(IsOpen()) ? ::PurgeComm(hComm_, dwPara)==TRUE : false;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
DWORD ClearError()
|
|
|
|
|
{
|
|
|
|
|
DWORD dwError;
|
|
|
|
|
return CN_ASSERT(IsOpen()) && ::ClearCommError(hComm_, &dwError, NULL) ? dwError : 0;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
|
|
|
|
DWORD GetQueueCount(bool bInput = true)
|
|
|
|
|
{
|
|
|
|
|
COMSTAT Stat;
|
|
|
|
|
DWORD dwError;
|
|
|
|
|
|
|
|
|
|
return CN_ASSERT(IsOpen()) && ::ClearCommError(hComm_, &dwError, &Stat) ? (bInput ? Stat.cbInQue : Stat.cbOutQue) : (DWORD)-1L;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD> CTS ON
|
|
|
|
|
bool CheckCTS()
|
|
|
|
|
{
|
|
|
|
|
return (GetModemStatus()&MS_CTS_ON) != 0;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD> DSR ON
|
|
|
|
|
bool CheckDSR()
|
|
|
|
|
{
|
|
|
|
|
return (GetModemStatus()&MS_DSR_ON) != 0;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD> Ring ON
|
|
|
|
|
bool CheckRING()
|
|
|
|
|
{
|
|
|
|
|
return (GetModemStatus()&MS_RING_ON) != 0;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD> RLSD ON
|
|
|
|
|
bool CheckRLSD()
|
|
|
|
|
{
|
|
|
|
|
return (GetModemStatus()&MS_RLSD_ON) != 0;
|
|
|
|
|
}
|
|
|
|
|
//! DTR <20><>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD>
|
|
|
|
|
bool SetDTR(bool bSetOrClr = true)
|
|
|
|
|
{
|
|
|
|
|
return Escape(bSetOrClr ? SETDTR : CLRDTR);
|
|
|
|
|
}
|
|
|
|
|
//! RTS <20><>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD>
|
|
|
|
|
bool SetRTS(bool bSetOrClr = true)
|
|
|
|
|
{
|
|
|
|
|
return Escape(bSetOrClr ? SETRTS : CLRRTS);
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
bool SetBreak(bool bSetOrClr = true)
|
|
|
|
|
{
|
|
|
|
|
return Escape(bSetOrClr ? SETBREAK : CLRBREAK);
|
|
|
|
|
}
|
|
|
|
|
#ifdef CN_COMM_FOR_CE
|
|
|
|
|
//! WINCE
|
|
|
|
|
bool SetIR(bool bSetOrClr)
|
|
|
|
|
{
|
|
|
|
|
return Escape(bSetOrClr ? SETIR : CLRIR);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> SETXON SETXOFF
|
|
|
|
|
bool SetX(bool bOnOrOff)
|
|
|
|
|
{
|
|
|
|
|
return Escape(bOnOrOff ? SETXON : SETXOFF);
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>ͨѶ<CDA8>ص㿪<D8B5><E3BFAA><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD> <20><>һЩ<D2BB><D0A9>չ<EFBFBD><D5B9>֧<EFBFBD>ֺ<EFBFBD>API<50>ҽ<EFBFBD>
|
|
|
|
|
class BlockBuffer
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD>
|
|
|
|
|
struct Block
|
|
|
|
|
{
|
|
|
|
|
DWORD B_; //!< <20><>ʼƫ<CABC><C6AB>
|
|
|
|
|
DWORD E_; //!< <20><><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB>
|
|
|
|
|
DWORD S_; //!< <20><><EFBFBD><EFBFBD>С <20>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD> <20>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>Сֵ<D0A1><D6B5>CN_COMM_BUFFER_MIN_BLOCK_SIZE<5A><45><EFBFBD><EFBFBD>
|
|
|
|
|
Block* N_; //!< <20><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
|
|
|
|
BYTE P_[4]; //!< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8> ʵ<>ʴ<EFBFBD>С<EFBFBD><D0A1>S_<53><5F><EFBFBD><EFBFBD>
|
|
|
|
|
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>
|
|
|
|
|
DWORD Capacity() { return S_; }
|
|
|
|
|
//! ʵ<>ʴ<EFBFBD>С
|
|
|
|
|
DWORD Size() { return E_ - B_; }
|
|
|
|
|
//! <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
|
|
|
|
BYTE* Begin() { return P_ + B_; }
|
|
|
|
|
//! ĩ<>˻<EFBFBD><CBBB><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
|
|
|
|
BYTE* End() { return P_ + E_; }
|
|
|
|
|
//! <20><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>
|
|
|
|
|
Block* Next() { return N_; }
|
|
|
|
|
//! <20>Ƿ<EFBFBD><C7B7><EFBFBD>
|
|
|
|
|
bool IsEmpty() { return B_ == E_; }
|
|
|
|
|
//! <20><><EFBFBD>д<EFBFBD>С
|
|
|
|
|
DWORD FreeSize() { return S_ - E_; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//! <20><><EFBFBD>ڻ<EFBFBD><DABB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
struct Iterator
|
|
|
|
|
{
|
|
|
|
|
BlockBuffer* P_; //!< <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
|
|
|
|
Block* B_; //!< <20><>ǰ<EFBFBD><C7B0>ָ<EFBFBD><D6B8>
|
|
|
|
|
DWORD I_; //!< <20><>ǰ<EFBFBD><C7B0>ƫ<EFBFBD><C6AB>
|
|
|
|
|
DWORD O_; //!< ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB>
|
|
|
|
|
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>
|
|
|
|
|
Iterator(BlockBuffer *P = NULL, Block* B = NULL, DWORD I = 0, DWORD O = 0)
|
|
|
|
|
: P_(P), B_(B), I_(I), O_(O)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
//! <20>Ƿ<EFBFBD><C7B7><EFBFBD>Ч
|
|
|
|
|
operator bool()
|
|
|
|
|
{
|
|
|
|
|
return B_ && I_<B_->E_&&I_>=B_->B_;
|
|
|
|
|
}
|
|
|
|
|
//! <20>Ƿ<EFBFBD><C7B7><EFBFBD>д
|
|
|
|
|
bool CanWrite()
|
|
|
|
|
{
|
|
|
|
|
return B_ && I_ < B_->S_;
|
|
|
|
|
}
|
|
|
|
|
//! ȡֵ<C8A1><D6B5><EFBFBD><EFBFBD>
|
|
|
|
|
BYTE& operator *()
|
|
|
|
|
{
|
|
|
|
|
CN_ASSERT( P_ && B_ && I_<B_->E_&&I_>=B_->B_);
|
|
|
|
|
return B_->P_[I_];
|
|
|
|
|
}
|
|
|
|
|
//! <20>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ++Iter;
|
|
|
|
|
Iterator& operator ++ ()
|
|
|
|
|
{
|
|
|
|
|
return operator +=(1);
|
|
|
|
|
}
|
|
|
|
|
//! <20>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Iter++;
|
|
|
|
|
Iterator& operator ++ (int)
|
|
|
|
|
{
|
|
|
|
|
return operator +=(1);
|
|
|
|
|
}
|
|
|
|
|
//! <20>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> \param dwOffset Ϊƫ<CEAA><C6AB><EFBFBD><EFBFBD>
|
|
|
|
|
Iterator& operator += (DWORD dwOffset)
|
|
|
|
|
{
|
|
|
|
|
while (dwOffset)
|
|
|
|
|
{
|
|
|
|
|
if (I_+dwOffset < B_->E_)
|
|
|
|
|
I_ += dwOffset, O_ += dwOffset, dwOffset = 0;
|
|
|
|
|
else
|
|
|
|
|
dwOffset -= B_->E_-I_, I_ += B_->E_-I_, O_ += B_->E_-I_, B_ = B_->N_, I_ = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
//! <20>Ƚ<EFBFBD>
|
|
|
|
|
bool operator == (const Iterator& iter)
|
|
|
|
|
{
|
|
|
|
|
return (P_ == iter.P_) && (B_ == iter.B_) && (I_ == iter.I_);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
//! <20><>Ԫ
|
|
|
|
|
friend struct Iterator;
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>
|
|
|
|
|
void Lock()
|
|
|
|
|
{
|
|
|
|
|
::EnterCriticalSection(&C_);
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>
|
|
|
|
|
void Unlock()
|
|
|
|
|
{
|
|
|
|
|
::LeaveCriticalSection(&C_);
|
|
|
|
|
}
|
|
|
|
|
//! <20>Զ<EFBFBD><D4B6><EFBFBD>
|
|
|
|
|
struct InnerLock
|
|
|
|
|
{
|
|
|
|
|
BlockBuffer* ptr;//!<<3C><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
|
|
|
|
///<2F><><EFBFBD><EFBFBD>
|
|
|
|
|
InnerLock(BlockBuffer* p) : ptr(p)
|
|
|
|
|
{
|
|
|
|
|
if (ptr)
|
|
|
|
|
ptr->Lock();
|
|
|
|
|
}
|
|
|
|
|
///<2F><><EFBFBD><EFBFBD>
|
|
|
|
|
~InnerLock()
|
|
|
|
|
{
|
|
|
|
|
if (ptr)
|
|
|
|
|
ptr->Unlock();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>
|
|
|
|
|
BlockBuffer()
|
|
|
|
|
{
|
|
|
|
|
::InitializeCriticalSection(&C_);
|
|
|
|
|
S_ = 0, F_ = L_ = NULL, M_ = CN_COMM_BUFFER_MIN_BLOCK_SIZE;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6>ͷſռ<C5BF>
|
|
|
|
|
virtual ~BlockBuffer()
|
|
|
|
|
{
|
|
|
|
|
Clear();
|
|
|
|
|
::DeleteCriticalSection(&C_);
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
Iterator Begin()
|
|
|
|
|
{
|
|
|
|
|
return Iterator(this, F_, F_? F_->B_ : 0, 0);
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD>
|
|
|
|
|
void SetMinBlockSize(DWORD dwMinSize)
|
|
|
|
|
{
|
|
|
|
|
M_ = dwMinSize;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD>
|
|
|
|
|
DWORD GetMinBlockSize()
|
|
|
|
|
{
|
|
|
|
|
return M_;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
|
|
|
|
|
DWORD Size()
|
|
|
|
|
{
|
|
|
|
|
return S_;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
|
|
|
|
|
DWORD SafeSize()
|
|
|
|
|
{
|
|
|
|
|
InnerLock lock(this);
|
|
|
|
|
return S_;
|
|
|
|
|
}
|
|
|
|
|
//! д<><D0B4>ANSI<53>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> \sa Write(LPCVOID lpBuf, DWORD dwSize)
|
|
|
|
|
DWORD Write(const char* lpBuf)
|
|
|
|
|
{
|
|
|
|
|
return Write(lpBuf, strlen(lpBuf));
|
|
|
|
|
}
|
|
|
|
|
//! д<><D0B4>UNICODE<44>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> \sa Write(LPCVOID lpBuf, DWORD dwSize)
|
|
|
|
|
DWORD Write(const wchar_t* lpBuf)
|
|
|
|
|
{
|
|
|
|
|
return Write(lpBuf, wcslen(lpBuf)*sizeof(wchar_t));
|
|
|
|
|
}
|
|
|
|
|
//! д<>뻺<EFBFBD><EBBBBA><EFBFBD><EFBFBD> \param[out] lpBuf Ŀ<>껺<EFBFBD><EABBBA><EFBFBD><EFBFBD> \param[in] dwSize <20><><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD> \return ʵ<>ʸ<EFBFBD><CAB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
|
|
|
|
|
DWORD Write(LPCVOID lpBuf, DWORD dwSize)
|
|
|
|
|
{
|
|
|
|
|
DWORD dwTemp = dwSize, dwFree = FreeSize(), dwCopy = 0;
|
|
|
|
|
|
|
|
|
|
if (dwFree)//! <20><><EFBFBD>Ȳ<EFBFBD><C8B2><EFBFBD>ĩβ<C4A9><CEB2><EFBFBD>У<EFBFBD><D0A3><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
{
|
|
|
|
|
dwCopy = dwFree > dwSize ? dwSize : dwFree;
|
|
|
|
|
memcpy(L_->P_ + L_->E_, lpBuf, dwCopy);
|
|
|
|
|
dwTemp -= dwCopy, L_->E_ += dwCopy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dwTemp)//! ʣ<><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݷ<EFBFBD><DDB7><EFBFBD><EFBFBD>µĿռ䲢д<E4B2A2><D0B4>
|
|
|
|
|
{
|
|
|
|
|
memcpy(NewBlock(dwSize)->P_, ((LPBYTE)lpBuf )+ dwCopy, dwTemp);
|
|
|
|
|
L_->E_ += dwTemp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
S_ += dwSize;
|
|
|
|
|
return dwSize;
|
|
|
|
|
}
|
|
|
|
|
//! <20>̰߳<DFB3>ȫд<C8AB>뻺<EFBFBD><EBBBBA><EFBFBD><EFBFBD> \sa Write(LPCVOID lpBuf, DWORD dwSize)
|
|
|
|
|
DWORD SafeWrite(LPCVOID lpBuf, DWORD dwSize)
|
|
|
|
|
{
|
|
|
|
|
InnerLock lock(this);
|
|
|
|
|
return Write(lpBuf, dwSize);
|
|
|
|
|
}
|
|
|
|
|
//! <20>̰߳<DFB3>ȫд<C8AB><D0B4>ANSI<53>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> \sa Write(LPCVOID lpBuf, DWORD dwSize)
|
|
|
|
|
DWORD SafeWrite(const char* lpBuf)
|
|
|
|
|
{
|
|
|
|
|
InnerLock lock(this);
|
|
|
|
|
return Write(lpBuf, strlen(lpBuf));
|
|
|
|
|
}
|
|
|
|
|
//! <20>̰߳<DFB3>ȫд<C8AB><D0B4>UNICODE<44>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> \sa Write(LPCVOID lpBuf, DWORD dwSize)
|
|
|
|
|
DWORD SafeWrite(const wchar_t* lpBuf)
|
|
|
|
|
{
|
|
|
|
|
InnerLock lock(this);
|
|
|
|
|
return Write(lpBuf, wcslen(lpBuf)*sizeof(wchar_t));
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> \param[out] lpBuf Ŀ<>껺<EFBFBD><EABBBA><EFBFBD><EFBFBD> \param[in] dwSize <20><><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD> \param[in] dwStart Դ<><D4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼƫ<CABC><C6AB>ֵ \return ʵ<>ʸ<EFBFBD><CAB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
|
|
|
|
|
DWORD Copy(LPVOID lpBuf, DWORD dwSize, DWORD dwStart = 0)
|
|
|
|
|
{
|
|
|
|
|
CN_ASSERT(lpBuf);
|
|
|
|
|
|
|
|
|
|
if (!F_ || !dwSize || dwStart >= S_)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
DWORD dwTemp, dwIndex;
|
|
|
|
|
Block * pCur = F_, *pNext = F_->N_;
|
|
|
|
|
|
|
|
|
|
for (dwTemp = 0, dwIndex = pCur->B_; dwTemp < dwStart; pCur = pCur->N_, dwIndex = pCur ? pCur->B_ : 0)
|
|
|
|
|
{
|
|
|
|
|
if (dwStart - dwTemp < pCur->E_ - pCur->B_)
|
|
|
|
|
{
|
|
|
|
|
dwIndex = pCur->B_ + dwStart - dwTemp;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dwTemp += pCur->E_ - pCur->B_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (dwTemp = 0; dwTemp < dwSize && pCur; pCur = pCur->N_, dwIndex = pCur ? pCur->B_ : 0)
|
|
|
|
|
{
|
|
|
|
|
if (dwSize - dwTemp < pCur->E_ - dwIndex)
|
|
|
|
|
{
|
|
|
|
|
memcpy((LPBYTE)lpBuf+dwTemp, pCur->P_ + dwIndex, dwSize - dwTemp );
|
|
|
|
|
dwTemp = dwSize;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
memcpy((LPBYTE)lpBuf+dwTemp, pCur->P_ + dwIndex, pCur->E_ - dwIndex);
|
|
|
|
|
dwTemp += pCur->E_ - dwIndex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return dwTemp;
|
|
|
|
|
}
|
|
|
|
|
//! <20>̰߳<DFB3>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> \sa Copy(LPVOID lpBuf, DWORD dwSize, DWORD dwStart=0)
|
|
|
|
|
DWORD SafeCopy(LPVOID lpBuf, DWORD dwSize, DWORD dwStart = 0)
|
|
|
|
|
{
|
|
|
|
|
InnerLock lock(this);
|
|
|
|
|
return Copy(lpBuf, dwSize, dwStart);
|
|
|
|
|
}
|
|
|
|
|
/*! \param[out] lpBuf Ŀ<>껺<EFBFBD><EABBBA><EFBFBD><EFBFBD> ΪNULLʱ<4C><CAB1>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> \param[in] dwSize <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD> \return ʵ<>ʸ<EFBFBD><CAB8>ƻ<EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD> */
|
|
|
|
|
//! <20><><EFBFBD>Ʋ<EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>lpBuf
|
|
|
|
|
DWORD Read(LPVOID lpBuf, DWORD dwSize)
|
|
|
|
|
{
|
|
|
|
|
DWORD dwTemp = 0, dwCopy;
|
|
|
|
|
|
|
|
|
|
for (Block * pCur = F_, *pNext = NULL; dwTemp<dwSize && pCur; pCur = pNext)
|
|
|
|
|
{
|
|
|
|
|
if (dwSize-dwTemp > pCur->E_-pCur->B_ )
|
|
|
|
|
dwCopy = pCur->E_ - pCur->B_;
|
|
|
|
|
else
|
|
|
|
|
dwCopy = dwSize - dwTemp;
|
|
|
|
|
|
|
|
|
|
if (lpBuf)
|
|
|
|
|
memcpy((LPBYTE)lpBuf+dwTemp, pCur->P_ + pCur->B_, dwCopy);
|
|
|
|
|
|
|
|
|
|
pNext = pCur->N_, dwTemp += dwCopy;
|
|
|
|
|
|
|
|
|
|
if (dwCopy == pCur->E_-pCur->B_)
|
|
|
|
|
{//! ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD>п<EFBFBD>, <20><>һ<EFBFBD>㱣<EFBFBD><E3B1A3>1<EFBFBD><31><EFBFBD><EFBFBD>, <20><>С<EFBFBD><D0A1>4*CN_COMM_BUFFER_MIN_BLOCK_SIZE<5A><45><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
if (pNext || pCur->S_>(M_<<2))
|
|
|
|
|
{
|
|
|
|
|
delete[] (BYTE*)pCur;
|
|
|
|
|
F_ = pNext;
|
|
|
|
|
if (!F_)
|
|
|
|
|
L_ = NULL;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
pCur->B_ = pCur->E_ = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
pCur->B_ += dwCopy;
|
|
|
|
|
|
|
|
|
|
S_ -= dwCopy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return dwTemp;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>ANSI<53>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
char* ReadString(char* lpBuf, DWORD dMaxSize)
|
|
|
|
|
{
|
|
|
|
|
lpBuf[Read(lpBuf, dMaxSize)] = '\0';
|
|
|
|
|
return lpBuf;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>UNICODE<44>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
wchar_t* ReadString(wchar_t* lpBuf, DWORD dMaxSize)
|
|
|
|
|
{
|
|
|
|
|
lpBuf[(Read(lpBuf, dMaxSize*sizeof(wchar_t))+1) / sizeof(wchar_t)] = L'\0';
|
|
|
|
|
return lpBuf;
|
|
|
|
|
}
|
|
|
|
|
//! <20>̰߳<DFB3>ȫ<EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
DWORD SafeRead(LPVOID lpBuf, DWORD dwSize)
|
|
|
|
|
{
|
|
|
|
|
InnerLock lock(this);
|
|
|
|
|
return Read(lpBuf, dwSize);
|
|
|
|
|
}
|
|
|
|
|
//! <20>̰߳<DFB3>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>ANSI<53>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
char* SafeReadString(char* lpBuf, DWORD dMaxSize)
|
|
|
|
|
{
|
|
|
|
|
InnerLock lock(this);
|
|
|
|
|
return ReadString(lpBuf, dMaxSize);
|
|
|
|
|
}
|
|
|
|
|
//! <20>̰߳<DFB3>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>UNICODE<44>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
wchar_t* SafeReadString(wchar_t* lpBuf, DWORD dMaxSize)
|
|
|
|
|
{
|
|
|
|
|
InnerLock lock(this);
|
|
|
|
|
return ReadString(lpBuf, dMaxSize);
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD> \param bDeleteAll Ϊtrueʱ<65>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>
|
|
|
|
|
void Clear(bool bDeleteAll = false)
|
|
|
|
|
{
|
|
|
|
|
if (F_ && (F_==L_) && F_->S_>(M_<<2))
|
|
|
|
|
{
|
|
|
|
|
DWORD S = F_->S_;
|
|
|
|
|
memset(F_, 0, sizeof(Block)), F_->S_ = S;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (Block* t = F_; t; delete F_)
|
|
|
|
|
F_ = t, t = t->N_;
|
|
|
|
|
|
|
|
|
|
F_ = L_ = NULL, S_ = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//! <20>̰߳<DFB3>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> \sa void Clear(bool bDeleteAll = false)
|
|
|
|
|
void SafeClear(bool bDeleteAll = false)
|
|
|
|
|
{
|
|
|
|
|
InnerLock lock(this);
|
|
|
|
|
Clear(bDeleteAll);
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD>ָ<EFBFBD><D6B8> \param bFirst Ϊtrueʱ<65><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD><CEB2>ָ<EFBFBD><D6B8>
|
|
|
|
|
Block* GetBlockPtr(bool bFirst = true)
|
|
|
|
|
{
|
|
|
|
|
return bFirst ? F_ : L_;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD><CEB2><EFBFBD>Ŀ<EFBFBD><C4BF>пռ<D0BF>
|
|
|
|
|
DWORD FreeSize()
|
|
|
|
|
{
|
|
|
|
|
return L_ ? L_->S_-L_->E_ : 0 ;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ù<EFBFBD>API<50><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ֱд<D6B1><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>СdwSize <20><><EFBFBD>в<EFBFBD><D0B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¿<EFBFBD> <20><><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD>β<EFBFBD><CEB2><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD>ָ<EFBFBD><D6B8> β<><CEB2><EFBFBD><EFBFBD><DEBF>з<EFBFBD><D0B7><EFBFBD>NULL
|
|
|
|
|
LPVOID GetFreePtr(DWORD dwSize = 0)
|
|
|
|
|
{
|
|
|
|
|
if (dwSize)
|
|
|
|
|
return FreeSize() > dwSize ? L_->P_ + L_->E_ : NewBlock(dwSize)->P_;
|
|
|
|
|
else
|
|
|
|
|
return L_ ? L_->P_ + L_->E_ : NULL;
|
|
|
|
|
}
|
|
|
|
|
/*! \param[in] dwSize <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB>
|
|
|
|
|
\code strcpy(GetFreePtr(100), "test"), Release(4); //<2F><>ȡ100<30>ֽڵĻ<DAB5><C4BB><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8>ֽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD>4<EFBFBD><34><EFBFBD>ֽ<EFBFBD> \endcode
|
|
|
|
|
*/
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>APIֱ<49><D6B1>д<EFBFBD><D0B4><EFBFBD><EFBFBD>GetFreePtr()<29><><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD>ָ<EFBFBD><D6B8>, ͬ<><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
|
|
|
|
|
DWORD Release(DWORD dwSize)
|
|
|
|
|
{
|
|
|
|
|
return (dwSize <= L_->S_) ? (L_->E_ += dwSize, S_ += dwSize, dwSize) : 0;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>õ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
|
|
|
|
LPVOID GetPtr()
|
|
|
|
|
{
|
|
|
|
|
return F_ ? F_->P_ + F_->B_ : NULL;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>õ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD>С
|
|
|
|
|
DWORD GetPtrSize()
|
|
|
|
|
{
|
|
|
|
|
return F_ ? F_->E_ - F_->B_ : 0;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1 Ч<>ʺܵ<CABA> <20>Ƽ<EFBFBD><C6BC>õ<EFBFBD><C3B5><EFBFBD><EFBFBD>ӷ<EFBFBD><D3B7>ʿ<EFBFBD><CABF>Ի<EFBFBD><D4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
BYTE& operator[](DWORD dwOffset)
|
|
|
|
|
{
|
|
|
|
|
CN_ASSERT(F_);
|
|
|
|
|
|
|
|
|
|
if (F_ == L_)
|
|
|
|
|
{
|
|
|
|
|
CN_ASSERT(F_->S_ > dwOffset);
|
|
|
|
|
return F_->P_[dwOffset];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Iterator iter = Begin();
|
|
|
|
|
iter += dwOffset;
|
|
|
|
|
CN_ASSERT(iter);
|
|
|
|
|
return *iter;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
|
|
//! <20>½<EFBFBD><C2BD><EFBFBD> <20>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD><CEB2>
|
|
|
|
|
Block* NewBlock(DWORD dwSize)
|
|
|
|
|
{
|
|
|
|
|
dwSize = dwSize < M_ ? M_ : dwSize;
|
|
|
|
|
Block * pNew = (Block *) new BYTE[sizeof(Block) - 4 + dwSize];
|
|
|
|
|
|
|
|
|
|
if (pNew)
|
|
|
|
|
{
|
|
|
|
|
memset(pNew, 0, sizeof(Block));
|
|
|
|
|
pNew->S_ = dwSize;
|
|
|
|
|
|
|
|
|
|
if (L_)
|
|
|
|
|
L_->N_ = pNew, L_ = pNew;
|
|
|
|
|
else
|
|
|
|
|
F_ = L_ = pNew;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return pNew;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Block* F_;//!< ͷָ<CDB7><D6B8>
|
|
|
|
|
Block* L_;//!< βָ<CEB2><D6B8>
|
|
|
|
|
DWORD S_;//!< <20><>С
|
|
|
|
|
DWORD M_;//!< <20><><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD>
|
|
|
|
|
CRITICAL_SECTION C_;//!< <20><><EFBFBD>ṹ
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#if defined(CN_COMM_MFC_EXCEPTION)
|
|
|
|
|
/*! <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CN_COMM_MFC_EXCEPTION CN_ASSERT \n <20><>ʹ<EFBFBD><CAB9>throw new MfcException(msg);<3B><><EFBFBD><EFBFBD><EFBFBD>׳<EFBFBD>MFC<46>쳣(VC++) */
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>MFC<46><43><EFBFBD>쳣
|
|
|
|
|
class MfcException : public CException
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
//! <20><><EFBFBD>캯<EFBFBD><ECBAAF><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>CException<6F>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
MfcException(LPCTSTR szMsg) : CException(TRUE)
|
|
|
|
|
{
|
|
|
|
|
lstrcpy(szMsg_, szMsg);
|
|
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
CException::m_bReadyForDelete = TRUE;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>Ϣ
|
|
|
|
|
BOOL GetErrorMessage( LPTSTR lpszError, UINT nMaxError, PUINT pnHelpContext = NULL )
|
|
|
|
|
{
|
|
|
|
|
#ifndef CN_COMM_FOR_CE
|
|
|
|
|
lstrcpyn(lpszError, szMsg_, nMaxError);
|
|
|
|
|
#else
|
|
|
|
|
_tcsncpy(lpszError, szMsg_, nMaxError - 1);
|
|
|
|
|
lpszError[nMaxError - 1] = _T('\0');
|
|
|
|
|
#endif
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
protected:
|
|
|
|
|
TCHAR szMsg_[256]; //!< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ <20><>ʽ<EFBFBD><CABD>CN_ASSERT(<28><><EFBFBD><EFBFBD>ʽ) failed; ComComm(<28>к<EFBFBD>); Code(GetLastError()); <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
};
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//! <20>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣 <20><><EFBFBD>׳<EFBFBD><D7B3>쳣; δ<><CEB4><EFBFBD><EFBFBD><EFBFBD>쳣: DEBUG<55>汾 <20><><EFBFBD><EFBFBD>̨<EFBFBD>汾<EFBFBD><E6B1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ <20><><EFBFBD>˳<EFBFBD>; Release<73>汾<EFBFBD><E6B1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD>û<EFBFBD>Ҫ<EFBFBD><D2AA>
|
|
|
|
|
static bool Assert(LPCTSTR szMessage)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
//#if defined(_DEBUG) || defined(CN_COMM_STD_EXCEPTION) || defined(CN_COMM_VCL_EXCEPTION) || defined(CN_COMM_MFC_EXCEPTION)
|
|
|
|
|
// TCHAR szMsg[256];
|
|
|
|
|
// DWORD dwError, dwLength;
|
|
|
|
|
//
|
|
|
|
|
// _tcscpy_s(szMsg, szMessage);
|
|
|
|
|
|
|
|
|
|
// dwError = GetLastError();
|
|
|
|
|
// if (dwError)//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(GetLastError())<29><>Ϊ 0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
// {
|
|
|
|
|
// dwLength = _tcslen(szMsg);
|
|
|
|
|
// _sntprintf_s(szMsg + dwLength, 256 - _tcslen(szMsg), 256, _T("Code:%d; "), dwError);
|
|
|
|
|
// dwLength = _tcslen(szMsg);
|
|
|
|
|
|
|
|
|
|
// FormatMessage(
|
|
|
|
|
// FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
|
|
|
// NULL,
|
|
|
|
|
// dwError,
|
|
|
|
|
// MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
// szMsg + dwLength - 1,
|
|
|
|
|
// 256 - dwLength - 1,
|
|
|
|
|
// NULL
|
|
|
|
|
// );
|
|
|
|
|
// }
|
|
|
|
|
//#else
|
|
|
|
|
// ;// Release<73>汾 ʲô<CAB2><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ԥ<><D4A4>
|
|
|
|
|
//#endif
|
|
|
|
|
|
|
|
|
|
//#if defined(CN_COMM_STD_EXCEPTION)
|
|
|
|
|
|
|
|
|
|
// #ifdef _UNICODE
|
|
|
|
|
// char szTemp[512] = {0};
|
|
|
|
|
// WideCharToMultiByte(CP_ACP, 0, szMsg, -1, szTemp, wcslen(szMsg)*sizeof(wchar_t), NULL, NULL);
|
|
|
|
|
// throw std::runtime_error(szTemp);
|
|
|
|
|
// #else
|
|
|
|
|
// throw std::runtime_error(szMsg);
|
|
|
|
|
// #endif
|
|
|
|
|
|
|
|
|
|
//#elif defined(CN_COMM_VCL_EXCEPTION)
|
|
|
|
|
|
|
|
|
|
// throw Exception(szMsg);
|
|
|
|
|
|
|
|
|
|
//#elif defined(CN_COMM_MFC_EXCEPTION)
|
|
|
|
|
|
|
|
|
|
// throw (new MfcException(szMsg));
|
|
|
|
|
|
|
|
|
|
//#elif defined(_DEBUG)
|
|
|
|
|
|
|
|
|
|
// OutputDebugString(szMsg);
|
|
|
|
|
// #ifdef _CONSOLE
|
|
|
|
|
// // <20><>Ҫ setlocale(LC_ALL, "chs"); <20><><EFBFBD><EFBFBD>̨<EFBFBD>ſ<EFBFBD><C5BF><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD>UNICODE<44><45><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>ANSI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
// #ifdef _UNICODE
|
|
|
|
|
// char szTemp[512] = {0};
|
|
|
|
|
// WideCharToMultiByte(CP_ACP, 0, szMsg, -1, szTemp, wcslen(szMsg)*sizeof(wchar_t), NULL, NULL);
|
|
|
|
|
// fprintf(stderr, szTemp);
|
|
|
|
|
// #else
|
|
|
|
|
// fprintf(stderr, szMsg);
|
|
|
|
|
// #endif
|
|
|
|
|
|
|
|
|
|
// system("pause");
|
|
|
|
|
// exit(1);
|
|
|
|
|
// #else
|
|
|
|
|
// switch(MessageBox(NULL, szMsg, _T("CN_ASSERT"), MB_ABORTRETRYIGNORE))
|
|
|
|
|
// {
|
|
|
|
|
// case IDABORT:
|
|
|
|
|
// exit(1);
|
|
|
|
|
|
|
|
|
|
// case IDRETRY:
|
|
|
|
|
// DebugBreak();
|
|
|
|
|
// break;
|
|
|
|
|
|
|
|
|
|
// case IDIGNORE:
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// #endif
|
|
|
|
|
|
|
|
|
|
//#else
|
|
|
|
|
// ;// Release<73>汾 ʲô<CAB2><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ԥ<><D4A4>
|
|
|
|
|
//#endif
|
|
|
|
|
// return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
DWORD m_lReadTimeout;
|
|
|
|
|
ComCallback m_pComCb; //!< <20><><EFBFBD>ݻص<DDBB>
|
|
|
|
|
void* m_pUser; //!< <20><><EFBFBD>ݶ<EFBFBD><DDB6><EFBFBD>
|
|
|
|
|
std::function<void()> m_pfn;
|
|
|
|
|
DWORD dwOption_; //!< <20>ؼ<EFBFBD>ģʽ<C4A3><CABD><EFBFBD><EFBFBD> <20>ڹ<EFBFBD><DAB9>캯<EFBFBD><ECBAAF><EFBFBD><EFBFBD><EFBFBD>趨
|
|
|
|
|
HANDLE hComm_; //!< <20><><EFBFBD>ھ<EFBFBD><DABE><EFBFBD>
|
|
|
|
|
DWORD dwPort_; //!< <20><><EFBFBD>ں<EFBFBD> 0Ϊ<30><CEAA><EFBFBD><EFBFBD><E2B4AE> -1Ϊ<31><CEAA>Ч <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD>
|
|
|
|
|
TCHAR szName_[64]; //!< <20><><EFBFBD>洮<EFBFBD><E6B4AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>COM1<4D><31><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
|
|
|
|
CRITICAL_SECTION CS_; //!< <20>ٽ绥<D9BD><E7BBA5><EFBFBD><EFBFBD>
|
|
|
|
|
DCB DCB_; //!< <20><><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD>ֹͣλ<D6B9><CEBB><EFBFBD><EFBFBD>
|
|
|
|
|
COMMTIMEOUTS CO_; //!< <20><>ʱ<EFBFBD>ṹ
|
|
|
|
|
COMMPROP* pCP_; //!< <20><><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD>
|
|
|
|
|
|
|
|
|
|
BlockBuffer I_; //!< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
BlockBuffer O_; //!< д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
DWORD dwInCount_; //!< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
DWORD dwOutCount_; //!< д<><D0B4><EFBFBD><EFBFBD>
|
|
|
|
|
|
|
|
|
|
bool bContinue_; //!< <20>̼߳<DFB3><CCBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD>־
|
|
|
|
|
DWORD dwWaitEvent_; //!< WaitCommEvent <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>¼<EFBFBD>
|
|
|
|
|
|
|
|
|
|
HANDLE hWatchThread_; //!< <20><><EFBFBD>Ӹ<EFBFBD><D3B8><EFBFBD><EFBFBD>߳<EFBFBD>
|
|
|
|
|
DWORD hWatchThreadId_; //!< <20><><EFBFBD>Ӹ<EFBFBD><D3B8><EFBFBD><EFBFBD>߳<EFBFBD> ID
|
|
|
|
|
HANDLE hWatchEvent_; //!< ֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
|
|
|
|
|
|
|
|
|
|
HANDLE hReadThread_; //!< <20><><EFBFBD>ո<EFBFBD><D5B8><EFBFBD><EFBFBD>߳<EFBFBD> ʵ<><CAB5>˫<EFBFBD><CBAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>
|
|
|
|
|
DWORD hReadThreadId_; //!< <20><><EFBFBD>ո<EFBFBD><D5B8><EFBFBD><EFBFBD>߳<EFBFBD> ID
|
|
|
|
|
HANDLE hReadEvent_; //!< ֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
|
|
|
|
|
|
|
|
|
|
HANDLE hWriteThread_; //!< <20><><EFBFBD><EFBFBD><CDB8><EFBFBD><EFBFBD>߳<EFBFBD> ʵ<><CAB5>˫<EFBFBD><CBAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>
|
|
|
|
|
DWORD hWriteThreadId_; //!< <20><><EFBFBD><EFBFBD><CDB8><EFBFBD><EFBFBD>߳<EFBFBD> ID
|
|
|
|
|
HANDLE hWriteEvent_; //!< ֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
|
|
|
|
|
|
|
|
|
|
DWORD dwNotifyNum_; //!< <20><><EFBFBD>ܶ<EFBFBD><DCB6><EFBFBD><EFBFBD>ֽ<EFBFBD>(>=dwNotifyNum_)<29><><EFBFBD><EFBFBD>֪ͨ<CDA8><D6AA>Ϣ
|
|
|
|
|
|
|
|
|
|
#ifndef CN_COMM_FOR_CE
|
|
|
|
|
OVERLAPPED RO_; //!< <20>ص<EFBFBD>I/O ReadFile
|
|
|
|
|
OVERLAPPED WO_; //!< <20>ص<EFBFBD>I/O WriteFile
|
|
|
|
|
OVERLAPPED EO_; //!< <20>ص<EFBFBD>I/O WaitCommEvent
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//! <20><>ʼ<EFBFBD><CABC>
|
|
|
|
|
virtual void Init()
|
|
|
|
|
{
|
|
|
|
|
::InitializeCriticalSection(&CS_);
|
|
|
|
|
|
|
|
|
|
memset(szName_, 0, 64*sizeof(TCHAR));
|
|
|
|
|
|
|
|
|
|
memset(&DCB_, 0, sizeof(DCB_));
|
|
|
|
|
DCB_.DCBlength = sizeof(DCB_);
|
|
|
|
|
m_pComCb = NULL;
|
|
|
|
|
m_pUser = NULL;
|
|
|
|
|
hComm_ = INVALID_HANDLE_VALUE;
|
|
|
|
|
dwPort_ = (DWORD)-1;
|
|
|
|
|
dwOutCount_ = 0;
|
|
|
|
|
dwInCount_ = 0;
|
|
|
|
|
|
|
|
|
|
dwWaitEvent_ = CN_COMM_WAIT_EVENT;
|
|
|
|
|
hWatchThread_ = NULL;
|
|
|
|
|
hReadThread_ = NULL;
|
|
|
|
|
hWriteThread_ = NULL;
|
|
|
|
|
hWatchThreadId_ = 0;
|
|
|
|
|
hReadThreadId_ = 0;
|
|
|
|
|
hWriteThreadId_ = 0;
|
|
|
|
|
|
|
|
|
|
dwNotifyNum_ = 0;
|
|
|
|
|
pCP_ = NULL;
|
|
|
|
|
|
|
|
|
|
#ifndef CN_COMM_FOR_CE
|
|
|
|
|
memset(&RO_, 0, sizeof(RO_));
|
|
|
|
|
memset(&WO_, 0, sizeof(WO_));
|
|
|
|
|
memset(&EO_, 0, sizeof(EO_));
|
|
|
|
|
|
|
|
|
|
RO_.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
|
|
CN_ASSERT(RO_.hEvent != NULL);
|
|
|
|
|
|
|
|
|
|
WO_.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
|
|
CN_ASSERT(WO_.hEvent != NULL);
|
|
|
|
|
|
|
|
|
|
EO_.hEvent= ::CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
|
|
CN_ASSERT(EO_.hEvent != NULL);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
hWatchEvent_ = ::CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
|
|
CN_ASSERT(hWatchEvent_ != NULL);
|
|
|
|
|
hReadEvent_ = ::CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
|
|
CN_ASSERT(hReadEvent_ != NULL);
|
|
|
|
|
hWriteEvent_ = ::CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
|
|
CN_ASSERT(hWriteEvent_ != NULL);
|
|
|
|
|
m_lReadTimeout = 250;//250ms
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>
|
|
|
|
|
virtual void Destroy()
|
|
|
|
|
{
|
|
|
|
|
#ifndef CN_COMM_FOR_CE
|
|
|
|
|
if(RO_.hEvent != NULL)
|
|
|
|
|
CloseHandle(RO_.hEvent);
|
|
|
|
|
|
|
|
|
|
if(WO_.hEvent != NULL)
|
|
|
|
|
CloseHandle(WO_.hEvent);
|
|
|
|
|
|
|
|
|
|
if(EO_.hEvent != NULL)
|
|
|
|
|
CloseHandle(EO_.hEvent);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if(hWatchEvent_ != NULL)
|
|
|
|
|
CloseHandle(hWatchEvent_);
|
|
|
|
|
|
|
|
|
|
if(hReadEvent_ != NULL)
|
|
|
|
|
CloseHandle(hReadEvent_);
|
|
|
|
|
|
|
|
|
|
if(hWriteEvent_ != NULL)
|
|
|
|
|
CloseHandle(hWriteEvent_);
|
|
|
|
|
|
|
|
|
|
if (pCP_)
|
|
|
|
|
delete[] ((BYTE*)pCP_);
|
|
|
|
|
|
|
|
|
|
::DeleteCriticalSection(&CS_);
|
|
|
|
|
}
|
|
|
|
|
//! <20><EFBFBD><F3B6A8B4><EFBFBD>
|
|
|
|
|
void BindPort(DWORD dwPort)
|
|
|
|
|
{
|
|
|
|
|
dwPort_ = dwPort;
|
|
|
|
|
|
|
|
|
|
#if defined(CN_COMM_FOR_CE)
|
|
|
|
|
wsprintf(szName_, _T("COM%d:"), dwPort);
|
|
|
|
|
#else
|
|
|
|
|
wsprintf(szName_, _T("\\\\.\\COM%d"), dwPort);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
//! <20><EFBFBD><F2BFAAB4><EFBFBD>
|
|
|
|
|
virtual bool OpenPort()
|
|
|
|
|
{
|
|
|
|
|
CN_ASSERT(!IsOpen());
|
|
|
|
|
|
|
|
|
|
if(IsOpen())
|
|
|
|
|
Close();
|
|
|
|
|
|
|
|
|
|
hComm_ = ::CreateFile(
|
|
|
|
|
szName_,
|
|
|
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
|
|
|
0,
|
|
|
|
|
NULL,
|
|
|
|
|
OPEN_EXISTING,
|
|
|
|
|
FILE_ATTRIBUTE_NORMAL | (IsOverlappedMode() ? FILE_FLAG_OVERLAPPED : 0),
|
|
|
|
|
NULL
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return IsOpen();
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>ô<EFBFBD><C3B4><EFBFBD>
|
|
|
|
|
virtual bool SetupPort()
|
|
|
|
|
{
|
|
|
|
|
if(!CN_ASSERT(IsOpen()))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
#if defined(CN_COMM_FOR_CE)
|
|
|
|
|
::SetupComm(hComm_, 4096, 4096);
|
|
|
|
|
#else
|
|
|
|
|
if(!CN_ASSERT(::SetupComm(hComm_, 4096, 4096)))//! <20><><EFBFBD>ö˿ڷ<CBBF><DAB7>ͽ<EFBFBD><CDBD>ն<EFBFBD><D5B6>д<EFBFBD>С, <20><>4096<39>ֽ<EFBFBD>, д4096<39>ֽ<EFBFBD>, <20><><EFBFBD><EFBFBD>I/Oģʽ<C4A3><CABD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
return false;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if(!CN_ASSERT(::GetCommTimeouts(hComm_, &CO_)))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
CO_.ReadIntervalTimeout = 50;//! <20><><EFBFBD>ó<EFBFBD>ʱ<EFBFBD>ṹ <20>ַ<EFBFBD><D6B7><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD>100ms
|
|
|
|
|
CO_.ReadTotalTimeoutMultiplier = 0;
|
|
|
|
|
CO_.ReadTotalTimeoutConstant = IsOverlappedMode() ? 500 : m_lReadTimeout;//! <20><><EFBFBD><EFBFBD>ʱ <20>ص<EFBFBD>I/Oģʽ<C4A3><CABD>500<30><30><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>I/Oģʽ<C4A3><CABD>250<35><30><EFBFBD><EFBFBD>
|
|
|
|
|
CO_.WriteTotalTimeoutMultiplier = IsOverlappedMode() ? 1 : 0;
|
|
|
|
|
CO_.WriteTotalTimeoutConstant = IsOverlappedMode() ? 10000 : 250;//! д<><D0B4>ʱ <20>ص<EFBFBD>I/Oģʽ<C4A3><CABD>(10000+1<><31><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>)<29><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>I/Oģʽ<C4A3><CABD>250<35><30><EFBFBD><EFBFBD>
|
|
|
|
|
|
|
|
|
|
if(!CN_ASSERT(::SetCommTimeouts(hComm_, &CO_)))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if(!CN_ASSERT(::PurgeComm(hComm_, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR )))//! <20><><EFBFBD><EFBFBD><EFBFBD>˿<EFBFBD>
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD>˿<EFBFBD><CBBF><EFBFBD><EFBFBD>ݶ<EFBFBD><DDB6>뻺<EFBFBD><EBBBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
DWORD PortToBuffer(DWORD dwPortByteNum)
|
|
|
|
|
{
|
|
|
|
|
BlockBuffer::InnerLock locker(&I_);
|
|
|
|
|
return dwPortByteNum ? I_.Release(ReadPort(I_.GetFreePtr(dwPortByteNum), dwPortByteNum)) : 0;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD>˿<EFBFBD>
|
|
|
|
|
DWORD BufferToPort(DWORD dwMaxSize = 1024)
|
|
|
|
|
{
|
|
|
|
|
if (IsOverlappedMode())
|
|
|
|
|
{
|
|
|
|
|
BlockBuffer::InnerLock locker(&O_);
|
|
|
|
|
|
|
|
|
|
if (!O_.Size())
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
DWORD dwWrite = dwMaxSize > O_.GetPtrSize() ? O_.GetPtrSize() : dwMaxSize;
|
|
|
|
|
WritePort(O_.GetPtr(), dwWrite);
|
|
|
|
|
return O_.Read(NULL, dwWrite);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
BYTE btTemp[1024];
|
|
|
|
|
DWORD dwLength, dwIndex = 0;
|
|
|
|
|
|
|
|
|
|
O_.Lock();
|
|
|
|
|
dwLength = O_.Read(btTemp, 1024);
|
|
|
|
|
O_.Unlock();
|
|
|
|
|
|
|
|
|
|
while ( dwIndex < dwLength )
|
|
|
|
|
dwIndex += WritePort(btTemp + dwIndex, dwLength - dwIndex);
|
|
|
|
|
|
|
|
|
|
return dwLength;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/*! \param uMsg <20><>Ϣ \param lParam <20><><EFBFBD><EFBFBD> \param bPostMode <20><><EFBFBD><EFBFBD>PostMessage<67><65><EFBFBD><EFBFBD>SendMessage<67><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ*/
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD>ھ<EFBFBD><DABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>ID<49><44>Ч, <20>ͳ<EFBFBD><CDB3><EFBFBD>Ϣ, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD>¼<EFBFBD>֪ͨ, WPARAMĬ<4D>ϰ<EFBFBD><CFB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڱ<EFBFBD><DAB1><EFBFBD>
|
|
|
|
|
virtual void Notify(UINT uMsg, LPARAM lParam = 0, bool bPostMode = true)
|
|
|
|
|
{
|
|
|
|
|
if (NULL != m_pComCb)
|
|
|
|
|
m_pComCb(uMsg, m_pUser);
|
|
|
|
|
else if (m_pfn != nullptr)
|
|
|
|
|
m_pfn();
|
|
|
|
|
}
|
|
|
|
|
//---------------------------------------threads callback-----------------------------------------------------
|
|
|
|
|
//! <20><>ӦEV_RXCHAR<41>¼<EFBFBD> <20><><EFBFBD>̻߳ص<CCBB>, <20>麯<EFBFBD><E9BAAF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڻ<EFBFBD><DABB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ(<28>Ƽ<EFBFBD><C6BC><EFBFBD>ʽ)
|
|
|
|
|
virtual void OnReceive()
|
|
|
|
|
{
|
|
|
|
|
Notify(ON_COM_RECEIVE);
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ӦEV_DSR<53>¼<EFBFBD>
|
|
|
|
|
virtual void OnDSR()
|
|
|
|
|
{
|
|
|
|
|
Notify(ON_COM_DSR, CheckDSR() ? 1 : 0);
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ӦEV_CTS<54>¼<EFBFBD>
|
|
|
|
|
virtual void OnCTS()
|
|
|
|
|
{
|
|
|
|
|
Notify(ON_COM_CTS, CheckCTS() ? 1 : 0);
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ӦEV_BREAK<41>¼<EFBFBD>
|
|
|
|
|
virtual void OnBreak()
|
|
|
|
|
{
|
|
|
|
|
ClearCommBreak(hComm_);
|
|
|
|
|
Notify(ON_COM_BREAK);
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ӦEV_TXEMPTY<54>¼<EFBFBD>
|
|
|
|
|
virtual void OnTxEmpty()
|
|
|
|
|
{
|
|
|
|
|
Notify(ON_COM_TXEMPTY);
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ӦEV_ERROR<4F>¼<EFBFBD>
|
|
|
|
|
virtual void OnError()
|
|
|
|
|
{
|
|
|
|
|
Notify(ON_COM_ERROR, ClearError());
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ӦEV_RING<4E>¼<EFBFBD>
|
|
|
|
|
virtual void OnRing()
|
|
|
|
|
{
|
|
|
|
|
Notify(ON_COM_RING, CheckRING() ? 1 : 0);
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ӦEV_RLSD<53>¼<EFBFBD>
|
|
|
|
|
virtual void OnRLSD()
|
|
|
|
|
{
|
|
|
|
|
Notify(MS_RLSD_ON, CheckRLSD() ? 1 : 0);
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ӦEV_RXFLAG<41>¼<EFBFBD>
|
|
|
|
|
virtual void OnRxFlag()
|
|
|
|
|
{
|
|
|
|
|
Notify(ON_COM_RXFLAG);
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ӦEV_POWER<45>¼<EFBFBD>
|
|
|
|
|
virtual void OnPower()
|
|
|
|
|
{
|
|
|
|
|
Notify(ON_COM_POWER);
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ӦEV_RX80FULL<4C>¼<EFBFBD>
|
|
|
|
|
virtual void OnRx80Full()
|
|
|
|
|
{
|
|
|
|
|
Notify(ON_COM_RX80FULL);
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ӦEV_EVENT1<54>¼<EFBFBD>
|
|
|
|
|
virtual void OnEvent1()
|
|
|
|
|
{
|
|
|
|
|
Notify(ON_COM_EVENT1);
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ӦEV_EVENT2<54>¼<EFBFBD>
|
|
|
|
|
virtual void OnEvent2()
|
|
|
|
|
{
|
|
|
|
|
Notify(ON_COM_EVENT2);
|
|
|
|
|
}
|
|
|
|
|
//! <20><>ӦEV_PERR<52>¼<EFBFBD>
|
|
|
|
|
virtual void OnPrintErr()
|
|
|
|
|
{
|
|
|
|
|
Notify(ON_COM_PERR);
|
|
|
|
|
}
|
|
|
|
|
//! ͨ<>õ<EFBFBD><C3B5>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
virtual void HandleEvent(DWORD dwMask)
|
|
|
|
|
{
|
|
|
|
|
if ((dwMask & EV_RXCHAR) && !(dwOption_&EN_RX_THREAD))
|
|
|
|
|
{
|
|
|
|
|
DWORD dwLength = GetQueueCount(true);
|
|
|
|
|
|
|
|
|
|
if (dwLength)
|
|
|
|
|
{
|
|
|
|
|
if (dwOption_ & EN_RX_BUFFER)
|
|
|
|
|
{
|
|
|
|
|
PortToBuffer((dwLength << 1) + 64);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>϶<EFBFBD><CFB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
|
|
|
|
if (I_.Size() >= dwNotifyNum_)
|
|
|
|
|
OnReceive();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (dwLength >= dwNotifyNum_)
|
|
|
|
|
OnReceive();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dwMask & EV_TXEMPTY)
|
|
|
|
|
{
|
|
|
|
|
if ((dwOption_&EN_TX_BUFFER) && !(dwOption_&EN_TX_THREAD) && O_.SafeSize())
|
|
|
|
|
BufferToPort();
|
|
|
|
|
|
|
|
|
|
OnTxEmpty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dwMask & EV_RXFLAG)
|
|
|
|
|
OnRxFlag();
|
|
|
|
|
|
|
|
|
|
if (dwMask & EV_CTS)
|
|
|
|
|
OnCTS();
|
|
|
|
|
|
|
|
|
|
if (dwMask & EV_DSR)
|
|
|
|
|
OnDSR();
|
|
|
|
|
|
|
|
|
|
if (dwMask & EV_RING)
|
|
|
|
|
OnRing();
|
|
|
|
|
|
|
|
|
|
if (dwMask & EV_RLSD)
|
|
|
|
|
OnRLSD();
|
|
|
|
|
|
|
|
|
|
if (dwMask & EV_BREAK)
|
|
|
|
|
OnBreak();
|
|
|
|
|
|
|
|
|
|
if (dwMask & EV_ERR)
|
|
|
|
|
OnError();
|
|
|
|
|
|
|
|
|
|
#ifdef CN_COMM_FOR_CE
|
|
|
|
|
if (dwMask & EV_POWER)
|
|
|
|
|
OnPower();
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef CN_COMM_FOR_CE
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>I/Oģ<4F><C4A3>
|
|
|
|
|
virtual DWORD OverlappedModel()
|
|
|
|
|
{
|
|
|
|
|
if(!CN_ASSERT(IsOpen()))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
if(!CN_ASSERT(::SetCommMask(hComm_, dwWaitEvent_)))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
for(DWORD dwMask = 0, dwLength; bContinue_ && IsOpen(); dwMask = 0)
|
|
|
|
|
{
|
|
|
|
|
if (GetQueueCount(true))//! <20>ȴ<EFBFBD><C8B4>¼<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>ɨ<EFBFBD><C9A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>һ<EFBFBD><D2BB>EV_RXCHAR<41>¼<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
dwMask = EV_RXCHAR, Sleep(10);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(!::WaitCommEvent(hComm_, &dwMask, &EO_))
|
|
|
|
|
{
|
|
|
|
|
if(::GetLastError() == ERROR_IO_PENDING)
|
|
|
|
|
::GetOverlappedResult(hComm_, &EO_, &dwLength, TRUE);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Sleep(10);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(dwMask == 0)
|
|
|
|
|
{
|
|
|
|
|
if ((dwOption_&EN_TX_BUFFER) && !(dwOption_&EN_TX_THREAD) && O_.SafeSize())
|
|
|
|
|
BufferToPort();
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HandleEvent(dwMask);
|
|
|
|
|
}//for
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>I/Oģ<4F><C4A3>
|
|
|
|
|
virtual DWORD NonoverlappedModel()
|
|
|
|
|
{
|
|
|
|
|
if(!CN_ASSERT(IsOpen()))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
for (DWORD dwReturn; bContinue_ && IsOpen();)
|
|
|
|
|
{
|
|
|
|
|
dwReturn = WaitForSingleObject(hWatchEvent_, 50);
|
|
|
|
|
|
|
|
|
|
if (!bContinue_)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
switch (dwReturn)
|
|
|
|
|
{
|
|
|
|
|
case WAIT_OBJECT_0:
|
|
|
|
|
while ((dwOption_&EN_TX_BUFFER) && O_.SafeSize())
|
|
|
|
|
BufferToPort();
|
|
|
|
|
|
|
|
|
|
ResetEvent(hWatchEvent_);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case WAIT_TIMEOUT:
|
|
|
|
|
|
|
|
|
|
DWORD dwLength = GetQueueCount(true);
|
|
|
|
|
|
|
|
|
|
if (dwLength)
|
|
|
|
|
{
|
|
|
|
|
if (dwOption_ & EN_RX_BUFFER)
|
|
|
|
|
{
|
|
|
|
|
PortToBuffer(dwLength);
|
|
|
|
|
|
|
|
|
|
if (I_.Size() >= dwNotifyNum_)
|
|
|
|
|
OnReceive();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (dwLength >= dwNotifyNum_)
|
|
|
|
|
OnReceive();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( (dwOption_&EN_TX_BUFFER) && O_.SafeSize() )
|
|
|
|
|
BufferToPort();
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#ifdef CN_COMM_FOR_CE
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD>WINCE<43><45>I/Oģ<4F><C4A3>(<28>ص<EFBFBD>+<2B><><EFBFBD><EFBFBD> Ҳ<><D2B2>֪<D6AA><CEA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʲôģʽ)
|
|
|
|
|
virtual DWORD EmbeddedModel()
|
|
|
|
|
{
|
|
|
|
|
if(!CN_ASSERT(IsOpen()))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
if(!CN_ASSERT(::SetCommMask(hComm_, dwWaitEvent_)))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
for(DWORD dwMask = 0; bContinue_ && IsOpen(); dwMask = 0)
|
|
|
|
|
{
|
|
|
|
|
if (GetQueueCount(true))//! <20>ȴ<EFBFBD><C8B4>¼<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>ɨ<EFBFBD><C9A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>һ<EFBFBD><D2BB>EV_RXCHAR<41>¼<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
dwMask = EV_RXCHAR, Sleep(10);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(!::WaitCommEvent(hComm_, &dwMask, NULL))
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(dwMask == 0)
|
|
|
|
|
{
|
|
|
|
|
if ( (dwOption_&EN_TX_BUFFER) && !(dwOption_&EN_TX_THREAD) && O_.SafeSize())
|
|
|
|
|
BufferToPort();
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HandleEvent(dwMask);
|
|
|
|
|
|
|
|
|
|
}//for
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>˫<EFBFBD><CBAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD><EFBFBD>Ըı<D4B8><C4B1><EFBFBD>;
|
|
|
|
|
virtual DWORD ReadModel()
|
|
|
|
|
{
|
|
|
|
|
while(bContinue_)
|
|
|
|
|
{
|
|
|
|
|
Sleep(50);
|
|
|
|
|
|
|
|
|
|
DWORD dwLength = GetQueueCount(true);
|
|
|
|
|
|
|
|
|
|
if (dwLength)
|
|
|
|
|
{
|
|
|
|
|
if (dwOption_ & EN_RX_BUFFER)
|
|
|
|
|
{
|
|
|
|
|
PortToBuffer(dwLength);
|
|
|
|
|
|
|
|
|
|
if (I_.Size() >= dwNotifyNum_)
|
|
|
|
|
OnReceive();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (dwLength >= dwNotifyNum_)
|
|
|
|
|
OnReceive();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD>˫<EFBFBD><CBAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD><EFBFBD>Ըı<D4B8><C4B1><EFBFBD>;
|
|
|
|
|
virtual DWORD WriteModel()
|
|
|
|
|
{
|
|
|
|
|
if (!IsOpen())
|
|
|
|
|
{
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
CN_ASSERT(dwOption_ & EN_TX_BUFFER);
|
|
|
|
|
|
|
|
|
|
while (bContinue_)
|
|
|
|
|
{
|
|
|
|
|
DWORD dwReturn = ::WaitForSingleObject(hWriteEvent_, 200);
|
|
|
|
|
|
|
|
|
|
while(bContinue_ && O_.SafeSize())
|
|
|
|
|
BufferToPort();
|
|
|
|
|
|
|
|
|
|
if (dwReturn == WAIT_OBJECT_0)
|
|
|
|
|
ResetEvent(hWatchEvent_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
//! <20><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
ComComm(const ComComm&);
|
|
|
|
|
//! <20><>ֹ<EFBFBD><D6B9>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>
|
|
|
|
|
ComComm &operator = (const ComComm&);
|
|
|
|
|
|
|
|
|
|
#if defined(_MT) && !defined(CN_COMM_FOR_CE)
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD> Watch MyThread <20><><EFBFBD>ɼ<EFBFBD><C9BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>þ<EFBFBD><C3BE><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ɶ<EFBFBD>д
|
|
|
|
|
static UINT APIENTRY WatchThreadProc(LPVOID lpPara)
|
|
|
|
|
#else
|
|
|
|
|
//! <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD> Watch MyThread <20><><EFBFBD>ɼ<EFBFBD><C9BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>þ<EFBFBD><C3BE><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ɶ<EFBFBD>д
|
|
|
|
|
static DWORD WINAPI WatchThreadProc(LPVOID lpPara)
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
#ifdef CN_COMM_FOR_CE
|
|
|
|
|
DWORD dwCode = ((ComComm *)lpPara)->EmbeddedModel();
|
|
|
|
|
#else
|
|
|
|
|
DWORD dwCode = ((ComComm *)lpPara)->IsOverlappedMode()
|
|
|
|
|
? ((ComComm *)lpPara)->OverlappedModel()
|
|
|
|
|
: ((ComComm *)lpPara)->NonoverlappedModel();
|
|
|
|
|
|
|
|
|
|
#if defined(_MT)
|
|
|
|
|
_endthreadex(dwCode);
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return dwCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if defined(_MT) && !defined(CN_COMM_FOR_CE)
|
|
|
|
|
//! ˫<><CBAB><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD> <20><>ʱδ<CAB1><CEB4> <20><><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><C3B2><EFBFBD>
|
|
|
|
|
static UINT APIENTRY ReadThreadProc(LPVOID lpPara)
|
|
|
|
|
#else
|
|
|
|
|
//! ˫<><CBAB><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD> <20><>ʱδ<CAB1><CEB4> <20><><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><C3B2><EFBFBD>
|
|
|
|
|
static DWORD WINAPI ReadThreadProc(LPVOID lpPara)
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
DWORD dwCode = ((ComComm *)lpPara)->ReadModel();
|
|
|
|
|
|
|
|
|
|
#if defined(_MT) && !defined(CN_COMM_FOR_CE)
|
|
|
|
|
_endthreadex(dwCode);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return dwCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if defined(_MT) && !defined(CN_COMM_FOR_CE)
|
|
|
|
|
//! ˫<><CBAB><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD> WINCE<43><45><EFBFBD>Բ<EFBFBD><D4B2><EFBFBD>
|
|
|
|
|
static UINT APIENTRY WriteThreadProc(LPVOID lpPara)
|
|
|
|
|
#else
|
|
|
|
|
//! ˫<><CBAB><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD> WINCE<43><45><EFBFBD>Բ<EFBFBD><D4B2><EFBFBD>
|
|
|
|
|
static DWORD WINAPI WriteThreadProc(LPVOID lpPara)
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
DWORD dwCode = ((ComComm *)lpPara)->WriteModel();
|
|
|
|
|
|
|
|
|
|
#if defined(_MT) && !defined(CN_COMM_FOR_CE)
|
|
|
|
|
_endthreadex(dwCode);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return dwCode;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif //! _CN_COMM_H_
|