⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 commbase.cs

📁 封装COM的操作的Windows API
💻 CS
📖 第 1 页 / 共 4 页
字号:
			if (AfterOpen()) 
			{
				auto = cs.autoReopen;
				return true;
			}
			else 
			{
				Close();
				return false;
			}
		}

		/// <summary>
		/// Closes the com port.
		/// </summary>
		public void Close()
		{
			if (online)
			{
				auto = false;
				BeforeClose(false);
				InternalClose();
				rxException = null;
			}
		}
		
		private void InternalClose() 
		{
			Win32Com.CancelIo(hPort);
			if (rxThread != null)
			{
				rxThread.Abort();
				rxThread = null;
			}
			Win32Com.CloseHandle(hPort);
			if (ptrUWO != IntPtr.Zero) Marshal.FreeHGlobal(ptrUWO);
			stateRTS = 2;
			stateDTR = 2;
			stateBRK = 2;
			online = false;
		}
		
		/// <summary>
		/// For IDisposable
		/// </summary>
		public void Dispose() {Close();}

		/// <summary>
		/// Destructor (just in case)
		/// </summary>
		~CommBase() {Close();}
		
		/// <summary>
		/// True if online.
		/// </summary>
		public bool Online {get {if (!online) return false; else return CheckOnline();}}

		/// <summary>
		/// Block until all bytes in the queue have been transmitted.
		/// </summary>
		public void Flush() {
			CheckOnline();
			CheckResult();
		}

		/// <summary>
		/// Use this to throw exceptions in derived classes. Correctly handles threading issues
		/// and closes the port if necessary.
		/// </summary>
		/// <param name="reason">Description of fault</param>
		protected void ThrowException(string reason)
		{
			if (Thread.CurrentThread == rxThread)
			{
				throw new CommPortException(reason);
			}
			else
			{
				if (online)
				{
					BeforeClose(true);
					InternalClose();
				}
				if (rxException == null)
				{
					throw new CommPortException(reason);
				}
				else
				{
					throw new CommPortException(rxException);
				}
			}
		}

		/// <summary>
		/// Queues bytes for transmission. 
		/// </summary>
		/// <param name="tosend">Array of bytes to be sent</param>
		protected void Send(byte[] tosend) {
			uint sent = 0;
			CheckOnline();
			CheckResult();
			writeCount = tosend.GetLength(0);
			if (Win32Com.WriteFile(hPort, tosend, (uint)writeCount, out sent, ptrUWO))
			{
				writeCount -= (int)sent;
			}
			else
			{
				if (Marshal.GetLastWin32Error() != Win32Com.ERROR_IO_PENDING) ThrowException("Unexpected failure");
			}
		}

		/// <summary>
		/// Queues a single byte for transmission.
		/// </summary>
		/// <param name="tosend">Byte to be sent</param>
		protected void Send(byte tosend) 
		{
			byte[] b = new byte[1];
			b[0] = tosend;
			Send(b);
		}

		private void CheckResult() 
		{
			uint sent = 0;
			if (writeCount > 0)
			{
				if (Win32Com.GetOverlappedResult(hPort, ptrUWO, out sent, checkSends))
				{
					writeCount -= (int)sent;
					if (writeCount != 0) ThrowException("Send Timeout");
				}
				else
				{
					if (Marshal.GetLastWin32Error() != Win32Com.ERROR_IO_PENDING) ThrowException("Unexpected failure");
				}
			}
		}

		/// <summary>
		/// Sends a protocol byte immediately ahead of any queued bytes.
		/// </summary>
		/// <param name="tosend">Byte to send</param>
		/// <returns>False if an immediate byte is already scheduled and not yet sent</returns>
		protected void SendImmediate(byte tosend) {
			CheckOnline();
			if (!Win32Com.TransmitCommChar(hPort, tosend)) ThrowException("Transmission failure");
		}
	
		/// <summary>
		/// Delay processing.
		/// </summary>
		/// <param name="milliseconds">Milliseconds to delay by</param>
		protected void Sleep(int milliseconds)
		{
			Thread.Sleep(milliseconds);
		}

		/// <summary>
		/// Represents the status of the modem control input signals.
		/// </summary>
		public struct ModemStatus 
		{
			private uint status;
			internal ModemStatus(uint val) {status = val;}
			/// <summary>
			/// Condition of the Clear To Send signal.
			/// </summary>
			public bool cts {get{return ((status & Win32Com.MS_CTS_ON) != 0);}}
			/// <summary>
			/// Condition of the Data Set Ready signal.
			/// </summary>
			public bool dsr {get{return ((status & Win32Com.MS_DSR_ON) != 0);}}
			/// <summary>
			/// Condition of the Receive Line Status Detection signal.
			/// </summary>
			public bool rlsd {get{return ((status & Win32Com.MS_RLSD_ON) != 0);}}
			/// <summary>
			/// Condition of the Ring Detection signal.
			/// </summary>
			public bool ring {get{return ((status & Win32Com.MS_RING_ON) != 0);}}
		}

		/// <summary>
		/// Gets the status of the modem control input signals.
		/// </summary>
		/// <returns>Modem status object</returns>
		protected ModemStatus GetModemStatus() {
			uint f;

			CheckOnline();
			if (!Win32Com.GetCommModemStatus(hPort, out f)) ThrowException("Unexpected failure");
			return new ModemStatus(f);
		}

		/// <summary>
		/// Represents the current condition of the port queues.
		/// </summary>
		public struct QueueStatus 
		{
			private uint status;
			private uint inQueue;
			private uint outQueue;
			private uint inQueueSize;
			private uint outQueueSize;

			internal QueueStatus(uint stat, uint inQ, uint outQ, uint inQs, uint outQs)
				{status = stat; inQueue = inQ; outQueue = outQ; inQueueSize = inQs; outQueueSize = outQs;}
			/// <summary>
			/// Output is blocked by CTS handshaking.
			/// </summary>
			public bool ctsHold {get{return ((status & Win32Com.COMSTAT.fCtsHold) != 0);}}
			/// <summary>
			/// Output is blocked by DRS handshaking.
			/// </summary>
			public bool dsrHold {get{return ((status & Win32Com.COMSTAT.fDsrHold) != 0);}}
			/// <summary>
			/// Output is blocked by RLSD handshaking.
			/// </summary>
			public bool rlsdHold {get{return ((status & Win32Com.COMSTAT.fRlsdHold) != 0);}}
			/// <summary>
			/// Output is blocked because software handshaking is enabled and XOFF was received.
			/// </summary>
			public bool xoffHold {get{return ((status & Win32Com.COMSTAT.fXoffHold) != 0);}}
			/// <summary>
			/// Output was blocked because XOFF was sent and this station is not yet ready to receive.
			/// </summary>
			public bool xoffSent {get{return ((status & Win32Com.COMSTAT.fXoffSent) != 0);}}
			
			/// <summary>
			/// There is a character waiting for transmission in the immediate buffer.
			/// </summary>
			public bool immediateWaiting {get{return ((status & Win32Com.COMSTAT.fTxim) != 0);}}

			/// <summary>
			/// Number of bytes waiting in the input queue.
			/// </summary>
			public long InQueue {get{return (long)inQueue;}}
			/// <summary>
			/// Number of bytes waiting for transmission.
			/// </summary>
			public long OutQueue {get{return (long)outQueue;}}
			/// <summary>
			/// Total size of input queue (0 means information unavailable)
			/// </summary>
			public long InQueueSize {get{return (long)inQueueSize;}}
			/// <summary>
			/// Total size of output queue (0 means information unavailable)
			/// </summary>
			public long OutQueueSize {get{return (long)outQueueSize;}}

			public override string ToString()
			{
				StringBuilder m = new StringBuilder("The reception queue is ", 60);
				if (inQueueSize == 0)
				{
					m.Append("of unknown size and ");
				}
				else
				{
					m.Append(inQueueSize.ToString() + " bytes long and ");
				}
				if (inQueue == 0)
				{
					m.Append("is empty.");
				}
				else if (inQueue == 1)
				{
					m.Append("contains 1 byte.");
				}
				else
				{
					m.Append("contains ");
					m.Append(inQueue.ToString());
					m.Append(" bytes.");
				}
				m.Append(" The transmission queue is ");
				if (outQueueSize == 0)
				{
					m.Append("of unknown size and ");
				}
				else
				{
					m.Append(outQueueSize.ToString() + " bytes long and ");
				}
				if (outQueue == 0)
				{
					m.Append("is empty");
				}
				else if (outQueue == 1)
				{
					m.Append("contains 1 byte. It is ");
				}
				else
				{
					m.Append("contains ");
					m.Append(outQueue.ToString());
					m.Append(" bytes. It is ");
				}
				if (outQueue > 0)
				{
					if (ctsHold || dsrHold || rlsdHold || xoffHold || xoffSent)
					{
						m.Append("holding on");
						if (ctsHold) m.Append(" CTS");
						if (dsrHold) m.Append(" DSR");
						if (rlsdHold) m.Append(" RLSD");
						if (xoffHold) m.Append(" Rx XOff");
						if (xoffSent) m.Append(" Tx XOff");
					}
					else
					{
						m.Append("pumping data");
					}
				}
				m.Append(". The immediate buffer is ");
				if (immediateWaiting)
					m.Append("full.");
				else
					m.Append("empty.");
				return m.ToString();
			}
		}

		/// <summary>
		/// Get the status of the queues
		/// </summary>
		/// <returns>Queue status object</returns>
		protected QueueStatus GetQueueStatus() 
		{
			Win32Com.COMSTAT cs;
			Win32Com.COMMPROP cp;
			uint er;

			CheckOnline();
			if (!Win32Com.ClearCommError(hPort, out er, out cs)) ThrowException("Unexpected failure");
			if (!Win32Com.GetCommProperties(hPort, out cp)) ThrowException("Unexpected failure");
			return new QueueStatus(cs.Flags, cs.cbInQue, cs.cbOutQue, cp.dwCurrentRxQueue, cp.dwCurrentTxQueue);
		}

		/// <summary>
		/// True if the RTS pin is controllable via the RTS property
		/// </summary>
		protected bool RTSavailable { get { return (stateRTS < 2);}}
		
		/// <summary>
		/// Set the state of the RTS modem control output
		/// </summary>
		protected bool RTS 
		{
			set {
				if (stateRTS > 1) return;
				CheckOnline();
				if (value)
				{
					if (Win32Com.EscapeCommFunction(hPort, Win32Com.SETRTS))
						stateRTS = 1;
					else
						ThrowException("Unexpected Failure");
				}
				else
				{
					if (Win32Com.EscapeCommFunction(hPort, Win32Com.CLRRTS))
						stateRTS = 1;
					else
						ThrowException("Unexpected Failure");
				}
			}
			get {
				return (stateRTS == 1);
			}
		}

		/// <summary>
		/// True if the DTR pin is controllable via the DTR property
		/// </summary>
		protected bool DTRavailable { get { return (stateDTR < 2);}}
		
		/// <summary>
		/// The state of the DTR modem control output
		/// </summary>
		protected bool DTR {
			set {
				if (stateDTR > 1) return;
				CheckOnline();
				if (value)
				{
					if (Win32Com.EscapeCommFunction(hPort, Win32Com.SETDTR))
						stateDTR = 1;
					else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -