www.pudn.com > PocketPC_ComAPI.rar > SerComm.cs, change:2007-04-22,size:15202b


using System; 
using System.Text; 
using System.Runtime.InteropServices; 
using System.ComponentModel; 
 
namespace CADmaping 
{ 
	public class SerComm 
	{ 
		private int mintHandle  = INVALID_HANDLE_VALUE;    
		private int mintPort = 1;                          
		private byte mbytParity = NOPARITY;              
		private byte mbytDataBits = DATABITS_8;           
		private byte mbytStopBits = STOPBITS_10;         
		private int mintBaudRate = CBR_1200;              
		private int mintTXBufferSize = 512;              
		private int mintRXBufferSize = 512;              
		private int mintTimeout = 100;                  
		private byte[] mbytTxBuffer;                 
		 
		private byte[] mbytRxBuffer;                 
		 
		#region "constants" 
 
		private const int GENERIC_READ = unchecked((int)0x80000000); 
		private const int GENERIC_WRITE = 0x40000000; 
		private const int OPEN_EXISTING = 3; 
		private const int INVALID_HANDLE_VALUE = -1; 
		private const int PURGE_TXCLEAR = 0x4; 
		private const int PURGE_RXCLEAR = 0x8; 
		private const byte STOPBITS_10 = 0x1; 
		private const byte STOPBITS_15 = 0x2; 
		private const byte STOPBITS_20 = 0x4; 
		private const byte DATABITS_7 = 0x4; 
		private const byte DATABITS_8 = 0x8; 
		private const byte EVENPARITY = 2; 
		private const byte MARKPARITY = 3; 
		private const byte NOPARITY = 0; 
		private const byte ODDPARITY = 1; 
		private const byte SPACEPARITY = 4; 
		private const int CBR_110 = 110; 
		private const int CBR_1200 = 1200; 
		private const int CBR_2400 = 2400; 
		private const int CBR_4800 = 4800; 
		private const int CBR_9600 = 9600; 
		 
 
		#endregion 
 
		#region "Typedefs" 
 
		#region "COMMTIMEOUTS" 
 
		private struct COMMTIMEOUTS  
		{												   
			public Int32 ReadIntervalTimeout;            
			public Int32 ReadTotalTimeoutMultiplier;       
			public Int32 ReadTotalTimeoutconstant;        
			public Int32 WriteTotalTimeoutMultiplier;    
			public Int32 WriteTotalTimeoutconstant;       
		}                                                
 
		#endregion    
		#region "DCB" 
		 
		private struct DCB 
		{ 
			public int DCBlength;         
			public int BaudRate;         
			public int fBinary;          
			public int fParity;            
			public int fOutxCtsFlow;      // CTS (clear-to-send)  
			public int fOutxDsrFlow;      // DSR (data-set-ready) 
			public int fDtrControl;       // DTR (data-terminal-ready)  
			public int fDsrSensitivity;   
			public int fTXContinueOnXoff; 
			public int fOutX;             
			public int fInX;               
			public int fErrorChar;    
			public int fNull;              
			public int fRtsControl;       // RTS (request-to-send) 
			public int fAbortOnError;     
			public int fDummy2;          
			public Int16 wReserved;     
			public Int16 XonLim;          
			public Int16 XoffLim;          
			public byte ByteSize;         
			public byte Parity;          
			public byte StopBits;          
			public char XonChar;      
			public char XoffChar;         
			public char ErrorChar;        
			public char EofChar;       
			public char EvtChar;        
			public Int16 wReserved1;      
		} 
 
		#endregion         
 
		#region "OVERLAPPED" 
		 
		private class OVERLAPPED             
		{ 
			public int Internal;			 
			public int InternalHigh;	 
			public int Offset;		       
			public int OffsetHigh;		 
			public int hEvent;		       
		} 
 
		#endregion      
 
		#endregion 
 
		#region "API functions" 
 
		#region "Comm" 
 
		#region "GetCommState" 
	 
		[DllImport ("coredll.dll")]  
		private static extern int GetCommState(int hCommDev ,out DCB lpDCB); 
 
		#endregion         
 
		#region "PurgeComm" 
		 
		[DllImport ("coredll.dll")]  
		private static extern int PurgeComm(int hFile, int dwFlags); 
		#endregion           
 
		#region "SetCommState" 
		 
		[DllImport ("coredll.dll")]  
		private static extern int SetCommState(int hFile, ref DCB lpDCB); 
 
		#endregion       
 
		#region "SetCommTimeouts" 
		 
		[DllImport ("coredll.dll")]  
		private static extern int SetCommTimeouts(int hFile, COMMTIMEOUTS lpCommTimeouts); 
 
		#endregion     
 
		#region "SetupComm" 
		 
		[DllImport ("coredll.dll")]  
		private static extern int SetupComm(int hFile, int dwInQueue, int dwOutQueue); 
 
		#endregion           
 
		#endregion       
 
		#region "File I/O" 
 
		#region "CloseHandle" 
		 
		[DllImport ("coredll.dll")]  
		private static extern int CloseHandle(int hObject); 
 
		#endregion         
 
		#region "CreateFile" 
		 
		[DllImport ("coredll.dll")]  
		private static extern int CreateFile(  
			string lpFileName,  
			int dwDesiredAccess,  
			int dwShareMode,  
			int lpSecurityAttributes,  
			int dwCreationDisposition,  
			int dwFlagsAndAttributes, 
			int hTemplateFile); 
 
		#endregion         
 
		#region "ReadFile" 
		 
		[DllImport ("coredll.dll")]  
		private static extern int ReadFile( 
			int hFile, 
			byte[] lpBuffer, 
			int nNumberOfBytesToRead, 
			ref int lpNumberOfBytesRead, 
			ref OVERLAPPED lpOverlapped); 
 
		#endregion            
 
		#region "WriteFile" 
		 
		[DllImport ("coredll.dll")]  
		private static extern int WriteFile( 
			int hFile, 
			byte[] lpBuffer, 
			int nNumberOfBytesToWrite, 
			ref int lpNumberOfBytesWritten, 
			ref OVERLAPPED lpOverlapped); 
 
		#endregion           
 
		#endregion    
 
		#endregion 
 
		#region "public instance properties" 
 
		#region "BaudRate" 
		 
		public int BaudRate 
		{ 
			get 
			{ 
				return mintBaudRate; 
			} 
			set 
			{ 
				if (value == CBR_1200 ||  
					value == CBR_2400 ||  
					value == CBR_4800 ||  
					value == CBR_9600 )  
				{ 
					mintBaudRate = value; 
				} 
				else 
				{ 
					throw new Exception("无效的波特率数值!"); 
				} 
			} 
		} 
		#endregion      
 
		#region "CommID" 
		public int CommID 
		{ 
			get 
			{ 
				return mintHandle; 
			} 
		} 
		#endregion          
 
		#region "CommPort" 
		public int CommPort 
		{ 
			get 
			{ 
				return mintPort; 
			} 
			set 
			{ 
				mintPort = value; 
				if (mintPort < 1 || mintPort > 16) 
				{ 
					throw new Exception("Invalid port number"); 
				} 
				else 
				{ 
					mintHandle = CreateFile("COM" + mintPort.ToString() + ":",  
						GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); 
					if (mintHandle == INVALID_HANDLE_VALUE) 
					{ 
						throw new Exception("端口已被占用!"); 
					} 
					else 
					{ 
						mintHandle = Close(mintHandle); 
					} 
				} 
			} 
		} 
		#endregion      
 
		#region "DataBits" 
		public int DataBits 
		{ 
			get 
			{ 
				int retval = 0; 
				switch (mbytDataBits) 
				{ 
					case DATABITS_7: 
						retval = 7; 
						break; 
					case DATABITS_8: 
						retval = 8; 
						break; 
				} 
				return retval; 
			} 
			set 
			{ 
				switch (value) 
				{ 
					case 7: 
						mbytDataBits = DATABITS_7; 
						break; 
					case 8: 
						mbytDataBits = DATABITS_8; 
						break; 
					default: 
						throw new Exception("无效的数据位!"); 
				} 
			} 
		} 
		#endregion      
 
		#region "InputLen" 
		public int InputLen 
		{ 
			get 
			{ 
				return mintRXBufferSize; 
			} 
			set 
			{ 
				mintRXBufferSize = value; 
			} 
		} 
		#endregion      
 
		#region "OutputLen" 
		public int OutputLen 
		{ 
			get 
			{ 
				return mintTXBufferSize; 
			} 
			set 
			{ 
				mintTXBufferSize = value; 
			} 
		} 
		#endregion      
 
		#region "Parity" 
		public String Parity 
		{ 
			get 
			{ 
				String retval = ""; 
				switch (mbytParity) 
				{ 
					case EVENPARITY: 
						retval = "E"; 
						break; 
					case MARKPARITY: 
						retval = "M"; 
						break; 
					case NOPARITY: 
						retval = "N"; 
						break; 
					case ODDPARITY: 
						retval = "O"; 
						break; 
					case SPACEPARITY: 
						retval = "S"; 
						break; 
				} 
				return retval; 
			} 
			set 
			{ 
				if (value.Length > 1) 
					value = value.Substring(0,1); 
				switch (value) 
				{ 
					case "E": 
						mbytParity = EVENPARITY; 
						break; 
					case "M": 
						mbytParity = MARKPARITY; 
						break; 
					case "N": 
						mbytParity = NOPARITY; 
						break; 
					case "O": 
						mbytParity = ODDPARITY; 
						break; 
					case "S": 
						mbytParity = SPACEPARITY; 
						break; 
					default: 
						throw new Exception("无效的奇偶属性!"); 
				} 
			} 
		} 
		#endregion        
 
		#region "PortOpen" 
		public bool PortOpen 
		{ 
			get 
			{ 
				if (mintHandle == INVALID_HANDLE_VALUE) 
					return false; 
				else 
					return true; 
			} 
			set 
			{ 
				if (value) 
					mintHandle = Open(mintPort, mintBaudRate, mbytParity, mbytDataBits, mbytStopBits, mintTXBufferSize, mintRXBufferSize, mintTimeout); 
				else 
					mintHandle = Close(mintHandle); 
			} 
		} 
		#endregion    
 
		#region "StopBits" 
		public int StopBits 
		{ 
			get  
			{ 
				int retval = 0; 
				switch (mbytStopBits) 
				{ 
					case STOPBITS_10: 
						retval = 1; 
						break; 
					case STOPBITS_15: 
						retval = 2; 
						break; 
					case STOPBITS_20: 
						retval = 3; 
						break; 
				} 
				return retval; 
			} 
			set  
			{ 
				switch (value) 
				{ 
					case 1: 
						mbytStopBits = STOPBITS_10; 
						break; 
					case 2: 
						mbytStopBits = STOPBITS_15; 
						break; 
					case 3: 
						mbytStopBits = STOPBITS_20; 
						break; 
					 
					default: 
						throw new Exception("无效的停止位!"); 
				} 
			} 
		} 
		#endregion         
		#region "Timeout" 
		public int Timeout 
		{ 
			get 
			{ 
				return mintTimeout; 
			} 
			set 
			{ 
				mintTimeout = value; 
			} 
		} 
		#endregion      
 
		#endregion 
 
		#region "public instance methods" 
 
		#region "Input" 
 
		public String Input() 
		{ 
			return Input(0); 
		} 
 
		public string Input(int BytesToRead) 
		{ 
			string result = ""; 
			int intResult; 
			ASCIIEncoding objEncoder = new ASCIIEncoding(); 
			int lpNumberOfBytesRead = 0; 
			OVERLAPPED lpOverlapped; 
 
			if (BytesToRead == 0) 
				BytesToRead = mintRXBufferSize; 
			if (mintHandle != INVALID_HANDLE_VALUE) 
			{ 
				mbytRxBuffer = new byte[BytesToRead]; 
				lpOverlapped = new OVERLAPPED(); 
				intResult = ReadFile(mintHandle, mbytRxBuffer, BytesToRead, ref lpNumberOfBytesRead, ref lpOverlapped); 
				if (intResult == 0) 
				{ 
					mintHandle = INVALID_HANDLE_VALUE; 
					throw new Exception("读COM:" + mintPort.ToString() +"时发生错误!"); 
				} 
				else 
				{ 
					result = objEncoder.GetString(mbytRxBuffer, 0, BytesToRead); 
				} 
			} 
 
			return result; 
		} 
		#endregion          
 
		#region "Constructors" 
 
		public Comm() 
		{ 
		} 
 
		public Comm(int port, int baudrate, String parity, int databits, int stopbits) 
		{ 
			mintPort = port; 
			mintBaudRate = baudrate; 
			switch (parity) 
			{ 
				case "E": 
					mbytParity = EVENPARITY; 
					break; 
				case "M": 
					mbytParity = MARKPARITY; 
					break; 
				case "O": 
					mbytParity = ODDPARITY; 
					break; 
				case "S": 
					mbytParity = SPACEPARITY; 
					break; 
				default: 
					mbytParity = NOPARITY; 
					break; 
			} 
 
			switch (databits) 
			{ 
				case 7: 
					mbytDataBits = DATABITS_7; 
					break; 
				default: 
					mbytDataBits = DATABITS_8; 
					break; 
			} 
 
			switch (stopbits) 
			{ 
				case 2: 
					mbytStopBits = STOPBITS_15; 
					break; 
				default: 
					mbytStopBits = STOPBITS_10; 
					break; 
			} 
		} 
		#endregion       
 
