#pragma once

#include ".\PCANBasicCLR.h"

namespace PCANBasicExample 
{
	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;
	using namespace System::Threading;
	using namespace Peak::Can::Basic;	

	/// <summary>
	/// Message Status structure used to show CAN Messages
	/// in a ListView
	///
	/// </summary>
	public value class MessageStatus 
	{
		private: 
			TPCANMsg m_Msg;
			TPCANTimestamp m_TimeStamp;
			TPCANTimestamp m_oldTimeStamp;
			int m_iIndex;
			int m_Count;
			bool m_bShowPeriod;
			bool m_bWasChanged;

			// Constructor
			//
		public: MessageStatus(TPCANMsg canMsg, TPCANTimestamp canTimestamp, int listIndex)
			{
				m_Msg = canMsg;
				m_TimeStamp = canTimestamp;
				m_oldTimeStamp = canTimestamp;
				m_iIndex = listIndex;
				m_Count = 1;
				m_bShowPeriod = true;
				m_bWasChanged = false;
			}

		public: void Update(TPCANMsg canMsg, TPCANTimestamp canTimestamp)
            {
                m_Msg = canMsg;
                m_oldTimeStamp = m_TimeStamp;
                m_TimeStamp = canTimestamp;
                m_bWasChanged = true;
                m_Count += 1;
            }

		private: String^ GetTimeString()
            {
                double fTime;

                fTime = m_TimeStamp.millis + (m_TimeStamp.micros / 1000.0);
                if (m_bShowPeriod)
                    fTime -= (m_oldTimeStamp.millis + (m_oldTimeStamp.micros / 1000.0));
                return fTime.ToString("F1");                
            }

		private: String^ GetDataString()
            {
                String^ strTemp;

                strTemp = "";

				if ((m_Msg.MSGTYPE & TPCANMessageType::PCAN_MESSAGE_RTR) == TPCANMessageType::PCAN_MESSAGE_RTR)
                    return "Remote Request";
                else
                    for (int i = 0; i < m_Msg.LEN; i++)
						strTemp += String::Format("{0:X2} ", m_Msg.DATA[i]);

                return strTemp;
            }

		private: String^ GetIdString()
            {
                // We format the ID of the message and show it
                //
				if ((m_Msg.MSGTYPE & TPCANMessageType::PCAN_MESSAGE_EXTENDED) == TPCANMessageType::PCAN_MESSAGE_EXTENDED)
					return String::Format("{0:X8}h", m_Msg.ID);
                else
					return String::Format("{0:X3}h", m_Msg.ID);
            }

		private: String^ GetMsgTypeString()
            {
                String^ strTemp;

				if ((m_Msg.MSGTYPE & TPCANMessageType::PCAN_MESSAGE_EXTENDED) == TPCANMessageType::PCAN_MESSAGE_EXTENDED)
                    strTemp = "EXTENDED";
                else
                    strTemp = "STANDARD";

				if ((m_Msg.MSGTYPE & TPCANMessageType::PCAN_MESSAGE_RTR) == TPCANMessageType::PCAN_MESSAGE_RTR)
                    strTemp += "/RTR";

                return strTemp;
            }

		public: property TPCANMsg CANMsg
            {
                TPCANMsg get() { return m_Msg; }
            }

		public: property TPCANTimestamp Timestamp
            {
                TPCANTimestamp get() { return m_TimeStamp; }
            }

		public: property int Position
            {
                int get() { return m_iIndex; }
            }

		public: property String^ TypeString
            {
                String^ get() { return GetMsgTypeString(); }
            }

		public: property String^ IdString
            {
                String^ get() { return GetIdString(); }
            }

		public: property String^ DataString
            {
                String^ get() { return GetDataString(); }
            }

		public: property int Count
            {
                int get() { return m_Count; }
            }

		public: property bool ShowingPeriod
            {
                bool get() { return m_bShowPeriod; }
                void set(bool value)
                {
                    if (m_bShowPeriod ^ value)
                    {
                        m_bShowPeriod = value;
                        m_bWasChanged = true;
                    }
                }
            }

		public: property bool MarkedAsUpdated
            {
                bool get() { return m_bWasChanged; }
                void set(bool value) { m_bWasChanged = value; }
            }

		public: property String^ TimeString
            {
                String^ get() { return GetTimeString(); }
            }
	};

