異世界


2012年6月23日 星期六

SerialPort Class 擴充 (一)

以執行序處理讀取,該Class 未加入SerialPort 的參數部分

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.IO;
using System.Threading;
using System.Diagnostics;
 
namespace SBM75e_4
{
    /// <summary>
    /// 事件委派宣告
    /// </summary>
    public delegate void jgecomEventHandler(object sender, jgecomEventArgs e);
 
    /// <summary>
    /// 定義專用事件參數類別
    /// </summary>
    public class jgecomEventArgs : EventArgs
    {
        private string mComName;
        private Stream mMSG = new MemoryStream();
        //Byte[] mMSG = new Byte[1024];
 
        //public jgecomEventArgs(byte[] msg, string commName)
        public jgecomEventArgs(Stream msg, string commName)
        {
            MSG = msg;
            NAME = commName;
        }
        
        public string NAME
        {
            get { return mComName; }
            private set { mComName = value; }
        }
 
        //public byte[] MSG
        public Stream MSG
        {
            get { return mMSG; }
            private set { mMSG = value; }
        }
    }
 
    
    // Invok 跳板的委派宣告
    delegate void onInvok(Stream buffer);
 
    class JgeComport : SerialPort
    {
        #region 靜態公用函式
        /// <summary>
        /// 將 Byte陣列 轉為 Stream
        /// </summary>
        /// <returns>Stream</returns>
        public static Stream BytesToStream(byte[] bytes)
        {
            Stream stream = new MemoryStream(bytes);
            return stream;
        }
 
        public static Stream BytesToStream(byte[] bytes, int Length)
        {
            Stream stream = new MemoryStream(bytes, 0, Length);
            return stream;
        }
        /// <summary>
        /// 將 Stream 轉為 Byte陣列
        /// </summary>
        public static byte[] StreamToBytes(Stream stream)
        {
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
 
            /*將 stream 指針指向開頭*/
            stream.Seek(0, SeekOrigin.Begin);
            return bytes;
        }
        #endregion
 
        /// <summary>
        /// 委派宣告
        /// </summary>
        private delegate void SetReceived(Stream msg, string ip);
 
        /// <summary>
        /// 委派欄位
        /// </summary>
        private SetReceived mSetReceivedDlg;
 
        /// <summary>
        /// Received 事件
        /// </summary>
        public event jgecomEventHandler Received;
 
        /// <summary>
        /// 委派處理函式
        /// </summary>
        private void OnReceivedText(Stream msg, string commName)
        {
            jgecomEventArgs e = new jgecomEventArgs(msg, commName);
 
            if (Received != null) //. 當事件變數不為 null 則執行之
            {
                Received(this, e);
            }
        }
 
        /// <summary>
        /// 儲存擁有者
        /// </summary>
        private object mOwner;
 
        /// <summary>
        /// 建構式
        /// </summary>
        public JgeComport(object Owner)
        {
            mOwner = Owner;
            
            /*設定委派處理函式*/
            mSetReceivedDlg = OnReceivedText;
 
            //..啟動非同步接受資料
        }
 
        //========================================================================
 
        /// <summary>
        /// SerialPort 物件,設為public 以便直接取用其屬性(偷懶的作法)
        /// </summary>
        public SerialPort comport;
 
        /// <summary>
        /// 內部使用變數
        /// </summary>
        private Boolean receiving; // 能讓DoReceive方法內的While迴圈停止        
        private Thread t;       // Thread型別的變數t,則是為了產生執行緒所宣告
 
        /// <summary>
        /// 建構式
        /// </summary>
        public JgeComport(object Owner, string PortName)
        {
            mOwner = Owner;
 
            /*設定委派處理函式*/
            mSetReceivedDlg = OnReceivedText;
 
            //..啟動
            comport = new SerialPort(PortName, 9600, Parity.None, 8, StopBits.One);
            if (!comport.IsOpen)
            {
                comport.Open();
 
                // 產生執行緒來執行自訂的DoReceive方法
                receiving = true;
                t = new Thread(DoReceive);
                //t = new Thread(DoReceiveEx);
                t.IsBackground = true;
                t.Start();
            }
        }
 
 
        // OnReceive 事件跳板
        private void onInvoked(Stream buffer)
        {
            OnReceivedText(buffer, comport.PortName.ToString());
        }
 
        /// <summary>
        /// Rx 執行序
        /// </summary>
        private void DoReceive()
        {
            Byte[] buffer = new Byte[1024];
            
            while (receiving)
            {
                if (comport.BytesToRead > 0)
                {
                    Thread.Sleep(312); // Sleep 一段時間,用以讀取個多數據(該處可加入判斷式,進行更多的條件讀取)
 
                    Int32 length = comport.Read(buffer, 0, buffer.Length);
                    Array.Resize(ref buffer, length);
                    onInvok d = new onInvok(onInvoked);
                    /* Invoke */((System.Windows.Forms.Form)mOwner).Invoke(d, new Object[] { BytesToStream(buffer) });
                    Array.Resize(ref buffer, 1024);
                }
                Thread.Sleep(16);
            }
        }
 
    }
}

使用該 Class


JgeComport My232 = new JgeComport(this,"COM2");
My232.Received += this.onReceived;


事件程式



private void onReceived(object sender, jgecomEventArgs e)
        {
            switch (e.NAME.ToString())
            {
                case "COM2":
                case "Com2":
                case "com2":                    
                    Byte[] bytes = new Byte[1024];
                    bytes = JgeComport.StreamToBytes(e.MSG);
                    textBox1.Text += String.Format("{0}{1}", BitConverter.ToString(bytes), Environment.NewLine); //Environment.NewLine => \r\n
                    label2.Text = bytes.Length.ToString();
                    break;
                default:
                    break;
            }
        }

沒有留言:

張貼留言