		#region "Output" 
		public void Output(String Value) 
		{ 
			int intResult; 
			int lpNumberOfBytesWritten = 0; 
			OVERLAPPED lpOverlapped = new OVERLAPPED(); 
			ASCIIEncoding objEncoder = new ASCIIEncoding(); 
 
			if (mintHandle != INVALID_HANDLE_VALUE) 
			{ 
				mbytTxBuffer = new byte[Value.Length]; 
				mbytTxBuffer = objEncoder.GetBytes(Value); 
				intResult = WriteFile(mintHandle, mbytTxBuffer, mbytTxBuffer.Length, ref lpNumberOfBytesWritten, ref lpOverlapped); 
			} 
		} 
		#endregion  
 
		#endregion 
 
		#region "private instance methods" 
 
		#region "Open" 
		private int Open(int port, int baudrate, byte parity, byte databits, byte stopbits, int txbuffersize, int rxbuffersize,int timeout ) 
		{ 
			int intResult; 
			int intHandle = INVALID_HANDLE_VALUE; 
			COMMTIMEOUTS lpCommTimeouts; 
			DCB lpDCB; 
 
			if (port > 0) 
			{ 
				if (intHandle == INVALID_HANDLE_VALUE) 
				{ 
					Close(intHandle); 
				} 
				else 
				{ 
					return INVALID_HANDLE_VALUE; 
				} 
 
				intHandle = CreateFile("COM" + port.ToString() + ":", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); 
 
				if (intHandle != INVALID_HANDLE_VALUE) 
				{ 
					//清除端口 rx 和tx 缓冲器 
					intResult = PurgeComm(intHandle, PURGE_RXCLEAR | PURGE_TXCLEAR); 
 
					//获得已存在端口的定义 
					intResult = GetCommState(intHandle, out lpDCB); 
					//设置必要的端口定义 
					lpDCB.fBinary = 1;               //二进制模式,没有文件结束的检校 
					lpDCB.fParity = 1;               // 启动奇偶检校 
					lpDCB.fOutxCtsFlow = 0;          // 没有 CTS 输出流控制  
					lpDCB.fOutxDsrFlow = 0;          // 没有 DSR 输出流控制 
					lpDCB.fDtrControl = 1;           // DTR 流控制类型 
					lpDCB.fDsrSensitivity = 0;       // DSR 感应 
					lpDCB.fTXContinueOnXoff = 1;  
					lpDCB.fOutX = 0;                 // 没有 XON/XOFF 输出流控制 
					lpDCB.fInX = 0;                  // 没有 XON/XOFF 输入流控制 
					lpDCB.fErrorChar = 0;            // 关闭错误替换  
					lpDCB.fNull = 0;                 // 关闭 null 拆卸 
					lpDCB.fRtsControl = 1;           //  RTS 流控制  
					lpDCB.fAbortOnError = 0;         // 不中止读写异常错误 
					lpDCB.StopBits = stopbits;       // 0, 1, 2 = 1, 1.5, 2 
					lpDCB.ByteSize = databits;      
					lpDCB.Parity = parity;           // 0-4 = no, odd, even, mark, space  
					lpDCB.BaudRate = baudrate;     
 
					 
					lpDCB.XonChar = '1'; 
 
					intResult = SetCommState(intHandle, ref lpDCB); 
 
					//设置端口缓冲区大小(单位为字节) 
					intResult = SetupComm(intHandle, rxbuffersize, txbuffersize); 
 
					//设置端口超时值(单位为毫秒) 
					lpCommTimeouts.ReadIntervalTimeout = 0; 
					lpCommTimeouts.ReadTotalTimeoutMultiplier = 0; 
					lpCommTimeouts.ReadTotalTimeoutconstant = timeout; 
					lpCommTimeouts.WriteTotalTimeoutMultiplier = 10; 
					lpCommTimeouts.WriteTotalTimeoutconstant = 100; 
 
					//intResult = SetCommTimeouts(intHandle, lpCommTimeouts); 
				} 
				else    
				{ 
					intHandle = INVALID_HANDLE_VALUE; 
				} 
			} 
			else     
			{ 
				intHandle = INVALID_HANDLE_VALUE; 
			} 
 
            return intHandle; 
		} 
		#endregion              
 
		#region "Close" 
		private int Close(int handle) 
		{ 
			int intResult; 
			if (handle != INVALID_HANDLE_VALUE) 
			{ 
				intResult = CloseHandle(handle); 
				if (intResult < 0) 
				{ 
					throw new Exception("不能关闭端口!"); 
				} 
			} 
 
			return INVALID_HANDLE_VALUE; 
		} 
		#endregion          
 
		#endregion 
 
	}																																																																																																																																																																																																																																																																																																																																																		 
}