	/// <summary>
	/// Summary for Form1
	///
	/// WARNING: If you change the name of this class, you will need to change the
	///          'Resource File Name' property for the managed resource compiler tool
	///          associated with all .resx files this class depends on.  Otherwise,
	///          the designers will not be able to interact properly with localized
	///          resources associated with this form.
	/// </summary>
	public ref class Form1 : public System::Windows::Forms::Form
	{
	public:
		Form1(void)
		{
			InitializeComponent();

			// Creates the list for received messages
			//
			m_LastMsgsList = gcnew System::Collections::ArrayList();
			// Creates the delegate used for message reading
			//
			m_ReadDelegate = gcnew ReadDelegateHandler(this, &Form1::ReadMessages);
			// Creates the event used for signalize incomming messages 
			//
			m_ReceiveEvent = gcnew System::Threading::AutoResetEvent(false);

			// Creates an array with all possible PCAN-Channels
			//
			m_HandlesArray = gcnew array<TPCANHandle^> { 
				PCANBasic::PCAN_ISABUS1,
				PCANBasic::PCAN_ISABUS2,
				PCANBasic::PCAN_ISABUS3,
				PCANBasic::PCAN_ISABUS4,
				PCANBasic::PCAN_ISABUS5,
				PCANBasic::PCAN_ISABUS6,
				PCANBasic::PCAN_ISABUS7,
				PCANBasic::PCAN_ISABUS8,
				PCANBasic::PCAN_DNGBUS1,
				PCANBasic::PCAN_PCIBUS1,
				PCANBasic::PCAN_PCIBUS2,
				PCANBasic::PCAN_PCIBUS3,
				PCANBasic::PCAN_PCIBUS4,
				PCANBasic::PCAN_PCIBUS5,
				PCANBasic::PCAN_PCIBUS6,
				PCANBasic::PCAN_PCIBUS7,
				PCANBasic::PCAN_PCIBUS8,
				PCANBasic::PCAN_USBBUS1,
				PCANBasic::PCAN_USBBUS2,
				PCANBasic::PCAN_USBBUS3,
				PCANBasic::PCAN_USBBUS4,
				PCANBasic::PCAN_USBBUS5,
				PCANBasic::PCAN_USBBUS6,
				PCANBasic::PCAN_USBBUS7,
				PCANBasic::PCAN_USBBUS8,
				PCANBasic::PCAN_PCCBUS1,
				PCANBasic::PCAN_PCCBUS2
			};

			// Prepares the PCAN-Basic's debug-Log file
			//
			FillComboBoxData();

			// Prepares the PCAN-Basic's debug-Log file
			//
			ConfigureLogFile();
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}
	
	private: System::Windows::Forms::CheckBox^  chbShowPeriod;
	private: System::Windows::Forms::RadioButton^  rdbManual;
	private: System::Windows::Forms::RadioButton^  rdbEvent;
	private: System::Windows::Forms::ListView^  lstMessages;
	private: System::Windows::Forms::ColumnHeader^  clhType;
	private: System::Windows::Forms::ColumnHeader^  clhID;
	private: System::Windows::Forms::ColumnHeader^  clhLength;
	private: System::Windows::Forms::ColumnHeader^  clhData;
	private: System::Windows::Forms::ColumnHeader^  clhCount;
	private: System::Windows::Forms::ColumnHeader^  clhRcvTime;
	private: System::Windows::Forms::NumericUpDown^  nudLength;
	private: System::Windows::Forms::Button^  btnMsgClear;
	private: System::Windows::Forms::ListBox^  lbxInfo;
	private: System::Windows::Forms::Button^  btnInfoClear;
	private: System::Windows::Forms::GroupBox^  groupBox5;
	private: System::Windows::Forms::RadioButton^  rdbTimer;
	private: System::Windows::Forms::Button^  btnRead;
	private: System::Windows::Forms::Button^  btnGetVersions;
	private: System::Windows::Forms::Label^  label11;
	private: System::Windows::Forms::Button^  btnWrite;
	private: System::Windows::Forms::Label^  label12;
	private: System::Windows::Forms::GroupBox^  groupBox6;
	private: System::Windows::Forms::CheckBox^  chbRemote;
	private: System::Windows::Forms::CheckBox^  chbExtended;
	private: System::Windows::Forms::Label^  label13;
	private: System::Windows::Forms::TextBox^  txtID;
	private: System::Windows::Forms::TextBox^  txtData7;
	private: System::Windows::Forms::TextBox^  txtData6;
	private: System::Windows::Forms::TextBox^  txtData5;
	private: System::Windows::Forms::TextBox^  txtData4;
	private: System::Windows::Forms::TextBox^  txtData3;
	private: System::Windows::Forms::TextBox^  txtData2;
	private: System::Windows::Forms::TextBox^  txtData1;
	private: System::Windows::Forms::TextBox^  txtData0;
	private: System::Windows::Forms::GroupBox^  groupBox4;
	private: System::Windows::Forms::ComboBox^  cbbChannel;
	private: System::Windows::Forms::RadioButton^  rdbParamInactive;
	private: System::Windows::Forms::Button^  btnHwRefresh;
	private: System::Windows::Forms::ComboBox^  cbbHwType;
	private: System::Windows::Forms::ComboBox^  cbbInterrupt;
	private: System::Windows::Forms::Button^  btnFilterQuery;
	private: System::Windows::Forms::Label^  label5;
	private: System::Windows::Forms::GroupBox^  groupBox3;
	private: System::Windows::Forms::CheckBox^  chbFilterExt;
	private: System::Windows::Forms::NumericUpDown^  nudIdTo;
	private: System::Windows::Forms::NumericUpDown^  nudIdFrom;
	private: System::Windows::Forms::Label^  label8;
	private: System::Windows::Forms::Label^  label7;
	private: System::Windows::Forms::RadioButton^  rdbFilterOpen;
	private: System::Windows::Forms::RadioButton^  rdbFilterCustom;
	private: System::Windows::Forms::RadioButton^  rdbFilterClose;
	private: System::Windows::Forms::Button^  btnFilterApply;
	private: System::Windows::Forms::ComboBox^  cbbIO;
	private: System::Windows::Forms::Timer^  tmrRead;
	private: System::Windows::Forms::Label^  label4;
	private: System::Windows::Forms::Label^  label3;
	private: System::Windows::Forms::ComboBox^  cbbBaudrates;
	private: System::Windows::Forms::Label^  label2;
	private: System::Windows::Forms::Label^  label1;
	private: System::Windows::Forms::Button^  btnInit;
	private: System::Windows::Forms::Button^  btnRelease;
	private: System::Windows::Forms::Button^  btnParameterGet;
	private: System::Windows::Forms::Label^  label10;
	private: System::Windows::Forms::NumericUpDown^  nudDeviceId;
	private: System::Windows::Forms::Label^  label9;
	private: System::Windows::Forms::ComboBox^  cbbParameter;
	private: System::Windows::Forms::GroupBox^  groupBox2;
	private: System::Windows::Forms::Label^  label6;
	private: System::Windows::Forms::RadioButton^  rdbParamActive;
	private: System::Windows::Forms::Button^  btnParameterSet;
	private: System::Windows::Forms::GroupBox^  groupBox1;
	private: System::Windows::Forms::Button^  btnReset;
	private: System::Windows::Forms::Button^  btnStatus;
private: System::Windows::Forms::Timer^  tmrDisplay;
	private: System::ComponentModel::IContainer^  components;

#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			this->components = (gcnew System::ComponentModel::Container());
			System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(Form1::typeid));
			this->chbShowPeriod = (gcnew System::Windows::Forms::CheckBox());
			this->rdbManual = (gcnew System::Windows::Forms::RadioButton());
			this->rdbEvent = (gcnew System::Windows::Forms::RadioButton());
			this->lstMessages = (gcnew System::Windows::Forms::ListView());
			this->clhType = (gcnew System::Windows::Forms::ColumnHeader());
			this->clhID = (gcnew System::Windows::Forms::ColumnHeader());
			this->clhLength = (gcnew System::Windows::Forms::ColumnHeader());
			this->clhData = (gcnew System::Windows::Forms::ColumnHeader());
			this->clhCount = (gcnew System::Windows::Forms::ColumnHeader());
			this->clhRcvTime = (gcnew System::Windows::Forms::ColumnHeader());
			this->nudLength = (gcnew System::Windows::Forms::NumericUpDown());
			this->btnMsgClear = (gcnew System::Windows::Forms::Button());
			this->lbxInfo = (gcnew System::Windows::Forms::ListBox());
			this->btnInfoClear = (gcnew System::Windows::Forms::Button());
			this->groupBox5 = (gcnew System::Windows::Forms::GroupBox());
			this->rdbTimer = (gcnew System::Windows::Forms::RadioButton());
			this->btnRead = (gcnew System::Windows::Forms::Button());
			this->btnGetVersions = (gcnew System::Windows::Forms::Button());
			this->label11 = (gcnew System::Windows::Forms::Label());
			this->btnWrite = (gcnew System::Windows::Forms::Button());
			this->label12 = (gcnew System::Windows::Forms::Label());
			this->groupBox6 = (gcnew System::Windows::Forms::GroupBox());
			this->chbRemote = (gcnew System::Windows::Forms::CheckBox());
			this->chbExtended = (gcnew System::Windows::Forms::CheckBox());
			this->label13 = (gcnew System::Windows::Forms::Label());
			this->txtID = (gcnew System::Windows::Forms::TextBox());
			this->txtData7 = (gcnew System::Windows::Forms::TextBox());
			this->txtData6 = (gcnew System::Windows::Forms::TextBox());
			this->txtData5 = (gcnew System::Windows::Forms::TextBox());
			this->txtData4 = (gcnew System::Windows::Forms::TextBox());
			this->txtData3 = (gcnew System::Windows::Forms::TextBox());
			this->txtData2 = (gcnew System::Windows::Forms::TextBox());
			this->txtData1 = (gcnew System::Windows::Forms::TextBox());
			this->txtData0 = (gcnew System::Windows::Forms::TextBox());
			this->groupBox4 = (gcnew System::Windows::Forms::GroupBox());
			this->btnReset = (gcnew System::Windows::Forms::Button());
			this->btnStatus = (gcnew System::Windows::Forms::Button());
			this->cbbChannel = (gcnew System::Windows::Forms::ComboBox());
			this->rdbParamInactive = (gcnew System::Windows::Forms::RadioButton());
			this->btnHwRefresh = (gcnew System::Windows::Forms::Button());
			this->cbbHwType = (gcnew System::Windows::Forms::ComboBox());
			this->cbbInterrupt = (gcnew System::Windows::Forms::ComboBox());
			this->btnFilterQuery = (gcnew System::Windows::Forms::Button());
			this->label5 = (gcnew System::Windows::Forms::Label());
			this->groupBox3 = (gcnew System::Windows::Forms::GroupBox());
			this->chbFilterExt = (gcnew System::Windows::Forms::CheckBox());
			this->nudIdTo = (gcnew System::Windows::Forms::NumericUpDown());
			this->nudIdFrom = (gcnew System::Windows::Forms::NumericUpDown());
			this->label8 = (gcnew System::Windows::Forms::Label());
			this->label7 = (gcnew System::Windows::Forms::Label());
			this->rdbFilterOpen = (gcnew System::Windows::Forms::RadioButton());
			this->rdbFilterCustom = (gcnew System::Windows::Forms::RadioButton());
			this->rdbFilterClose = (gcnew System::Windows::Forms::RadioButton());
			this->btnFilterApply = (gcnew System::Windows::Forms::Button());
			this->cbbIO = (gcnew System::Windows::Forms::ComboBox());
			this->tmrRead = (gcnew System::Windows::Forms::Timer(this->components));
			this->label4 = (gcnew System::Windows::Forms::Label());
			this->label3 = (gcnew System::Windows::Forms::Label());
			this->cbbBaudrates = (gcnew System::Windows::Forms::ComboBox());
			this->label2 = (gcnew System::Windows::Forms::Label());
			this->label1 = (gcnew System::Windows::Forms::Label());
			this->btnInit = (gcnew System::Windows::Forms::Button());
			this->btnRelease = (gcnew System::Windows::Forms::Button());
			this->btnParameterGet = (gcnew System::Windows::Forms::Button());
			this->label10 = (gcnew System::Windows::Forms::Label());
			this->nudDeviceId = (gcnew System::Windows::Forms::NumericUpDown());
			this->label9 = (gcnew System::Windows::Forms::Label());
			this->cbbParameter = (gcnew System::Windows::Forms::ComboBox());
			this->groupBox2 = (gcnew System::Windows::Forms::GroupBox());
			this->label6 = (gcnew System::Windows::Forms::Label());
			this->rdbParamActive = (gcnew System::Windows::Forms::RadioButton());
			this->btnParameterSet = (gcnew System::Windows::Forms::Button());
			this->groupBox1 = (gcnew System::Windows::Forms::GroupBox());
			this->tmrDisplay = (gcnew System::Windows::Forms::Timer(this->components));
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->nudLength))->BeginInit();
			this->groupBox5->SuspendLayout();
			this->groupBox6->SuspendLayout();
			this->groupBox4->SuspendLayout();
			this->groupBox3->SuspendLayout();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->nudIdTo))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->nudIdFrom))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->nudDeviceId))->BeginInit();
			this->groupBox2->SuspendLayout();
			this->groupBox1->SuspendLayout();
			this->SuspendLayout();
			// 
			// chbShowPeriod
			// 
			this->chbShowPeriod->AutoSize = true;
			this->chbShowPeriod->Checked = true;
			this->chbShowPeriod->CheckState = System::Windows::Forms::CheckState::Checked;
			this->chbShowPeriod->Location = System::Drawing::Point(374, 15);
			this->chbShowPeriod->Name = L"chbShowPeriod";
			this->chbShowPeriod->Size = System::Drawing::Size(123, 17);
			this->chbShowPeriod->TabIndex = 3;
			this->chbShowPeriod->Text = L"Timestamp as period";
			this->chbShowPeriod->UseVisualStyleBackColor = true;
			this->chbShowPeriod->CheckedChanged += gcnew System::EventHandler(this, &Form1::chbShowPeriod_CheckedChanged);
			// 
			// rdbManual
			// 
			this->rdbManual->AutoSize = true;
			this->rdbManual->Location = System::Drawing::Point(276, 14);
			this->rdbManual->Name = L"rdbManual";
			this->rdbManual->Size = System::Drawing::Size(89, 17);
			this->rdbManual->TabIndex = 2;
			this->rdbManual->Text = L"Manual Read";
			this->rdbManual->UseVisualStyleBackColor = true;
			this->rdbManual->CheckedChanged += gcnew System::EventHandler(this, &Form1::rdbTimer_CheckedChanged);
			// 
			// rdbEvent
			// 
			this->rdbEvent->AutoSize = true;
			this->rdbEvent->Location = System::Drawing::Point(131, 14);
			this->rdbEvent->Name = L"rdbEvent";
			this->rdbEvent->Size = System::Drawing::Size(139, 17);
			this->rdbEvent->TabIndex = 1;
			this->rdbEvent->Text = L"Reading using an Event";
			this->rdbEvent->UseVisualStyleBackColor = true;
			this->rdbEvent->CheckedChanged += gcnew System::EventHandler(this, &Form1::rdbTimer_CheckedChanged);
			// 
			// lstMessages
			// 
			this->lstMessages->Columns->AddRange(gcnew cli::array< System::Windows::Forms::ColumnHeader^  >(6) {this->clhType, this->clhID, 
				this->clhLength, this->clhData, this->clhCount, this->clhRcvTime});
			this->lstMessages->FullRowSelect = true;
			this->lstMessages->Location = System::Drawing::Point(8, 37);
			this->lstMessages->MultiSelect = false;
			this->lstMessages->Name = L"lstMessages";
			this->lstMessages->Size = System::Drawing::Size(560, 96);
			this->lstMessages->TabIndex = 4;
			this->lstMessages->UseCompatibleStateImageBehavior = false;
			this->lstMessages->View = System::Windows::Forms::View::Details;
			// 
			// clhType
			// 
			this->clhType->Text = L"Type";
			this->clhType->Width = 69;
			// 
			// clhID
			// 
			this->clhID->Text = L"ID";
			this->clhID->Width = 90;
			// 
			// clhLength
			// 
			this->clhLength->Text = L"Length";
			this->clhLength->Width = 50;
			// 
			// clhData
			// 
			this->clhData->Text = L"Data";
			this->clhData->Width = 160;
			// 
			// clhCount
			// 
			this->clhCount->Text = L"Count";
			this->clhCount->Width = 49;
			// 
			// clhRcvTime
			// 
			this->clhRcvTime->Text = L"Rcv Time";
			this->clhRcvTime->Width = 97;
			// 
			// nudLength
			// 
			this->nudLength->BackColor = System::Drawing::Color::White;
			this->nudLength->Location = System::Drawing::Point(177, 34);
			this->nudLength->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) {8, 0, 0, 0});
			this->nudLength->Name = L"nudLength";
			this->nudLength->ReadOnly = true;
			this->nudLength->Size = System::Drawing::Size(50, 20);
			this->nudLength->TabIndex = 2;
			this->nudLength->Value = System::Decimal(gcnew cli::array< System::Int32 >(4) {8, 0, 0, 0});
			this->nudLength->ValueChanged += gcnew System::EventHandler(this, &Form1::nudLength_ValueChanged);
			// 
			// btnMsgClear
			// 
			this->btnMsgClear->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->btnMsgClear->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->btnMsgClear->Location = System::Drawing::Point(649, 37);
			this->btnMsgClear->Name = L"btnMsgClear";
			this->btnMsgClear->Size = System::Drawing::Size(65, 23);
			this->btnMsgClear->TabIndex = 6;
			this->btnMsgClear->Text = L"Clear";
			this->btnMsgClear->UseVisualStyleBackColor = true;
			this->btnMsgClear->Click += gcnew System::EventHandler(this, &Form1::btnMsgClear_Click);
			// 
			// lbxInfo
			// 
			this->lbxInfo->FormattingEnabled = true;
			this->lbxInfo->Items->AddRange(gcnew cli::array< System::Object^  >(2) {L"Select a Hardware and a configuration for it. Then click \"Initialize\" button", 
				L"When activated, the Debug-Log file will be found in the same directory as this ap" 
				L"plication"});
			this->lbxInfo->Location = System::Drawing::Point(10, 19);
			this->lbxInfo->Name = L"lbxInfo";
			this->lbxInfo->ScrollAlwaysVisible = true;
			this->lbxInfo->Size = System::Drawing::Size(558, 108);
			this->lbxInfo->TabIndex = 0;
			// 
			// btnInfoClear
			// 
			this->btnInfoClear->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->btnInfoClear->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->btnInfoClear->Location = System::Drawing::Point(649, 19);
			this->btnInfoClear->Name = L"btnInfoClear";
			this->btnInfoClear->Size = System::Drawing::Size(65, 23);
			this->btnInfoClear->TabIndex = 2;
			this->btnInfoClear->Text = L"Clear";
			this->btnInfoClear->UseVisualStyleBackColor = true;
			this->btnInfoClear->Click += gcnew System::EventHandler(this, &Form1::btnInfoClear_Click);
			// 
			// groupBox5
			// 
			this->groupBox5->Anchor = static_cast<System::Windows::Forms::AnchorStyles>(((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Left) 
				| System::Windows::Forms::AnchorStyles::Right));
			this->groupBox5->Controls->Add(this->chbShowPeriod);
			this->groupBox5->Controls->Add(this->rdbManual);
			this->groupBox5->Controls->Add(this->rdbEvent);
			this->groupBox5->Controls->Add(this->lstMessages);
			this->groupBox5->Controls->Add(this->btnMsgClear);
			this->groupBox5->Controls->Add(this->rdbTimer);
			this->groupBox5->Controls->Add(this->btnRead);
			this->groupBox5->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->groupBox5->Location = System::Drawing::Point(12, 211);
			this->groupBox5->Name = L"groupBox5";
			this->groupBox5->Size = System::Drawing::Size(720, 140);
			this->groupBox5->TabIndex = 3;
			this->groupBox5->TabStop = false;
			this->groupBox5->Text = L" Messages Reading ";
			// 
			// rdbTimer
			// 
			this->rdbTimer->AutoSize = true;
			this->rdbTimer->Checked = true;
			this->rdbTimer->Location = System::Drawing::Point(8, 14);
			this->rdbTimer->Name = L"rdbTimer";
			this->rdbTimer->Size = System::Drawing::Size(117, 17);
			this->rdbTimer->TabIndex = 0;
			this->rdbTimer->TabStop = true;
			this->rdbTimer->Text = L"Read using a Timer";
			this->rdbTimer->UseVisualStyleBackColor = true;
			this->rdbTimer->CheckedChanged += gcnew System::EventHandler(this, &Form1::rdbTimer_CheckedChanged);
			// 
			// btnRead
			// 
			this->btnRead->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->btnRead->Enabled = false;
			this->btnRead->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->btnRead->Location = System::Drawing::Point(578, 37);
			this->btnRead->Name = L"btnRead";
			this->btnRead->Size = System::Drawing::Size(65, 23);
			this->btnRead->TabIndex = 5;
			this->btnRead->Text = L"Read";
			this->btnRead->UseVisualStyleBackColor = true;
			this->btnRead->Click += gcnew System::EventHandler(this, &Form1::btnRead_Click);
			// 
			// btnGetVersions
			// 
			this->btnGetVersions->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->btnGetVersions->Enabled = false;
			this->btnGetVersions->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->btnGetVersions->Location = System::Drawing::Point(578, 19);
			this->btnGetVersions->Name = L"btnGetVersions";
			this->btnGetVersions->Size = System::Drawing::Size(65, 23);
			this->btnGetVersions->TabIndex = 1;
			this->btnGetVersions->Text = L"Versions";
			this->btnGetVersions->UseVisualStyleBackColor = true;
			this->btnGetVersions->Click += gcnew System::EventHandler(this, &Form1::btnGetVersions_Click);
			// 
			// label11
			// 
			this->label11->AutoSize = true;
			this->label11->Location = System::Drawing::Point(267, 17);
			this->label11->Name = L"label11";
			this->label11->Size = System::Drawing::Size(60, 13);
			this->label11->TabIndex = 32;
			this->label11->Text = L"Data (0..7):";
			// 
			// btnWrite
			// 
			this->btnWrite->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->btnWrite->Cursor = System::Windows::Forms::Cursors::Default;
			this->btnWrite->Enabled = false;
			this->btnWrite->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->btnWrite->Location = System::Drawing::Point(649, 32);
			this->btnWrite->Name = L"btnWrite";
			this->btnWrite->Size = System::Drawing::Size(65, 23);
			this->btnWrite->TabIndex = 12;
			this->btnWrite->Text = L"Write";
			this->btnWrite->Click += gcnew System::EventHandler(this, &Form1::btnWrite_Click);
			// 
			// label12
			// 
			this->label12->AutoSize = true;
			this->label12->Location = System::Drawing::Point(174, 17);
			this->label12->Name = L"label12";
			this->label12->Size = System::Drawing::Size(43, 13);
			this->label12->TabIndex = 31;
			this->label12->Text = L"Length:";
			// 
			// groupBox6
			// 
			this->groupBox6->Anchor = static_cast<System::Windows::Forms::AnchorStyles>(((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Left) 
				| System::Windows::Forms::AnchorStyles::Right));
			this->groupBox6->Controls->Add(this->chbRemote);
			this->groupBox6->Controls->Add(this->chbExtended);
			this->groupBox6->Controls->Add(this->label11);
			this->groupBox6->Controls->Add(this->btnWrite);
			this->groupBox6->Controls->Add(this->label12);
			this->groupBox6->Controls->Add(this->label13);
			this->groupBox6->Controls->Add(this->txtID);
			this->groupBox6->Controls->Add(this->txtData7);
			this->groupBox6->Controls->Add(this->txtData6);
			this->groupBox6->Controls->Add(this->txtData5);
			this->groupBox6->Controls->Add(this->txtData4);
			this->groupBox6->Controls->Add(this->txtData3);
			this->groupBox6->Controls->Add(this->txtData2);
			this->groupBox6->Controls->Add(this->txtData1);
			this->groupBox6->Controls->Add(this->txtData0);
			this->groupBox6->Controls->Add(this->nudLength);
			this->groupBox6->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->groupBox6->Location = System::Drawing::Point(12, 357);
			this->groupBox6->Name = L"groupBox6";
			this->groupBox6->Size = System::Drawing::Size(720, 66);
			this->groupBox6->TabIndex = 4;
			this->groupBox6->TabStop = false;
			this->groupBox6->Text = L"Write Messages";
			// 
			// chbRemote
			// 
			this->chbRemote->Cursor = System::Windows::Forms::Cursors::Default;
			this->chbRemote->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->chbRemote->Location = System::Drawing::Point(270, 32);
			this->chbRemote->Name = L"chbRemote";
			this->chbRemote->Size = System::Drawing::Size(44, 24);
			this->chbRemote->TabIndex = 3;
			this->chbRemote->Text = L"RTR";
			this->chbRemote->CheckedChanged += gcnew System::EventHandler(this, &Form1::chbRemote_CheckedChanged);
			// 
			// chbExtended
			// 
			this->chbExtended->Cursor = System::Windows::Forms::Cursors::Default;
			this->chbExtended->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->chbExtended->Location = System::Drawing::Point(94, 32);
			this->chbExtended->Name = L"chbExtended";
			this->chbExtended->Size = System::Drawing::Size(62, 24);
			this->chbExtended->TabIndex = 1;
			this->chbExtended->Text = L"Extended";
			this->chbExtended->CheckedChanged += gcnew System::EventHandler(this, &Form1::chbExtended_CheckedChanged);
			// 
			// label13
			// 
			this->label13->AutoSize = true;
			this->label13->Location = System::Drawing::Point(7, 17);
			this->label13->Name = L"label13";
			this->label13->Size = System::Drawing::Size(49, 13);
			this->label13->TabIndex = 30;
			this->label13->Text = L"ID (Hex):";
			// 
			// txtID
			// 
			this->txtID->CharacterCasing = System::Windows::Forms::CharacterCasing::Upper;
			this->txtID->Location = System::Drawing::Point(8, 34);
			this->txtID->MaxLength = 3;
			this->txtID->Name = L"txtID";
			this->txtID->Size = System::Drawing::Size(80, 20);
			this->txtID->TabIndex = 0;
			this->txtID->Text = L"0";
			this->txtID->Leave += gcnew System::EventHandler(this, &Form1::txtID_Leave);
			this->txtID->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::txtID_KeyPress);
			// 
			// txtData7
			// 
			this->txtData7->CharacterCasing = System::Windows::Forms::CharacterCasing::Upper;
			this->txtData7->Location = System::Drawing::Point(544, 34);
			this->txtData7->MaxLength = 2;
			this->txtData7->Name = L"txtData7";
			this->txtData7->Size = System::Drawing::Size(24, 20);
			this->txtData7->TabIndex = 11;
			this->txtData7->Text = L"00";
			this->txtData7->TextAlign = System::Windows::Forms::HorizontalAlignment::Center;
			this->txtData7->Leave += gcnew System::EventHandler(this, &Form1::txtData0_Leave);
			this->txtData7->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::txtID_KeyPress);
			// 
			// txtData6
			// 
			this->txtData6->CharacterCasing = System::Windows::Forms::CharacterCasing::Upper;
			this->txtData6->Location = System::Drawing::Point(512, 34);
			this->txtData6->MaxLength = 2;
			this->txtData6->Name = L"txtData6";
			this->txtData6->Size = System::Drawing::Size(24, 20);
			this->txtData6->TabIndex = 10;
			this->txtData6->Text = L"00";
			this->txtData6->TextAlign = System::Windows::Forms::HorizontalAlignment::Center;
			this->txtData6->Leave += gcnew System::EventHandler(this, &Form1::txtData0_Leave);
			this->txtData6->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::txtID_KeyPress);
			// 
			// txtData5
			// 
			this->txtData5->CharacterCasing = System::Windows::Forms::CharacterCasing::Upper;
			this->txtData5->Location = System::Drawing::Point(480, 34);
			this->txtData5->MaxLength = 2;
			this->txtData5->Name = L"txtData5";
			this->txtData5->Size = System::Drawing::Size(24, 20);
			this->txtData5->TabIndex = 9;
			this->txtData5->Text = L"00";
			this->txtData5->TextAlign = System::Windows::Forms::HorizontalAlignment::Center;
			this->txtData5->Leave += gcnew System::EventHandler(this, &Form1::txtData0_Leave);
			this->txtData5->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::txtID_KeyPress);
			// 
			// txtData4
			// 
			this->txtData4->CharacterCasing = System::Windows::Forms::CharacterCasing::Upper;
			this->txtData4->Location = System::Drawing::Point(448, 34);
			this->txtData4->MaxLength = 2;
			this->txtData4->Name = L"txtData4";
			this->txtData4->Size = System::Drawing::Size(24, 20);
			this->txtData4->TabIndex = 8;
			this->txtData4->Text = L"00";
			this->txtData4->TextAlign = System::Windows::Forms::HorizontalAlignment::Center;
			this->txtData4->Leave += gcnew System::EventHandler(this, &Form1::txtData0_Leave);
			this->txtData4->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::txtID_KeyPress);
			// 
			// txtData3
			// 
			this->txtData3->CharacterCasing = System::Windows::Forms::CharacterCasing::Upper;
			this->txtData3->Location = System::Drawing::Point(416, 34);
			this->txtData3->MaxLength = 2;
			this->txtData3->Name = L"txtData3";
			this->txtData3->Size = System::Drawing::Size(24, 20);
			this->txtData3->TabIndex = 7;
			this->txtData3->Text = L"00";
			this->txtData3->TextAlign = System::Windows::Forms::HorizontalAlignment::Center;
			this->txtData3->Leave += gcnew System::EventHandler(this, &Form1::txtData0_Leave);
			this->txtData3->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::txtID_KeyPress);
			// 
			// txtData2
			// 
			this->txtData2->CharacterCasing = System::Windows::Forms::CharacterCasing::Upper;
			this->txtData2->Location = System::Drawing::Point(384, 34);
			this->txtData2->MaxLength = 2;
			this->txtData2->Name = L"txtData2";
			this->txtData2->Size = System::Drawing::Size(24, 20);
			this->txtData2->TabIndex = 6;
			this->txtData2->Text = L"00";
			this->txtData2->TextAlign = System::Windows::Forms::HorizontalAlignment::Center;
			this->txtData2->Leave += gcnew System::EventHandler(this, &Form1::txtData0_Leave);
			this->txtData2->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::txtID_KeyPress);
			// 
			// txtData1
			// 
			this->txtData1->CharacterCasing = System::Windows::Forms::CharacterCasing::Upper;
			this->txtData1->Location = System::Drawing::Point(352, 34);
			this->txtData1->MaxLength = 2;
			this->txtData1->Name = L"txtData1";
			this->txtData1->Size = System::Drawing::Size(24, 20);
			this->txtData1->TabIndex = 5;
			this->txtData1->Text = L"00";
			this->txtData1->TextAlign = System::Windows::Forms::HorizontalAlignment::Center;
			this->txtData1->Leave += gcnew System::EventHandler(this, &Form1::txtData0_Leave);
			this->txtData1->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::txtID_KeyPress);
			// 
			// txtData0
			// 
			this->txtData0->CharacterCasing = System::Windows::Forms::CharacterCasing::Upper;
			this->txtData0->Location = System::Drawing::Point(320, 34);
			this->txtData0->MaxLength = 2;
			this->txtData0->Name = L"txtData0";
			this->txtData0->Size = System::Drawing::Size(24, 20);
			this->txtData0->TabIndex = 4;
			this->txtData0->Text = L"00";
			this->txtData0->TextAlign = System::Windows::Forms::HorizontalAlignment::Center;
			this->txtData0->Leave += gcnew System::EventHandler(this, &Form1::txtData0_Leave);
			this->txtData0->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::txtID_KeyPress);
			// 
			// groupBox4
			// 
			this->groupBox4->Anchor = static_cast<System::Windows::Forms::AnchorStyles>(((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Left) 
				| System::Windows::Forms::AnchorStyles::Right));
			this->groupBox4->Controls->Add(this->btnReset);
			this->groupBox4->Controls->Add(this->btnStatus);
			this->groupBox4->Controls->Add(this->btnGetVersions);
			this->groupBox4->Controls->Add(this->lbxInfo);
			this->groupBox4->Controls->Add(this->btnInfoClear);
			this->groupBox4->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->groupBox4->Location = System::Drawing::Point(12, 429);
			this->groupBox4->Name = L"groupBox4";
			this->groupBox4->Size = System::Drawing::Size(720, 135);
			this->groupBox4->TabIndex = 5;
			this->groupBox4->TabStop = false;
			this->groupBox4->Text = L"Information";
			// 
			// btnReset
			// 
			this->btnReset->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->btnReset->Enabled = false;
			this->btnReset->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->btnReset->Location = System::Drawing::Point(649, 48);
			this->btnReset->Name = L"btnReset";
			this->btnReset->Size = System::Drawing::Size(65, 23);
			this->btnReset->TabIndex = 4;
			this->btnReset->Text = L"Reset";
			this->btnReset->UseVisualStyleBackColor = true;
			this->btnReset->Click += gcnew System::EventHandler(this, &Form1::buttonReset_Click);
			// 
			// btnStatus
			// 
			this->btnStatus->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->btnStatus->Enabled = false;
			this->btnStatus->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->btnStatus->Location = System::Drawing::Point(578, 48);
			this->btnStatus->Name = L"btnStatus";
			this->btnStatus->Size = System::Drawing::Size(65, 23);
			this->btnStatus->TabIndex = 3;
			this->btnStatus->Text = L"Status";
			this->btnStatus->UseVisualStyleBackColor = true;
			this->btnStatus->Click += gcnew System::EventHandler(this, &Form1::buttonStatus_Click);
			// 
			// cbbChannel
			// 
			this->cbbChannel->DropDownStyle = System::Windows::Forms::ComboBoxStyle::DropDownList;
			this->cbbChannel->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 8.25F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->cbbChannel->Items->AddRange(gcnew cli::array< System::Object^  >(28) {L"None", L"DNG-Channel 1", L"ISA-Channel 1", L"ISA-Channel 2", 
				L"ISA-Channel 3", L"ISA-Channel 4", L"ISA-Channel 5", L"ISA-Channel 6", L"ISA-Channel 7", L"ISA-Channel 8", L"PCC-Channel 1", 
				L"PCC-Channel 2", L"PCI-Channel 1", L"PCI-Channel 2", L"PCI-Channel 3", L"PCI-Channel 4", L"PCI-Channel 5", L"PCI-Channel 6", 
				L"PCI-Channel 7", L"PCI-Channel 8", L"USB-Channel 1", L"USB-Channel 2", L"USB-Channel 3", L"USB-Channel 4", L"USB-Channel 5", 
				L"USB-Channel 6", L"USB-Channel 7", L"USB-Channel 8"});
			this->cbbChannel->Location = System::Drawing::Point(8, 31);
			this->cbbChannel->Name = L"cbbChannel";
			this->cbbChannel->Size = System::Drawing::Size(119, 21);
			this->cbbChannel->TabIndex = 0;
			this->cbbChannel->SelectedIndexChanged += gcnew System::EventHandler(this, &Form1::cbbChannel_SelectedIndexChanged);
			// 
			// rdbParamInactive
			// 
			this->rdbParamInactive->Location = System::Drawing::Point(300, 32);
			this->rdbParamInactive->Name = L"rdbParamInactive";
			this->rdbParamInactive->Size = System::Drawing::Size(67, 17);
			this->rdbParamInactive->TabIndex = 2;
			this->rdbParamInactive->Text = L"Inactive";
			this->rdbParamInactive->UseVisualStyleBackColor = true;
			// 
			// btnHwRefresh
			// 
			this->btnHwRefresh->Cursor = System::Windows::Forms::Cursors::Default;
			this->btnHwRefresh->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->btnHwRefresh->Location = System::Drawing::Point(133, 30);
			this->btnHwRefresh->Name = L"btnHwRefresh";
			this->btnHwRefresh->Size = System::Drawing::Size(65, 23);
			this->btnHwRefresh->TabIndex = 1;
			this->btnHwRefresh->Text = L"Refresh";
			this->btnHwRefresh->Click += gcnew System::EventHandler(this, &Form1::btnHwRefresh_Click);
			// 
			// cbbHwType
			// 
			this->cbbHwType->DropDownStyle = System::Windows::Forms::ComboBoxStyle::DropDownList;
			this->cbbHwType->Items->AddRange(gcnew cli::array< System::Object^  >(7) {L"ISA-82C200", L"ISA-SJA1000", L"ISA-PHYTEC", L"DNG-82C200", 
				L"DNG-82C200 EPP", L"DNG-SJA1000", L"DNG-SJA1000 EPP"});
			this->cbbHwType->Location = System::Drawing::Point(326, 31);
			this->cbbHwType->Name = L"cbbHwType";
			this->cbbHwType->Size = System::Drawing::Size(120, 21);
			this->cbbHwType->TabIndex = 3;
			this->cbbHwType->SelectedIndexChanged += gcnew System::EventHandler(this, &Form1::cbbHwType_SelectedIndexChanged);
			// 
			// cbbInterrupt
			// 
			this->cbbInterrupt->DropDownStyle = System::Windows::Forms::ComboBoxStyle::DropDownList;
			this->cbbInterrupt->Items->AddRange(gcnew cli::array< System::Object^  >(9) {L"3", L"4", L"5", L"7", L"9", L"10", L"11", 
				L"12", L"15"});
			this->cbbInterrupt->Location = System::Drawing::Point(513, 31);
			this->cbbInterrupt->Name = L"cbbInterrupt";
			this->cbbInterrupt->Size = System::Drawing::Size(55, 21);
			this->cbbInterrupt->TabIndex = 5;
			// 
			// btnFilterQuery
			// 
			this->btnFilterQuery->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->btnFilterQuery->Enabled = false;
			this->btnFilterQuery->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->btnFilterQuery->Location = System::Drawing::Point(649, 26);
			this->btnFilterQuery->Name = L"btnFilterQuery";
			this->btnFilterQuery->Size = System::Drawing::Size(65, 23);
			this->btnFilterQuery->TabIndex = 7;
			this->btnFilterQuery->Text = L"Query";
			this->btnFilterQuery->UseVisualStyleBackColor = true;
			this->btnFilterQuery->Click += gcnew System::EventHandler(this, &Form1::btnFilterQuery_Click);
			// 
			// label5
			// 
			this->label5->Location = System::Drawing::Point(515, 15);
			this->label5->Name = L"label5";
			this->label5->Size = System::Drawing::Size(53, 23);
			this->label5->TabIndex = 44;
			this->label5->Text = L"Interrupt:";
			// 
			// groupBox3
			// 
			this->groupBox3->Anchor = static_cast<System::Windows::Forms::AnchorStyles>(((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Left) 
				| System::Windows::Forms::AnchorStyles::Right));
			this->groupBox3->Controls->Add(this->btnFilterQuery);
			this->groupBox3->Controls->Add(this->chbFilterExt);
			this->groupBox3->Controls->Add(this->nudIdTo);
			this->groupBox3->Controls->Add(this->nudIdFrom);
			this->groupBox3->Controls->Add(this->label8);
			this->groupBox3->Controls->Add(this->label7);
			this->groupBox3->Controls->Add(this->rdbFilterOpen);
			this->groupBox3->Controls->Add(this->rdbFilterCustom);
			this->groupBox3->Controls->Add(this->rdbFilterClose);
			this->groupBox3->Controls->Add(this->btnFilterApply);
			this->groupBox3->Location = System::Drawing::Point(12, 83);
			this->groupBox3->Name = L"groupBox3";
			this->groupBox3->Size = System::Drawing::Size(720, 58);
			this->groupBox3->TabIndex = 1;
			this->groupBox3->TabStop = false;
			this->groupBox3->Text = L" Message Filtering ";
			// 
			// chbFilterExt
			// 
			this->chbFilterExt->AutoSize = true;
			this->chbFilterExt->Location = System::Drawing::Point(10, 33);
			this->chbFilterExt->Name = L"chbFilterExt";
			this->chbFilterExt->Size = System::Drawing::Size(103, 17);
			this->chbFilterExt->TabIndex = 0;
			this->chbFilterExt->Text = L"Extended Frame";
			this->chbFilterExt->UseVisualStyleBackColor = true;
			this->chbFilterExt->CheckedChanged += gcnew System::EventHandler(this, &Form1::chbFilterExt_CheckedChanged);
			// 
			// nudIdTo
			// 
			this->nudIdTo->Hexadecimal = true;
			this->nudIdTo->Location = System::Drawing::Point(438, 29);
			this->nudIdTo->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) {2047, 0, 0, 0});
			this->nudIdTo->Name = L"nudIdTo";
			this->nudIdTo->Size = System::Drawing::Size(69, 20);
			this->nudIdTo->TabIndex = 5;
			this->nudIdTo->Value = System::Decimal(gcnew cli::array< System::Int32 >(4) {2047, 0, 0, 0});
			// 
			// nudIdFrom
			// 
			this->nudIdFrom->Hexadecimal = true;
			this->nudIdFrom->Location = System::Drawing::Point(363, 29);
			this->nudIdFrom->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) {536870911, 0, 0, 0});
			this->nudIdFrom->Name = L"nudIdFrom";
			this->nudIdFrom->Size = System::Drawing::Size(69, 20);
			this->nudIdFrom->TabIndex = 4;
			// 
			// label8
			// 
			this->label8->Location = System::Drawing::Point(436, 10);
			this->label8->Name = L"label8";
			this->label8->Size = System::Drawing::Size(28, 23);
			this->label8->TabIndex = 43;
			this->label8->Text = L"To:";
			// 
			// label7
			// 
			this->label7->Location = System::Drawing::Point(361, 12);
			this->label7->Name = L"label7";
			this->label7->Size = System::Drawing::Size(38, 23);
			this->label7->TabIndex = 42;
			this->label7->Text = L"From:";
			// 
			// rdbFilterOpen
			// 
			this->rdbFilterOpen->Checked = true;
			this->rdbFilterOpen->Location = System::Drawing::Point(120, 32);
			this->rdbFilterOpen->Name = L"rdbFilterOpen";
			this->rdbFilterOpen->Size = System::Drawing::Size(53, 17);
			this->rdbFilterOpen->TabIndex = 1;
			this->rdbFilterOpen->TabStop = true;
			this->rdbFilterOpen->Text = L"Open";
			this->rdbFilterOpen->UseVisualStyleBackColor = true;
			// 
			// rdbFilterCustom
			// 
			this->rdbFilterCustom->Location = System::Drawing::Point(238, 32);
			this->rdbFilterCustom->Name = L"rdbFilterCustom";
			this->rdbFilterCustom->Size = System::Drawing::Size(104, 17);
			this->rdbFilterCustom->TabIndex = 3;
			this->rdbFilterCustom->Text = L"Custom (expand)";
			this->rdbFilterCustom->UseVisualStyleBackColor = true;
			// 
			// rdbFilterClose
			// 
			this->rdbFilterClose->Location = System::Drawing::Point(177, 32);
			this->rdbFilterClose->Name = L"rdbFilterClose";
			this->rdbFilterClose->Size = System::Drawing::Size(58, 17);
			this->rdbFilterClose->TabIndex = 2;
			this->rdbFilterClose->Text = L"Close";
			this->rdbFilterClose->UseVisualStyleBackColor = true;
			// 
			// btnFilterApply
			// 
			this->btnFilterApply->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->btnFilterApply->Enabled = false;
			this->btnFilterApply->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->btnFilterApply->Location = System::Drawing::Point(578, 26);
			this->btnFilterApply->Name = L"btnFilterApply";
			this->btnFilterApply->Size = System::Drawing::Size(65, 23);
			this->btnFilterApply->TabIndex = 6;
			this->btnFilterApply->Text = L"Apply";
			this->btnFilterApply->UseVisualStyleBackColor = true;
			this->btnFilterApply->Click += gcnew System::EventHandler(this, &Form1::btnFilterApply_Click);
			// 
			// cbbIO
			// 
			this->cbbIO->DropDownStyle = System::Windows::Forms::ComboBoxStyle::DropDownList;
			this->cbbIO->Items->AddRange(gcnew cli::array< System::Object^  >(24) {L"0100", L"0120", L"0140", L"0200", L"0220", L"0240", 
				L"0260", L"0278", L"0280", L"02A0", L"02C0", L"02E0", L"02E8", L"02F8", L"0300", L"0320", L"0340", L"0360", L"0378", L"0380", 
				L"03BC", L"03E0", L"03E8", L"03F8"});
			this->cbbIO->Location = System::Drawing::Point(452, 31);
			this->cbbIO->Name = L"cbbIO";
			this->cbbIO->Size = System::Drawing::Size(55, 21);
			this->cbbIO->TabIndex = 4;
			// 
			// tmrRead
			// 
			this->tmrRead->Interval = 50;
			this->tmrRead->Tick += gcnew System::EventHandler(this, &Form1::tmrRead_Tick);
			// 
			// label4
			// 
			this->label4->Location = System::Drawing::Point(452, 15);
			this->label4->Name = L"label4";
			this->label4->Size = System::Drawing::Size(55, 23);
			this->label4->TabIndex = 43;
			this->label4->Text = L"I/O Port:";
			// 
			// label3
			// 
			this->label3->Location = System::Drawing::Point(327, 15);
			this->label3->Name = L"label3";
			this->label3->Size = System::Drawing::Size(90, 23);
			this->label3->TabIndex = 42;
			this->label3->Text = L"Hardware Type:";
			// 
			// cbbBaudrates
			// 
			this->cbbBaudrates->DropDownStyle = System::Windows::Forms::ComboBoxStyle::DropDownList;
			this->cbbBaudrates->Items->AddRange(gcnew cli::array< System::Object^  >(14) {L"1 MBit/sec", L"800 kBit/sec", L"500 kBit/sec", 
				L"250 kBit/sec", L"125 kBit/sec", L"100 kBit/sec", L"95,238 kBit/sec", L"83,333 kBit/sec", L"50 kBit/sec", L"47,619 kBit/sec", 
				L"33,333 kBit/sec", L"20 kBit/sec", L"10 kBit/sec", L"5 kBit/sec"});
			this->cbbBaudrates->Location = System::Drawing::Point(204, 31);
			this->cbbBaudrates->Name = L"cbbBaudrates";
			this->cbbBaudrates->Size = System::Drawing::Size(116, 21);
			this->cbbBaudrates->TabIndex = 2;
			this->cbbBaudrates->SelectedIndexChanged += gcnew System::EventHandler(this, &Form1::cbbBaudrates_SelectedIndexChanged);
			// 
			// label2
			// 
			this->label2->Location = System::Drawing::Point(204, 15);
			this->label2->Name = L"label2";
			this->label2->Size = System::Drawing::Size(56, 23);
			this->label2->TabIndex = 41;
			this->label2->Text = L"Baudrate:";
			// 
			// label1
			// 
			this->label1->Location = System::Drawing::Point(7, 16);
			this->label1->Name = L"label1";
			this->label1->Size = System::Drawing::Size(56, 23);
			this->label1->TabIndex = 40;
			this->label1->Text = L"Hardware:";
			// 
			// btnInit
			// 
			this->btnInit->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->btnInit->Cursor = System::Windows::Forms::Cursors::Default;
			this->btnInit->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->btnInit->Location = System::Drawing::Point(578, 30);
			this->btnInit->Name = L"btnInit";
			this->btnInit->Size = System::Drawing::Size(65, 23);
			this->btnInit->TabIndex = 6;
			this->btnInit->Text = L"Initialize";
			this->btnInit->Click += gcnew System::EventHandler(this, &Form1::btnInit_Click);
			// 
			// btnRelease
			// 
			this->btnRelease->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->btnRelease->Cursor = System::Windows::Forms::Cursors::Default;
			this->btnRelease->Enabled = false;
			this->btnRelease->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->btnRelease->Location = System::Drawing::Point(649, 30);
			this->btnRelease->Name = L"btnRelease";
			this->btnRelease->Size = System::Drawing::Size(65, 23);
			this->btnRelease->TabIndex = 7;
			this->btnRelease->Text = L"Release";
			this->btnRelease->Click += gcnew System::EventHandler(this, &Form1::btnRelease_Click);
			// 
			// btnParameterGet
			// 
			this->btnParameterGet->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->btnParameterGet->Enabled = false;
			this->btnParameterGet->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->btnParameterGet->Location = System::Drawing::Point(649, 26);
			this->btnParameterGet->Name = L"btnParameterGet";
			this->btnParameterGet->Size = System::Drawing::Size(65, 23);
			this->btnParameterGet->TabIndex = 5;
			this->btnParameterGet->Text = L"Get";
			this->btnParameterGet->UseVisualStyleBackColor = true;
			this->btnParameterGet->Click += gcnew System::EventHandler(this, &Form1::btnParameterGet_Click);
			// 
			// label10
			// 
			this->label10->Location = System::Drawing::Point(241, 11);
			this->label10->Name = L"label10";
			this->label10->Size = System::Drawing::Size(59, 23);
			this->label10->TabIndex = 46;
			this->label10->Text = L"Activation:";
			// 
			// nudDeviceId
			// 
			this->nudDeviceId->Enabled = false;
			this->nudDeviceId->Location = System::Drawing::Point(408, 29);
			this->nudDeviceId->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) {-1, 0, 0, 0});
			this->nudDeviceId->Name = L"nudDeviceId";
			this->nudDeviceId->Size = System::Drawing::Size(99, 20);
			this->nudDeviceId->TabIndex = 3;
			// 
			// label9
			// 
			this->label9->Location = System::Drawing::Point(405, 12);
			this->label9->Name = L"label9";
			this->label9->Size = System::Drawing::Size(59, 23);
			this->label9->TabIndex = 45;
			this->label9->Text = L"Device ID:";
			// 
			// cbbParameter
			// 
			this->cbbParameter->DropDownStyle = System::Windows::Forms::ComboBoxStyle::DropDownList;
			this->cbbParameter->FormattingEnabled = true;
			this->cbbParameter->Items->AddRange(gcnew cli::array< System::Object^  >(5) {L"USB\'s Device Number", L"USB/PC-Card\'s 5V Power", 
				L"Auto-reset on BUS-OFF", L"CAN Listen-Only", L"Debug\'s Log"});
			this->cbbParameter->Location = System::Drawing::Point(10, 31);
			this->cbbParameter->Name = L"cbbParameter";
			this->cbbParameter->Size = System::Drawing::Size(217, 21);
			this->cbbParameter->TabIndex = 0;
			this->cbbParameter->SelectedIndexChanged += gcnew System::EventHandler(this, &Form1::cbbParameter_SelectedIndexChanged);
			// 
			// groupBox2
			// 
			this->groupBox2->Anchor = static_cast<System::Windows::Forms::AnchorStyles>(((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Left) 
				| System::Windows::Forms::AnchorStyles::Right));
			this->groupBox2->Controls->Add(this->btnParameterGet);
			this->groupBox2->Controls->Add(this->label10);
			this->groupBox2->Controls->Add(this->nudDeviceId);
			this->groupBox2->Controls->Add(this->label9);
			this->groupBox2->Controls->Add(this->cbbParameter);
			this->groupBox2->Controls->Add(this->label6);
			this->groupBox2->Controls->Add(this->rdbParamActive);
			this->groupBox2->Controls->Add(this->rdbParamInactive);
			this->groupBox2->Controls->Add(this->btnParameterSet);
			this->groupBox2->Location = System::Drawing::Point(12, 147);
			this->groupBox2->Name = L"groupBox2";
			this->groupBox2->Size = System::Drawing::Size(720, 58);
			this->groupBox2->TabIndex = 2;
			this->groupBox2->TabStop = false;
			this->groupBox2->Text = L" Configuration Parameters ";
			// 
			// label6
			// 
			this->label6->Location = System::Drawing::Point(7, 14);
			this->label6->Name = L"label6";
			this->label6->Size = System::Drawing::Size(64, 23);
			this->label6->TabIndex = 43;
			this->label6->Text = L"Parameter:";
			// 
			// rdbParamActive
			// 
			this->rdbParamActive->Checked = true;
			this->rdbParamActive->Location = System::Drawing::Point(238, 32);
			this->rdbParamActive->Name = L"rdbParamActive";
			this->rdbParamActive->Size = System::Drawing::Size(56, 17);
			this->rdbParamActive->TabIndex = 1;
			this->rdbParamActive->TabStop = true;
			this->rdbParamActive->Text = L"Active";
			this->rdbParamActive->UseVisualStyleBackColor = true;
			// 
			// btnParameterSet
			// 
			this->btnParameterSet->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->btnParameterSet->Enabled = false;
			this->btnParameterSet->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->btnParameterSet->Location = System::Drawing::Point(578, 26);
			this->btnParameterSet->Name = L"btnParameterSet";
			this->btnParameterSet->Size = System::Drawing::Size(65, 23);
			this->btnParameterSet->TabIndex = 4;
			this->btnParameterSet->Text = L"Set";
			this->btnParameterSet->UseVisualStyleBackColor = true;
			this->btnParameterSet->Click += gcnew System::EventHandler(this, &Form1::btnParameterSet_Click);
			// 
			// groupBox1
			// 
			this->groupBox1->Anchor = static_cast<System::Windows::Forms::AnchorStyles>(((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Left) 
				| System::Windows::Forms::AnchorStyles::Right));
			this->groupBox1->Controls->Add(this->btnHwRefresh);
			this->groupBox1->Controls->Add(this->cbbChannel);
			this->groupBox1->Controls->Add(this->cbbHwType);
			this->groupBox1->Controls->Add(this->cbbInterrupt);
			this->groupBox1->Controls->Add(this->label5);
			this->groupBox1->Controls->Add(this->cbbIO);
			this->groupBox1->Controls->Add(this->label4);
			this->groupBox1->Controls->Add(this->label3);
			this->groupBox1->Controls->Add(this->cbbBaudrates);
			this->groupBox1->Controls->Add(this->label2);
			this->groupBox1->Controls->Add(this->label1);
			this->groupBox1->Controls->Add(this->btnInit);
			this->groupBox1->Controls->Add(this->btnRelease);
			this->groupBox1->FlatStyle = System::Windows::Forms::FlatStyle::System;
			this->groupBox1->Location = System::Drawing::Point(12, 12);
			this->groupBox1->Name = L"groupBox1";
			this->groupBox1->Size = System::Drawing::Size(720, 65);
			this->groupBox1->TabIndex = 0;
			this->groupBox1->TabStop = false;
			this->groupBox1->Text = L" Connection ";
			// 
			// tmrDisplay
			// 
			this->tmrDisplay->Tick += gcnew System::EventHandler(this, &Form1::tmrDisplay_Tick);
			// 
			// Form1
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(744, 564);
			this->Controls->Add(this->groupBox5);
			this->Controls->Add(this->groupBox6);
			this->Controls->Add(this->groupBox4);
			this->Controls->Add(this->groupBox3);
			this->Controls->Add(this->groupBox2);
			this->Controls->Add(this->groupBox1);
			this->Icon = (cli::safe_cast<System::Drawing::Icon^  >(resources->GetObject(L"$this.Icon")));
			this->MaximizeBox = false;
			this->Name = L"Form1";
			this->Text = L"PCAN-Basic Example";
			this->FormClosing += gcnew System::Windows::Forms::FormClosingEventHandler(this, &Form1::Form1_FormClosing);
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->nudLength))->EndInit();
			this->groupBox5->ResumeLayout(false);
			this->groupBox5->PerformLayout();
			this->groupBox6->ResumeLayout(false);
			this->groupBox6->PerformLayout();
			this->groupBox4->ResumeLayout(false);
			this->groupBox3->ResumeLayout(false);
			this->groupBox3->PerformLayout();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->nudIdTo))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->nudIdFrom))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->nudDeviceId))->EndInit();
			this->groupBox2->ResumeLayout(false);
			this->groupBox1->ResumeLayout(false);
			this->ResumeLayout(false);

		}
#pragma endregion

#pragma region Delegates
		/// <summary>
		/// Read-Delegate Handler
		/// </summary>
	private: 
		delegate void ReadDelegateHandler();
#pragma endregion

#pragma region Members
	private:
		/// <summary>
		/// Saves the handle of a PCAN hardware
		/// </summary>
		TPCANHandle ^m_PcanHandle;
		/// <summary>
		/// Saves the baudrate register for a conenction
		/// </summary>
		TPCANBaudrate ^m_Baudrate;
		/// <summary>
		/// Saves the type of a non-plug-and-play hardware
		/// </summary>
		TPCANType ^m_HwType;
		/// <summary>
		/// Stores the status of received messages for its display
		/// </summary>
		System::Collections::ArrayList ^m_LastMsgsList;
		/// <summary>
		/// Read Delegate for calling the function "ReadMessages"
		/// </summary>
		ReadDelegateHandler ^m_ReadDelegate;
		/// <summary>
		/// Receive-Event
		/// </summary>
		System::Threading::AutoResetEvent ^m_ReceiveEvent;
		/// <summary>
		/// Thread for message reading (using events)
		/// </summary>
		System::Threading::Thread ^m_ReadThread;
		/// <summary>
		/// Handles of the current available PCAN-Hardware
		/// </summary>
		array<TPCANHandle^> ^m_HandlesArray;
#pragma endregion

#pragma region Methods

#pragma region Help functions
	/// <summary>
	/// Gets the formated text for a CPAN-Basic channel handle
	/// </summary>
	/// <param name="handle">PCAN-Basic Handle to format</param>
	/// <returns>The formatted text for a channel</returns>
	private: String ^FormatChannelName(TPCANHandle ^handle)
	{
		TPCANDevice ^devDevice;
		Byte byChannel;

		// Gets the owner device and channel for a 
		// PCAN-Basic handle
		//
		devDevice = safe_cast<TPCANDevice>(safe_cast<Byte>(handle) >> 4);
		byChannel = safe_cast<Byte>(safe_cast<Byte>(handle) & 0xF);

		// Constructs the PCAN-Basic Channel name and return it
		//
		return String::Format("{0} {1} ({2:X2}h)", devDevice, byChannel, handle);
	}
	
	/// <summary>
	/// Configures the data of all ComboBox components of the main-form
	/// </summary>
	private: void FillComboBoxData()
	{
		// Channels will be check
		//
		btnHwRefresh_Click(this, gcnew EventArgs());

		// Baudrates 
		//
		cbbBaudrates->SelectedIndex = 2; // 500 K

		// Hardware Type for no plugAndplay hardware
		//
		cbbHwType->SelectedIndex = 0;

		// Interrupt for no plugAndplay hardware
		//
		cbbInterrupt->SelectedIndex = 0;

		// IO Port for no plugAndplay hardware
		//
		cbbIO->SelectedIndex = 0;

		// Parameters for GetValue and SetValue function calls
		//
		cbbParameter->SelectedIndex = 0;
	}

	/// <summary>
	/// Help Function used to get an error as text
	/// </summary>
	/// <param name="error">Error code to be translated</param>
	/// <returns>A text with the translated error</returns>
	private:String ^GetFormatedError(TPCANStatus ^error)
	{
		StringBuilder ^strTemp;

		// Creates a buffer big enough for a error-text
		//
		strTemp = gcnew StringBuilder(256);
		// Gets the text using the GetErrorText API function
		// If the function success, the translated error is returned. If it fails,
		// a text describing the current error is returned.
		//
		if (PCANBasic::GetErrorText(*error, 0, strTemp) != TPCANStatus::PCAN_ERROR_OK)
			return String::Format("An eror occurred. Error-code's text ({0:X}) couldn't be retrieved", error);
		else
			return strTemp->ToString();
	}

	/// <summary>
	/// Configure LogFile the Debug-Log file of PCAN-Basic
	/// </summary>
	/// <param name="bConnected">Current status. True if connected, false otherwise</param>
	private: void ConfigureLogFile()
	{
		UInt32 iBuffer;

		// Sets the mask to catch all events
		//
		iBuffer = PCANBasic::LOG_FUNCTION_ENTRY | PCANBasic::LOG_FUNCTION_LEAVE | PCANBasic::LOG_FUNCTION_PARAMETERS | PCANBasic::LOG_FUNCTION_READ | PCANBasic::LOG_FUNCTION_WRITE;

		// Configures the log file. 
		// NOTE: The Log capability is to be used with the NONEBUS Handle. Other handle than this will 
		// cause the function fail.
		//
		PCANBasic::SetValue(PCANBasic::PCAN_NONEBUS, TPCANParameter::PCAN_LOG_CONFIGURE, iBuffer, sizeof(UInt32));
	}

	/// <summary>
	/// Activates/deaactivates the different controls of the main-form according
	/// with the current connection status
	/// </summary>
	/// <param name="bConnected">Current status. True if connected, false otherwise</param>
	private: void SetConnectionStatus(bool bConnected)
	{
		// Buttons
		//
		btnInit->Enabled = !bConnected;
		btnRead->Enabled = bConnected && rdbManual->Checked;
		btnWrite->Enabled = bConnected;
		btnRelease->Enabled = bConnected;
		btnFilterApply->Enabled = bConnected;
		btnFilterQuery->Enabled = bConnected;
		btnParameterSet->Enabled = bConnected;
		btnParameterGet->Enabled = bConnected;
		btnGetVersions->Enabled = bConnected;
		btnStatus->Enabled = bConnected;
		btnReset->Enabled = bConnected;

		// ComboBoxs
		//
		cbbBaudrates->Enabled = !bConnected;
		cbbChannel->Enabled = !bConnected;
		cbbHwType->Enabled = !bConnected;
		cbbIO->Enabled = !bConnected;
		cbbInterrupt->Enabled = !bConnected;

		// Hardware configuration and read mode
		//
		if (!bConnected)
			cbbChannel_SelectedIndexChanged(this, gcnew EventArgs());
		else
			rdbTimer_CheckedChanged(this, gcnew EventArgs());

        // Display messages in grid
        //
        tmrDisplay->Enabled = bConnected;
	}

	/// <summary>
	/// Gets the current status of the PCAN-Basic message filter
	/// </summary>
	/// <param name="status">Buffer to retrieve the filter status</param>
	/// <returns>If calling the function was successfull or not</returns>
	private: bool GetFilterStatus([System::Runtime::InteropServices::Out] UInt32 %status)
	 {
		 TPCANStatus ^stsResult;

		 // Tries to get the stataus of the filter for the current connected hardware
		 //
		 stsResult = PCANBasic::GetValue(*m_PcanHandle, TPCANParameter::PCAN_MESSAGE_FILTER, status, sizeof(UInt32));

		 // If it fails, a error message is shown
		 //
		 if (*stsResult != TPCANStatus::PCAN_ERROR_OK)
		 {
			 MessageBox::Show(GetFormatedError(stsResult));
			 return false;
		 }
		 return true;
	 }

	/// <summary>
	/// Includes a new line of text into the information Listview
	/// </summary>
	/// <param name="strMsg">Text to be included</param>
	private: void IncludeTextMessage(String ^strMsg)
	 {
		 lbxInfo->Items->Add(strMsg);
		 lbxInfo->SelectedIndex = lbxInfo->Items->Count - 1;
	 }
#pragma endregion

#pragma region Message-proccessing functions

	/// <summary>
	/// Thread-Function used for reading PCAN-Basic messages
	/// </summary>
	private:void CANReadThreadFunc()
	{
		UInt32 iBuffer;
		TPCANStatus ^stsResult;

		iBuffer = Convert::ToUInt32(m_ReceiveEvent->SafeWaitHandle->DangerousGetHandle().ToInt32());
		// Sets the handle of the Receive-Event.
		//
		stsResult = PCANBasic::SetValue(*m_PcanHandle, TPCANParameter::PCAN_RECEIVE_EVENT,iBuffer, sizeof(UInt32));
		
		if(*stsResult != TPCANStatus::PCAN_ERROR_OK)
		{
			MessageBox::Show(GetFormatedError(stsResult),"Error!",MessageBoxButtons::OK,MessageBoxIcon::Error);
			return;
		}

		// While this mode is selected
		while (rdbEvent->Checked)
		{
			// Waiting for Receive-Event
			// 
			if(m_ReceiveEvent->WaitOne(50))
				// Process Receive-Event using .NET Invoke function
				// in order to interact with Winforms UI (calling the 
				// function ReadMessages)
				// 
				this->Invoke(m_ReadDelegate);
		}

		// Resets the Event-handle configuration
		//
		iBuffer = 0;
		PCANBasic::SetValue(*m_PcanHandle, TPCANParameter::PCAN_RECEIVE_EVENT,iBuffer, sizeof(UInt32));
	}

	/// <summary>
	/// Function for reading PCAN-Basic messages
	/// </summary>
	private: void ReadMessages()
	{
		TPCANMsg ^CANMsg;
		TPCANTimestamp ^CANTimeStamp;
		TPCANStatus ^stsResult;

		// Initializes Variables
		//
		CANTimeStamp = gcnew TPCANTimestamp();
		CANMsg = gcnew TPCANMsg();

		// We read at least one time the queue looking for messages.
		// If a message is found, we look again trying to find more.
		// If the queue is empty or an error occurr, we get out from
		// the dowhile statement.
		//			
		do
		{
			// We execute the "Read" function of the PCANBasic                
			//
			stsResult = PCANBasic::Read(*m_PcanHandle, *CANMsg, *CANTimeStamp);

			// A message was received
			// We process the message(s)
			//
			if (*stsResult == TPCANStatus::PCAN_ERROR_OK)
				ProcessMessage(CANMsg, CANTimeStamp);
		} while (btnRelease->Enabled && (!Convert::ToBoolean(*stsResult & TPCANStatus::PCAN_ERROR_QRCVEMPTY)));
	}

	/// <summary>
	/// Processes a received message, in order to show it in the Message-ListView
	/// </summary>
	/// <param name="theMsg">The received PCAN-Basic message</param>
	/// <param name="itsTimeStamp">The Timestamp of the received message</param>
	private: void ProcessMessage(TPCANMsg ^theMsg, TPCANTimestamp ^itsTimeStamp)
	{

		try
		{
			Monitor::Enter(m_LastMsgsList->SyncRoot);
            for each (MessageStatus^ msg in m_LastMsgsList)
            {
                if ((msg->CANMsg.ID == theMsg->ID) && (msg->CANMsg.MSGTYPE == theMsg->MSGTYPE))
                {
                    // Modify the message and exit
                    //
                    msg->Update(*theMsg, *itsTimeStamp);
                    return;
                }
            }
			// Message not found. It will created
			//
			InsertMsgEntry(theMsg, itsTimeStamp);
		}
		finally
		{
			Monitor::Exit(m_LastMsgsList->SyncRoot);
		}		
	}

	/// <summary>
	/// Inserts a new entry for a new message in the Message-ListView
	/// </summary>
	/// <param name="newMsg">The me3ssasge to be inserted</param>
	/// <param name="timeStamp">The Timesamp of the new message</param>
	private: void InsertMsgEntry(TPCANMsg ^newMsg, TPCANTimestamp ^timeStamp)
	{
		ListViewItem ^lviCurrentItem;
		MessageStatus ^msgStsCurrentMsg;

		try
		{
			Monitor::Enter(m_LastMsgsList->SyncRoot);

            // We add this status in the last message list
            //
            msgStsCurrentMsg = gcnew MessageStatus(*newMsg, *timeStamp, lstMessages->Items->Count);
            m_LastMsgsList->Add(msgStsCurrentMsg);

            // Add the new ListView Item with the Type of the message
            //	
            lviCurrentItem = lstMessages->Items->Add(msgStsCurrentMsg->TypeString);
            // We set the ID of the message
            //
            lviCurrentItem->SubItems->Add(msgStsCurrentMsg->IdString);
            // We set the length of the Message
            //
            lviCurrentItem->SubItems->Add(newMsg->LEN.ToString());
            // We set the data of the message. 	
            //
            lviCurrentItem->SubItems->Add(msgStsCurrentMsg->DataString);
            // we set the message count message (this is the First, so count is 1)            
            //
            lviCurrentItem->SubItems->Add(msgStsCurrentMsg->Count.ToString());
            // Add time stamp information if needed
            //
            lviCurrentItem->SubItems->Add(msgStsCurrentMsg->TimeString);
        }
		finally
		{
			Monitor::Exit(m_LastMsgsList->SyncRoot);
		}
	}


	/// <summary>
	/// Display CAN messages in the Message-ListView
	/// </summary>
	private: void DisplayMessages()
	{
		ListViewItem ^lviCurrentItem;

		try
		{
			Monitor::Enter(m_LastMsgsList->SyncRoot);
			
            for each (MessageStatus^ msgStatus in m_LastMsgsList)
            {
                // Get the data to actualize
                //
                if (msgStatus->MarkedAsUpdated)
                {
                    msgStatus->MarkedAsUpdated = false;
                    lviCurrentItem = lstMessages->Items[msgStatus->Position];

                    lviCurrentItem->SubItems[2]->Text = msgStatus->CANMsg.LEN.ToString();
                    lviCurrentItem->SubItems[3]->Text = msgStatus->DataString;
                    lviCurrentItem->SubItems[4]->Text = msgStatus->Count.ToString();
                    lviCurrentItem->SubItems[5]->Text = msgStatus->TimeString;
                }
            }	
		}
		finally
		{
			Monitor::Exit(m_LastMsgsList->SyncRoot);
		}
	}
#pragma endregion

#pragma region Event Handlers
	private: System::Void cbbChannel_SelectedIndexChanged(System::Object^  sender, System::EventArgs^  e)
	{
		bool bNonPnP;
		String ^strTemp;

		// Get the handle fromt he text being shown
		//
		strTemp = cbbChannel->Text;
		strTemp = strTemp->Substring(strTemp->IndexOf('(')+1, 2);

		// Determines if the handle belong to a No Plug&Play hardware 
		//
		m_PcanHandle = Convert::ToByte(strTemp,16);
		bNonPnP = static_cast<Byte>(m_PcanHandle) <= PCANBasic::PCAN_DNGBUS1;

		// Activates/deactivates configuration controls according with the 
		// kind of hardware
		//
		cbbHwType->Enabled = bNonPnP;
		cbbIO->Enabled = bNonPnP;
		cbbInterrupt->Enabled = bNonPnP;
	}

	private: System::Void btnHwRefresh_Click(System::Object^  sender, System::EventArgs^  e) 
	{
		UInt32 iBuffer;
		TPCANStatus ^stsResult;

		// Clears the Channel combioBox and fill it againa with 
		// the PCAN-Basic handles for no-Plug&Play hardware and
		// the detected Plug&Play hardware
		//
		cbbChannel->Items->Clear();
		try
		{
			for (int i = 0; i < m_HandlesArray->Length; i++)
			{
				// Includes all no-Plug&Play Handles
				if (safe_cast<Byte>(m_HandlesArray[i]) <= PCANBasic::PCAN_DNGBUS1)
					cbbChannel->Items->Add(FormatChannelName(m_HandlesArray[i]));
				else
				{
					// Checks for a Plug&Play Handle and, according with the return value, includes it
					// into the list of available hardware channels.
					//
					stsResult = PCANBasic::GetValue(safe_cast<Byte>(m_HandlesArray[i]), TPCANParameter::PCAN_CHANNEL_CONDITION, iBuffer, sizeof(UInt32));
					if (((*stsResult) == TPCANStatus::PCAN_ERROR_OK) && (iBuffer == PCANBasic::PCAN_CHANNEL_AVAILABLE))
						cbbChannel->Items->Add(FormatChannelName(m_HandlesArray[i]));
				}
			}
			cbbChannel->SelectedIndex = cbbChannel->Items->Count - 1;
		}
		catch(DllNotFoundException^)
		{
			MessageBox::Show("Unable to find the library: PCANBasic.dll !", "Error!",MessageBoxButtons::OK,MessageBoxIcon::Error);
			Environment::Exit(-1);
		}
	}

	private:System::Void btnInit_Click(System::Object^  sender, System::EventArgs^  e) 
	{
		TPCANStatus ^stsResult;

		// Connects a selected PCAN-Basic channel
		//
		stsResult = PCANBasic::Initialize(*m_PcanHandle, *m_Baudrate, *m_HwType, Convert::ToUInt32(cbbIO->Text,16), Convert::ToUInt16(cbbInterrupt->Text));

		if (*stsResult != TPCANStatus::PCAN_ERROR_OK)
			MessageBox::Show(GetFormatedError(stsResult));

		// Sets the connection status of the main-form
		//
		SetConnectionStatus(*stsResult == TPCANStatus::PCAN_ERROR_OK);

	}

	private:System::Void rdbTimer_CheckedChanged(System::Object^  sender, System::EventArgs^  e) 
	{				
		// CheckedChanged event is fired for each Radiobutton of one group
		// So, we must only take in account the selected button
		RadioButton^ radionButton = dynamic_cast<RadioButton ^>(sender);
		if(radionButton && !radionButton->Checked)
			return;
				
		if (!btnRelease->Enabled)
			return;

		// According with the kind of reading, a timer, a thread or a button will be enabled
		//
		if (rdbTimer->Checked)
		{
			// Abort Read Thread if it exists
			//
			if (m_ReadThread != nullptr)
			{
				m_ReadThread->Abort();
				m_ReadThread->Join();
				m_ReadThread = nullptr;
			}

			// Enable Timer
			//
			tmrRead->Enabled = btnRelease->Enabled;
		}
		
		if (rdbEvent->Checked)
		{
			// Disable Timer
			//
			tmrRead->Enabled = false;
			// Create and start the tread to read CAN Message using SetRcvEvent()
			//
			System::Threading::ThreadStart ^threadDelegate = gcnew System::Threading::ThreadStart(this, &Form1::CANReadThreadFunc);
			m_ReadThread = gcnew System::Threading::Thread(threadDelegate);
			m_ReadThread->IsBackground = true;
			m_ReadThread->Start();
		}
		
		if (rdbManual->Checked)
		{
			// Abort Read Thread if it exists
			//
			if (m_ReadThread != nullptr)
			{
				m_ReadThread->Abort();
				m_ReadThread->Join();
				m_ReadThread = nullptr;
			}
			// Disable Timer
			//
			tmrRead->Enabled = false;
			btnRead->Enabled = btnRelease->Enabled && rdbManual->Checked;
		}
	}

	private:System::Void cbbBaudrates_SelectedIndexChanged(System::Object^  sender, System::EventArgs^  e) 
	{
		// Saves the current selected baudrate register code
		//
		switch (cbbBaudrates->SelectedIndex)
		{
			case 0:
				m_Baudrate = TPCANBaudrate::PCAN_BAUD_1M;
				break;
			case 1:
				m_Baudrate = TPCANBaudrate::PCAN_BAUD_800K;
				break;
			case 2:
				m_Baudrate = TPCANBaudrate::PCAN_BAUD_500K;
				break;
			case 3:
				m_Baudrate = TPCANBaudrate::PCAN_BAUD_250K;
				break;
			case 4:
				m_Baudrate = TPCANBaudrate::PCAN_BAUD_125K;
				break;
			case 5:
				m_Baudrate = TPCANBaudrate::PCAN_BAUD_100K;
				break;
			case 6:
				m_Baudrate = TPCANBaudrate::PCAN_BAUD_95K;
				break;
			case 7:
				m_Baudrate = TPCANBaudrate::PCAN_BAUD_83K;
				break;
			case 8:
				m_Baudrate = TPCANBaudrate::PCAN_BAUD_50K;
				break;
			case 9:
				m_Baudrate = TPCANBaudrate::PCAN_BAUD_47K;
				break;
			case 10:
				m_Baudrate = TPCANBaudrate::PCAN_BAUD_33K;
				break;
			case 11:
				m_Baudrate = TPCANBaudrate::PCAN_BAUD_20K;
				break;
			case 12:
				m_Baudrate = TPCANBaudrate::PCAN_BAUD_10K;
				break;
			case 13:
				m_Baudrate = TPCANBaudrate::PCAN_BAUD_5K;
				break;
		}
	}

	private: System::Void cbbHwType_SelectedIndexChanged(System::Object^  sender, System::EventArgs^  e) 
	{
		// Saves the current type for a no-Plug&Play hardware
		//
		switch (cbbHwType->SelectedIndex)
		{
			case 0:
				m_HwType = TPCANType::PCAN_TYPE_ISA;
				break;
			case 1:
				m_HwType = TPCANType::PCAN_TYPE_ISA_SJA;
				break;
			case 2:
				m_HwType = TPCANType::PCAN_TYPE_ISA_PHYTEC;
				break;
			case 3:
				m_HwType = TPCANType::PCAN_TYPE_DNG;
				break;
			case 4:
				m_HwType = TPCANType::PCAN_TYPE_DNG_EPP;
				break;
			case 5:
				m_HwType = TPCANType::PCAN_TYPE_DNG_SJA;
				break;
			case 6:
				m_HwType = TPCANType::PCAN_TYPE_DNG_SJA_EPP;
				break;
		}
	}

	private: System::Void btnRelease_Click(System::Object^  sender, System::EventArgs^  e) 
	{
		//Stop Timer
		tmrRead->Enabled = false;

		//Stop Thread
		if (m_ReadThread != nullptr)
		{
			m_ReadThread->Abort();
			m_ReadThread->Join();
			m_ReadThread = nullptr;
		}

		// Releases a current connected PCAN-Basic channel
		//
		PCANBasic::Uninitialize(*m_PcanHandle);

		// Sets the connection status of the main-form
		//
		SetConnectionStatus(false);
	}

	private: System::Void chbFilterExt_CheckedChanged(System::Object^  sender, System::EventArgs^  e) 
	{
		int iMaxValue;

		iMaxValue = (chbFilterExt->Checked) ? 0x1FFFFFFF : 0x7FF;

		// We check that the maximum value for a selected filter 
		// mode is used
		//
		if (nudIdTo->Value > iMaxValue)
			nudIdTo->Value = iMaxValue;

		nudIdTo->Maximum = iMaxValue;
	}

	private: System::Void btnFilterApply_Click(System::Object^  sender, System::EventArgs^  e) 
	{
		UInt32 iBuffer;
		TPCANStatus ^stsResult;

		// Gets the current status of the message filter
		//
		if (!GetFilterStatus(iBuffer))
			return;

		// Configures the message filter for a custom range of messages
		//
		if (rdbFilterCustom->Checked)
		{
			// The filter must be first closed in order to customize it
			//
			if (iBuffer != PCANBasic::PCAN_FILTER_OPEN)
			{
				// Sets the custom filter
				//
				stsResult = PCANBasic::FilterMessages(*m_PcanHandle, Convert::ToUInt32(nudIdFrom->Value), Convert::ToUInt32(nudIdTo->Value), chbFilterExt->Checked ? TPCANMode::PCAN_MODE_EXTENDED : TPCANMode::PCAN_MODE_STANDARD);
				// If success, an information message is written, if it is not, an error message is shown
				//
				if (*stsResult == TPCANStatus::PCAN_ERROR_OK)
					IncludeTextMessage(String::Format("The filter was customized. IDs from {0:X} to {1:X} will be received", nudIdFrom->Text, nudIdTo->Text));
				else
					MessageBox::Show(GetFormatedError(stsResult));
			}
			else
				MessageBox::Show("The filter must be closed first in order to be able to customize it");

			return;
		}

		 // The filter will be full opened or complete closed
		 //
		 if (rdbFilterClose->Checked)
			 iBuffer = PCANBasic::PCAN_FILTER_CLOSE;
		 else
			 iBuffer = PCANBasic::PCAN_FILTER_OPEN;

		 // The filter is configured
		 //
		 stsResult = PCANBasic::SetValue(*m_PcanHandle, TPCANParameter::PCAN_MESSAGE_FILTER, iBuffer, sizeof(UInt32));

		 // If success, an information message is written, if it is not, an error message is shown
		 //
		 if (*stsResult == TPCANStatus::PCAN_ERROR_OK)
			 IncludeTextMessage(String::Format("The filter was successfully {0}", rdbFilterClose->Checked ? "closed." : "opened."));
		 else
			 MessageBox::Show(GetFormatedError(stsResult));
	}

	private: System::Void btnRead_Click(System::Object^  sender, System::EventArgs^  e) 
	{
		TPCANMsg ^CANMsg;
		TPCANTimestamp ^CANTimeStamp;
		TPCANStatus ^stsResult;

		// Initializes Variables
		//
		CANTimeStamp = gcnew TPCANTimestamp();
		CANMsg = gcnew TPCANMsg();

		// We execute the "Read" function of the PCANBasic                
		//
		stsResult = PCANBasic::Read(*m_PcanHandle, *CANMsg, *CANTimeStamp);
		if (*stsResult == TPCANStatus::PCAN_ERROR_OK)
			// We process the received message
			//
			ProcessMessage(CANMsg, CANTimeStamp);
		else
			// If an error occurred, an information message is included
			//
			IncludeTextMessage(GetFormatedError(stsResult));
	}

	private: System::Void btnMsgClear_Click(System::Object^  sender, System::EventArgs^  e) 
	{
		// The information contained in the messages List-View
		// is cleared
		//
		Monitor::Enter(m_LastMsgsList->SyncRoot);
		try
		{
			lstMessages->Items->Clear();
			m_LastMsgsList->Clear();
		}
		finally
		{
			System::Threading::Monitor::Exit(this);
		}
	}

	private: System::Void txtID_KeyPress(System::Object^  sender, System::Windows::Forms::KeyPressEventArgs^  e) 
	{
		Char chCheck;

		// We convert the Character to its Upper case equivalent
		//
		chCheck = Char::ToUpper(e->KeyChar);

		// The Key is the Delete (Backspace) Key
		//
		if (chCheck == 8)
			return;
		// The Key is a number between 0-9
		//
		if ((chCheck > 47) && (chCheck < 58))
			return;
		// The Key is a character between A-F
		//
		if ((chCheck > 64) && (chCheck < 71))
			return;

		// Is neither a number nor a character between A(a) and F(f)
		//
		e->Handled = true;
	}

	private: System::Void txtID_Leave(System::Object^  sender, System::EventArgs^  e) 
	{
		int iTextLength;
		UInt32 uiMaxValue;

		// Calculates the text length and Maximum ID value according
		// with the Message Type
		//
		iTextLength = (chbExtended->Checked) ? 8 : 3;
		uiMaxValue = (chbExtended->Checked) ? safe_cast<UInt32>(0x1FFFFFF) : safe_cast<UInt32>(0x7FF);

		// The Textbox for the ID is represented with 3 characters for 
		// Standard and 8 characters for extended messages.
		// Therefore if the Length of the text is smaller than TextLength,  
		// we add "0"
		//
		while (txtID->Text->Length != iTextLength)
			txtID->Text = ("0" + txtID->Text);

		// We check that the ID is not bigger than current maximum value
		//
		if (Convert::ToUInt32(txtID->Text, 16) > uiMaxValue)
			txtID->Text = String::Format("{0:X" + iTextLength.ToString() + "}", uiMaxValue);
	}

	private: System::Void chbExtended_CheckedChanged(System::Object^  sender, System::EventArgs^  e) 
	{
		UInt32 uiTemp;

		txtID->MaxLength = (chbExtended->Checked) ? 8 : 3;
		
		// the only way that the text length can be bigger als MaxLength
		// is when the change is from Extended to Standard message Type.
		// We have to handle this and set an ID not bigger than the Maximum
		// ID value for a Standard Message (0x7FF)
		//
		if (txtID->Text->Length > txtID->MaxLength)
		{
			uiTemp = Convert::ToUInt32(txtID->Text, 16);
			txtID->Text = (uiTemp < 0x7FF) ? String::Format("{0:X3}", uiTemp) : "7FF";
		}

		txtID_Leave(this, gcnew EventArgs());
	}

	private: System::Void chbRemote_CheckedChanged(System::Object^  sender, System::EventArgs^  e) 
	{
		TextBox ^txtbCurrentTextBox;

		txtbCurrentTextBox = txtData0;

		// If the message is a RTR, no data is sent. The textbox for data 
		// will be turned invisible
		// 
		for (int i = 0; i < 8; i++)
		{
			txtbCurrentTextBox->Visible = !chbRemote->Checked;
			if (i < 7)
				txtbCurrentTextBox = safe_cast<TextBox^>(this->GetNextControl(txtbCurrentTextBox, true));
		}
	}

	private: System::Void txtData0_Leave(System::Object^  sender, System::EventArgs^  e) 
	{
		TextBox ^txtbCurrentTextbox;

		// all the Textbox Data fields are represented with 2 characters.
		// Therefore if the Length of the text is smaller than 2, we add
		// a "0"
		//
		if (sender->GetType()->Name == "TextBox")
		{
			txtbCurrentTextbox = safe_cast<TextBox^>(sender);
			while (txtbCurrentTextbox->Text->Length != 2)
				txtbCurrentTextbox->Text = ("0" + txtbCurrentTextbox->Text);
		}
	}

	private: System::Void btnWrite_Click(System::Object^  sender, System::EventArgs^  e) 
	{
		TPCANMsg ^CANMsg;
		TextBox ^txtbCurrentTextBox;
		TPCANStatus ^stsResult;

		// We create a TCLightMsg message structure 
		//
		CANMsg = gcnew TPCANMsg();
		CANMsg->DATA = gcnew array<Byte>(8);

		// We configurate the Message.  The ID (max 0x1FF),
		// Length of the Data, Message Type (Standard in 
		// this example) and die data
		//
		CANMsg->ID = Convert::ToUInt32(txtID->Text, 16);
		CANMsg->LEN = Convert::ToByte(nudLength->Value);
		CANMsg->MSGTYPE = (chbExtended->Checked) ? TPCANMessageType::PCAN_MESSAGE_EXTENDED : TPCANMessageType::PCAN_MESSAGE_STANDARD;
		// If a remote frame will be sent, the data bytes are not important.
		//
		if (chbRemote->Checked)
			CANMsg->MSGTYPE = safe_cast<TPCANMessageType>(safe_cast<Byte>(CANMsg->MSGTYPE) | safe_cast<Byte>(TPCANMessageType::PCAN_MESSAGE_RTR));
		else
		{
			// We get so much data as the Len of the message
			//
			txtbCurrentTextBox = txtData0;
			for (int i = 0; i < CANMsg->LEN; i++)
			{
				CANMsg->DATA[i] = Convert::ToByte(txtbCurrentTextBox->Text, 16);
				if (i < 7)
					txtbCurrentTextBox = safe_cast<TextBox^>(this->GetNextControl(txtbCurrentTextBox, true));
			}
		}

		// The message is sent to the configured hardware
		//
		stsResult = PCANBasic::Write(*m_PcanHandle, *CANMsg);

		// The Hardware was successfully sent
		//
		if (*stsResult == TPCANStatus::PCAN_ERROR_OK)
			IncludeTextMessage("Message was successfully SENT");
		// An error occurred.  We show the error.
		//			
		else
			MessageBox::Show(GetFormatedError(stsResult));
	}

	private: System::Void btnGetVersions_Click(System::Object^  sender, System::EventArgs^  e) 
	{
		TPCANStatus ^stsResult;
		StringBuilder ^strTemp;
		array<String^> ^strArrayVersion;

		strTemp = gcnew StringBuilder(256);

		// We get the vesion of the PCAN-Basic API
		//
		stsResult = PCANBasic::GetValue(PCANBasic::PCAN_NONEBUS, TPCANParameter::PCAN_API_VERSION, strTemp, 256);
		if (*stsResult == TPCANStatus::PCAN_ERROR_OK)
		{
			IncludeTextMessage("API Version: " + strTemp->ToString());
			// We get the driver version of the channel being used
			//
			stsResult = PCANBasic::GetValue(*m_PcanHandle, TPCANParameter::PCAN_CHANNEL_VERSION, strTemp, 256);
			if (*stsResult == TPCANStatus::PCAN_ERROR_OK)
			{
				// Because this information contains line control characters (several lines)
				// we split this also in several entries in the Information List-Box
				//
				strArrayVersion = strTemp->ToString()->Split(gcnew array<Char> { '\n' });
				IncludeTextMessage("Channel/Driver Version: ");
				for(int i =0; i < strArrayVersion->Length; i++)
					IncludeTextMessage("     * " + strArrayVersion[i]);
			}
		}

		// If an error ccurred, a message is shown
		//
		if (*stsResult != TPCANStatus::PCAN_ERROR_OK)
			MessageBox::Show(GetFormatedError(stsResult));
	}

	private: System::Void btnInfoClear_Click(System::Object^  sender, System::EventArgs^  e) 
	{
		// The information contained in the Information List-Box 
		// is cleared
		//
		lbxInfo->Items->Clear();
	}

	private: System::Void Form1_FormClosing(System::Object^  sender, System::Windows::Forms::FormClosingEventArgs^  e) 
	{
		// Releases the used PCAN-Basic channel
		//
		if(btnRelease->Enabled)
			btnRelease_Click(nullptr , nullptr);
	}

	private: System::Void tmrRead_Tick(System::Object^  sender, System::EventArgs^  e) 
	{
		// Checks if in the receive-queue are currently messages for read
		// 
		ReadMessages();
	}

	private: System::Void tmrDisplay_Tick(System::Object^  sender, System::EventArgs^  e) 
	{
		DisplayMessages();
	}

	private: System::Void chbShowPeriod_CheckedChanged(System::Object^  sender, System::EventArgs^  e) 
	{
		// According with the check-value of this checkbox,
		// the recieved time of a messages will be interpreted as 
		// period (time between the two last messages) or as time-stamp
		// (the elapsed time since windows was started)
		//
		Monitor::Enter(m_LastMsgsList->SyncRoot);
		try
		{
			for each (MessageStatus^ msg in m_LastMsgsList)
				msg->ShowingPeriod = chbShowPeriod->Checked;
		}
		finally
		{
			Monitor::Exit(m_LastMsgsList->SyncRoot);
		}
	}

	private: System::Void btnFilterQuery_Click(System::Object^  sender, System::EventArgs^  e) 
	{
		UInt32 iBuffer;

		// Queries the current status of the message filter
		//
		if (GetFilterStatus(iBuffer))
		{
			switch(iBuffer)
			{
				// The filter is closed
				//
				case PCANBasic::PCAN_FILTER_CLOSE:
					IncludeTextMessage("The Status of the filter is: closed.");
					break;
				// The filter is fully opened
				//
				case PCANBasic::PCAN_FILTER_OPEN:
					IncludeTextMessage("The Status of the filter is: full opened.");
					break;
				// The filter is customized
				//
				case PCANBasic::PCAN_FILTER_CUSTOM:
					IncludeTextMessage("The Status of the filter is: customized.");
					break;
				// The status of the filter is undefined. (Should never happen)
				//
				default:
					IncludeTextMessage("The Status of the filter is: Invalid.");
					break;
			}
		}
	}

	private: System::Void cbbParameter_SelectedIndexChanged(System::Object^  sender, System::EventArgs^  e) 
	{
		// Activates/deactivates controls according with the selected 
		// PCAN-Basic parameter 
		//
		rdbParamActive->Enabled = (dynamic_cast<ComboBox^>(sender))->SelectedIndex != 0;
		rdbParamInactive->Enabled = rdbParamActive->Enabled;
		nudDeviceId->Enabled = !rdbParamActive->Enabled;
	}

	private: System::Void btnParameterSet_Click(System::Object^  sender, System::EventArgs^  e) 
	{
		TPCANStatus ^stsResult;
		UInt32 iBuffer;

		// Sets a PCAN-Basic parameter value
		//
		switch (cbbParameter->SelectedIndex)
		{
			// The Device-Number of an USB channel will be set
			//
			case 0:
				iBuffer = Convert::ToUInt32(nudDeviceId->Value);
				stsResult = PCANBasic::SetValue(*m_PcanHandle, TPCANParameter::PCAN_DEVICE_NUMBER, iBuffer, sizeof(UInt32));
				if(*stsResult == TPCANStatus::PCAN_ERROR_OK)
					IncludeTextMessage("The desired Device-Number was successfully configured");
				break;
			// The 5 Volt Power feature of a PC-card or USB will be set
			//
			case 1:
				iBuffer = safe_cast<UInt32>(rdbParamActive->Checked ? PCANBasic::PCAN_PARAMETER_ON : PCANBasic::PCAN_PARAMETER_OFF);
				stsResult = PCANBasic::SetValue(*m_PcanHandle, TPCANParameter::PCAN_5VOLTS_POWER, iBuffer, sizeof(UInt32));
				if (*stsResult == TPCANStatus::PCAN_ERROR_OK)
					IncludeTextMessage(String::Format("The USB/PC-Card 5 power was successfully {0}", (iBuffer == PCANBasic::PCAN_PARAMETER_ON) ? "activated" : "deactivated"));
				break;
			// The feature for automatic reset on BUS-OFF will be set
			//
			case 2:
				iBuffer = safe_cast<UInt32>(rdbParamActive->Checked ? PCANBasic::PCAN_PARAMETER_ON : PCANBasic::PCAN_PARAMETER_OFF);
				stsResult = PCANBasic::SetValue(*m_PcanHandle, TPCANParameter::PCAN_BUSOFF_AUTORESET, iBuffer, sizeof(UInt32));
				if (*stsResult == TPCANStatus::PCAN_ERROR_OK)
					IncludeTextMessage(String::Format("The automatic-reset on BUS-OFF was successfully {0}", (iBuffer == PCANBasic::PCAN_PARAMETER_ON) ? "activated" : "deactivated"));
				break;
			// The CAN option "Listen Only" will be set
			//
			case 3:
				iBuffer = safe_cast<UInt32>(rdbParamActive->Checked ? PCANBasic::PCAN_PARAMETER_ON : PCANBasic::PCAN_PARAMETER_OFF);
				stsResult = PCANBasic::SetValue(*m_PcanHandle, TPCANParameter::PCAN_LISTEN_ONLY, iBuffer, sizeof(UInt32));
				if (*stsResult == TPCANStatus::PCAN_ERROR_OK)
					IncludeTextMessage(String::Format("The CAN-option Listen-Only was successfully {0}", (iBuffer == PCANBasic::PCAN_PARAMETER_ON) ? "activated" : "deactivated"));
				break;
			// The feature for logging debug-information will be set
			//
			case 4:
				iBuffer = safe_cast<UInt32>(rdbParamActive->Checked ? PCANBasic::PCAN_PARAMETER_ON : PCANBasic::PCAN_PARAMETER_OFF);
				stsResult = PCANBasic::SetValue(PCANBasic::PCAN_NONEBUS, TPCANParameter::PCAN_LOG_STATUS, iBuffer, sizeof(UInt32));
				if (*stsResult == TPCANStatus::PCAN_ERROR_OK)
					IncludeTextMessage(String::Format("The feature for logging debug information was successfully {0}", (iBuffer == PCANBasic::PCAN_PARAMETER_ON) ? "activated" : "deactivated"));
				break;
			// The current parameter is invalid
			//
			default:
				*stsResult = TPCANStatus::PCAN_ERROR_UNKNOWN;
				MessageBox::Show("Wrong parameter code.");
				return;
		}

		// If the function fail, an error message is shown
		//
		if(*stsResult != TPCANStatus::PCAN_ERROR_OK)
			MessageBox::Show(GetFormatedError(stsResult));
	}

	private: System::Void btnParameterGet_Click(System::Object^  sender, System::EventArgs^  e) 
	{
		TPCANStatus ^stsResult;
		UInt32 iBuffer;

		// Gets a PCAN-Basic parameter value
		//
		switch (cbbParameter->SelectedIndex)
		{
			// The Device-Number of an USB channel will be retrieved
			//
			case 0:
				stsResult = PCANBasic::GetValue(*m_PcanHandle, TPCANParameter::PCAN_DEVICE_NUMBER, iBuffer, sizeof(UInt32));
				if (*stsResult == TPCANStatus::PCAN_ERROR_OK)
					IncludeTextMessage(String::Format("The configured Device-Number is {0:X}",iBuffer));
				break;
				// The activation status of the 5 Volt Power feature of a PC-card or USB will be retrieved
				//
			case 1:
				stsResult = PCANBasic::GetValue(*m_PcanHandle, TPCANParameter::PCAN_5VOLTS_POWER, iBuffer, sizeof(UInt32));
				if (*stsResult == TPCANStatus::PCAN_ERROR_OK)
					IncludeTextMessage(String::Format("The 5-Volt Power of the USB/PC-Card is {0:X}", (iBuffer == PCANBasic::PCAN_PARAMETER_ON) ? "ON" : "OFF"));
				break;
			// The activation status of the feature for automatic reset on BUS-OFF will be retrieved
			//
			case 2:
				stsResult = PCANBasic::GetValue(*m_PcanHandle, TPCANParameter::PCAN_BUSOFF_AUTORESET, iBuffer, sizeof(UInt32));
				if (*stsResult == TPCANStatus::PCAN_ERROR_OK)
					IncludeTextMessage(String::Format("The automatic-reset on BUS-OFF is {0:X}", (iBuffer == PCANBasic::PCAN_PARAMETER_ON) ? "ON" : "OFF"));
					break;
			// The activation status of the CAN option "Listen Only" will be retrieved
			//
			case 3:
				stsResult = PCANBasic::GetValue(*m_PcanHandle, TPCANParameter::PCAN_LISTEN_ONLY, iBuffer, sizeof(UInt32));
				if (*stsResult == TPCANStatus::PCAN_ERROR_OK)
					IncludeTextMessage(String::Format("The CAN-option Listen-Only is {0:X}", (iBuffer == PCANBasic::PCAN_PARAMETER_ON) ? "ON" : "OFF"));
				break;
			// The activation status for the feature for logging debug-information will be retrieved
			//
			case 4:
				stsResult = PCANBasic::GetValue(PCANBasic::PCAN_NONEBUS, TPCANParameter::PCAN_LOG_STATUS, iBuffer, sizeof(UInt32));
				if (*stsResult == TPCANStatus::PCAN_ERROR_OK)
					IncludeTextMessage(String::Format("The feature for logging debug information is {0:X}", (iBuffer == PCANBasic::PCAN_PARAMETER_ON) ? "ON" : "OFF"));
				break;
			// The current parameter is invalid
			//
			default:
				*stsResult = TPCANStatus::PCAN_ERROR_UNKNOWN;
				MessageBox::Show("Wrong parameter code.");
				return;
		}

		// If the function fail, an error message is shown
		//
		if (*stsResult != TPCANStatus::PCAN_ERROR_OK)
			MessageBox::Show(GetFormatedError(stsResult));
	}

	private: System::Void nudLength_ValueChanged(System::Object^  sender, System::EventArgs^  e) 
	{
		TextBox ^CurrentTextBox;

		CurrentTextBox = txtData0;

		// We enable so much TextBox Data fields as the length of the
		// message will be, that is the value of the UpDown control.
		// 
		for(int i=0; i< 8; i++)
		{
			CurrentTextBox->Enabled = (i < nudLength->Value)? true : false;
			if(i < 7)
				CurrentTextBox = safe_cast<TextBox^>(this->GetNextControl(CurrentTextBox,true));
		}
	}

	private: System::Void buttonReset_Click(System::Object^  sender, System::EventArgs^  e)
	{
		TPCANStatus ^stsResult;

		// Resets the receive and transmit queues of a PCAN Channel.
		//
		stsResult = PCANBasic::Reset(*m_PcanHandle);

		// If it fails, a error message is shown
		//
		if (*stsResult != TPCANStatus::PCAN_ERROR_OK)
			MessageBox::Show(GetFormatedError(stsResult));
		else
			IncludeTextMessage("Receive and transmit queues successfully reset");
	}

	private: System::Void buttonStatus_Click(System::Object^  sender, System::EventArgs^  e) 
	{
		TPCANStatus ^status;
		String ^errorName;

		// Gets the current BUS status of a PCAN Channel.
		//
		status = PCANBasic::GetStatus(*m_PcanHandle);

		// Switch On Error Name
		//
		switch(*status)
		{
			case TPCANStatus::PCAN_ERROR_INITIALIZE:
				errorName = "PCAN_ERROR_INITIALIZE";
				break;

			case TPCANStatus::PCAN_ERROR_BUSLIGHT:
				errorName = "PCAN_ERROR_BUSLIGHT";
				break;

			case TPCANStatus::PCAN_ERROR_BUSHEAVY:
				errorName = "PCAN_ERROR_BUSHEAVY";
				break;

			case TPCANStatus::PCAN_ERROR_BUSOFF:
				errorName = "PCAN_ERROR_BUSOFF";
				break;

			case TPCANStatus::PCAN_ERROR_OK:
				errorName = "PCAN_ERROR_OK";
				break;

			default:
				errorName = "See Documentation";
				break;
		}

		// Display Message
		//
		IncludeTextMessage(String::Format("Status: {0} ({1:X}h)", errorName, *status));
	}
#pragma endregion

#pragma endregion
};
}

