Skip to content

Instantly share code, notes, and snippets.

@kreon
Last active July 19, 2018 16:21
Show Gist options
  • Save kreon/c204d79496019cb2542831000ef796d8 to your computer and use it in GitHub Desktop.
Save kreon/c204d79496019cb2542831000ef796d8 to your computer and use it in GitHub Desktop.
Temperature Terminal with Graph thru serial port
#include "GraphForm.h"
#pragma once
namespace TermGraph {
#pragma region ---HEAD---
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 System::Windows::Forms::DataVisualization::Charting;
/// <summary>
/// Сводка для GraphForm
/// </summary>
public ref class GraphForm : public System::Windows::Forms::Form
{
public: //create parameterized constructor IO::Ports::SerialPort^ _comPort
GraphForm(System::Windows::Forms::DataVisualization::Charting::Series^ _ptSeries)
{
InitializeComponent();
//
//TODO: добавьте код конструктора
//
//comPort = _comPort;
MyFormPtSer = _ptSeries;
}
protected:
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
~GraphForm()
{
// Abort thread
if ((addDataRunner->ThreadState & ThreadState::Suspended) == ThreadState::Suspended)
{
addDataRunner->Resume();
}
addDataRunner->Abort();
if (components)
{
delete components;
}
}
protected:
private:
/// <summary>
/// Обязательная переменная конструктора.
/// </summary>
System::ComponentModel::Container ^components;
//private: IO::Ports::SerialPort^ comPort;
private: Series^ MyFormPtSer;
private: Series^ GraphFormPtSer;
// Chart data adding thread
private: System::Threading::Thread^ addDataRunner;
// Thread Add Data delegate
public: delegate void AddDataDelegate();
public: AddDataDelegate^ addDataDlg;
private: DateTime^ minValue;
private: DateTime^ maxValue;
private: double MinY, MaxY;
private: System::Windows::Forms::DataVisualization::Charting::Chart^ chartGraphForm;
private: System::Windows::Forms::DataVisualization::Charting::RectangleAnnotation^ myAnno;
private: Double zero = 0.0;
private: Double myNan = 0.0 / zero;
private: double SelectionStart = myNan;//double.NaN
private: int time_press_button, mult;
#pragma region Windows Form Designer generated code
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
void InitializeComponent(void)
{
System::Windows::Forms::DataVisualization::Charting::RectangleAnnotation^ rectangleAnnotation1 = (gcnew System::Windows::Forms::DataVisualization::Charting::RectangleAnnotation());
System::Windows::Forms::DataVisualization::Charting::ChartArea^ chartArea1 = (gcnew System::Windows::Forms::DataVisualization::Charting::ChartArea());
System::Windows::Forms::DataVisualization::Charting::Series^ series1 = (gcnew System::Windows::Forms::DataVisualization::Charting::Series());
this->chartGraphForm = (gcnew System::Windows::Forms::DataVisualization::Charting::Chart());
(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->chartGraphForm))->BeginInit();
this->SuspendLayout();
//
// chartGraphForm
//
rectangleAnnotation1->AllowMoving = true;
rectangleAnnotation1->Name = L"annot1";
rectangleAnnotation1->Text = L"Annotation Text";
this->chartGraphForm->Annotations->Add(rectangleAnnotation1);
chartArea1->AxisX->IntervalAutoMode = System::Windows::Forms::DataVisualization::Charting::IntervalAutoMode::VariableCount;
chartArea1->AxisX->IntervalType = System::Windows::Forms::DataVisualization::Charting::DateTimeIntervalType::Minutes;
chartArea1->AxisX->LabelAutoFitMaxFontSize = 9;
chartArea1->AxisX->LabelAutoFitStyle = static_cast<System::Windows::Forms::DataVisualization::Charting::LabelAutoFitStyles>(((((((System::Windows::Forms::DataVisualization::Charting::LabelAutoFitStyles::IncreaseFont | System::Windows::Forms::DataVisualization::Charting::LabelAutoFitStyles::DecreaseFont)
| System::Windows::Forms::DataVisualization::Charting::LabelAutoFitStyles::StaggeredLabels)
| System::Windows::Forms::DataVisualization::Charting::LabelAutoFitStyles::LabelsAngleStep30)
| System::Windows::Forms::DataVisualization::Charting::LabelAutoFitStyles::LabelsAngleStep45)
| System::Windows::Forms::DataVisualization::Charting::LabelAutoFitStyles::LabelsAngleStep90)
| System::Windows::Forms::DataVisualization::Charting::LabelAutoFitStyles::WordWrap));
chartArea1->AxisX->LabelStyle->Font = (gcnew System::Drawing::Font(L"Trebuchet MS", 8.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(204)));
chartArea1->AxisX->LabelStyle->Format = L"HH:mm";
chartArea1->AxisX->LabelStyle->Interval = 0;
chartArea1->AxisX->LabelStyle->IntervalType = System::Windows::Forms::DataVisualization::Charting::DateTimeIntervalType::Minutes;
chartArea1->AxisX->MajorGrid->IntervalType = System::Windows::Forms::DataVisualization::Charting::DateTimeIntervalType::Minutes;
chartArea1->AxisX->MajorGrid->LineColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(224)),
static_cast<System::Int32>(static_cast<System::Byte>(224)), static_cast<System::Int32>(static_cast<System::Byte>(224)));
chartArea1->AxisX->MajorTickMark->Interval = 0;
chartArea1->AxisX->MajorTickMark->IntervalType = System::Windows::Forms::DataVisualization::Charting::DateTimeIntervalType::Minutes;
chartArea1->AxisX->MaximumAutoSize = 95;
chartArea1->AxisX->ScaleBreakStyle->StartFromZero = System::Windows::Forms::DataVisualization::Charting::StartFromZero::No;
chartArea1->AxisX->ScrollBar->LineColor = System::Drawing::Color::Black;
chartArea1->AxisX->ScrollBar->Size = 10;
chartArea1->AxisY->IntervalAutoMode = System::Windows::Forms::DataVisualization::Charting::IntervalAutoMode::VariableCount;
chartArea1->AxisY->IsStartedFromZero = false;
chartArea1->AxisY->LabelAutoFitMaxFontSize = 9;
chartArea1->AxisY->LabelStyle->Font = (gcnew System::Drawing::Font(L"Trebuchet MS", 8.25F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(204)));
chartArea1->AxisY->LabelStyle->Format = L"{0.00}°C";
chartArea1->AxisY->LabelStyle->Interval = 0;
chartArea1->AxisY->MajorGrid->Interval = 0;
chartArea1->AxisY->MajorGrid->LineColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(224)),
static_cast<System::Int32>(static_cast<System::Byte>(224)), static_cast<System::Int32>(static_cast<System::Byte>(224)));
chartArea1->AxisY->MajorTickMark->Interval = 0;
chartArea1->AxisY->MaximumAutoSize = 95;
chartArea1->AxisY->MinorGrid->LineColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(224)),
static_cast<System::Int32>(static_cast<System::Byte>(224)), static_cast<System::Int32>(static_cast<System::Byte>(224)));
chartArea1->AxisY->ScrollBar->LineColor = System::Drawing::Color::Black;
chartArea1->AxisY->ScrollBar->Size = 10;
chartArea1->CursorX->IntervalType = System::Windows::Forms::DataVisualization::Charting::DateTimeIntervalType::Seconds;
chartArea1->CursorX->IsUserEnabled = true;
chartArea1->CursorX->IsUserSelectionEnabled = true;
chartArea1->CursorY->IsUserEnabled = true;
chartArea1->CursorY->IsUserSelectionEnabled = true;
chartArea1->CursorY->LineColor = System::Drawing::Color::Blue;
chartArea1->Name = L"ChartArea1";
this->chartGraphForm->ChartAreas->Add(chartArea1);
this->chartGraphForm->Dock = System::Windows::Forms::DockStyle::Fill;
this->chartGraphForm->Location = System::Drawing::Point(0, 0);
this->chartGraphForm->Name = L"chartGraphForm";
series1->ChartArea = L"ChartArea1";
series1->ChartType = System::Windows::Forms::DataVisualization::Charting::SeriesChartType::Line;
series1->Name = L"Series1";
series1->ShadowOffset = 1;
this->chartGraphForm->Series->Add(series1);
this->chartGraphForm->Size = System::Drawing::Size(352, 329);
this->chartGraphForm->TabIndex = 0;
this->chartGraphForm->Text = L"chart1";
this->chartGraphForm->CursorPositionChanged += gcnew System::EventHandler<System::Windows::Forms::DataVisualization::Charting::CursorEventArgs^ >(this, &GraphForm::chartGraphForm_CursorPositionChanged);
this->chartGraphForm->Click += gcnew System::EventHandler(this, &GraphForm::chartGraphForm_Click);
this->chartGraphForm->KeyDown += gcnew System::Windows::Forms::KeyEventHandler(this, &GraphForm::chartGraphForm_KeyDown);
this->chartGraphForm->KeyUp += gcnew System::Windows::Forms::KeyEventHandler(this, &GraphForm::chartGraphForm_KeyUp);
//
// GraphForm
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(352, 329);
this->Controls->Add(this->chartGraphForm);
this->Name = L"GraphForm";
this->Text = L"GraphForm";
this->FormClosing += gcnew System::Windows::Forms::FormClosingEventHandler(this, &GraphForm::GraphForm_FormClosing);
this->Load += gcnew System::EventHandler(this, &GraphForm::GraphForm_Load);
(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->chartGraphForm))->EndInit();
this->ResumeLayout(false);
}
#pragma endregion
#pragma endregion
private: System::Void GraphForm_Load(System::Object^ sender, System::EventArgs^ e) {
GraphFormPtSer = chartGraphForm->Series[L"Series1"];
//threadDelegate
ThreadStart^ addDataThreadStart = gcnew ThreadStart(this, &GraphForm::AddDataThreadLoop);
this->addDataRunner = gcnew System::Threading::Thread(addDataThreadStart);
addDataDlg += gcnew AddDataDelegate(this, &GraphForm::AddData);
this->startTrending(nullptr, EventArgs::Empty);
myAnno = (gcnew System::Windows::Forms::DataVisualization::Charting::RectangleAnnotation());
myAnno->AllowMoving = true;
myAnno->Name = L"myAnno1";
myAnno->Text = L"Select and Reposition Me\\nusing the mouse";
myAnno->X = 0;
myAnno->Y = 0;
this->chartGraphForm->Annotations->Add(myAnno);
time_press_button = 0;//System::Environment::TickCount; // time in milliseconds
mult = 1;
chartGraphForm->Focus();
}
private: System::Void startTrending(System::Object^ sender, System::EventArgs^ e) {
// Predefine the viewing area of the chart
/* minValue = DateTime::Now;
maxValue = minValue->AddSeconds(30);
try {
chartGraphForm->ChartAreas[0]->AxisX->Minimum = minValue->ToOADate();
chartGraphForm->ChartAreas[0]->AxisX->Maximum = maxValue->ToOADate();
}
catch (Exception^ e) { MessageBox::Show(e->Message,"AxisXMinMaxValue"); }
if (MyFormPtSer->Points->Count > 0) {
array<double>^ MinMaxY = MyFormPtSer->Points[0]->YValues;
chartGraphForm->ChartAreas[0]->AxisY->Minimum = MinMaxY[0] - 0.5;
chartGraphForm->ChartAreas[0]->AxisY->Maximum = MinMaxY[0] + 0.5;
MinY = MinMaxY[0] - 0.5;
MaxY = MinMaxY[0] + 0.5;
}*/
/*// Reset number of series in the chart.
chartGraphForm->Series->Clear();
Series^ newSeries = gcnew Series("Series1");
newSeries->ChartType = SeriesChartType::Line;
newSeries->BorderWidth = 1;
newSeries->Color = Color::FromArgb(224, 64, 10);
newSeries->ShadowOffset = 1;
newSeries->XValueType = ChartValueType::DateTime;
chartGraphForm->Series->Add(newSeries);
chartGraphForm->Series[0]->Points->AddXY(0,10);
chartGraphForm->Invalidate();*/
// start worker threads.
if (addDataRunner->IsAlive == true) {
addDataRunner->Resume();
}
else {
this->addDataRunner->IsBackground = true;
this->addDataRunner->Start();
}
}
private: System::Void AddDataThreadLoop() {
try
{
while (true)
{
// Invoke method must be used to interact with the chart
// control on the form!
if (this->InvokeRequired) {
chartGraphForm->Invoke(addDataDlg);
}
// Thread is inactive for 2500ms
System::Threading::Thread::Sleep(2500);
}
}
catch (Exception^ e) { MessageBox::Show(e->Message, "AddDataThreadLoop"); }// Thread is aborted
}
public: System::Void AddData()
{
DateTime^ timeStamp = DateTime();
timeStamp = DateTime::Now;
for each(GraphFormPtSer in chartGraphForm->Series) { //series1->Name = L"Series1";
AddNewPoint(timeStamp, GraphFormPtSer);
}
}
public: System::Void AddNewPoint(DateTime^ timeStamp, Series^ ptSeries)
{
// Add new data point to its series.
if (ptSeries->Points->Count == 0) {
int pts_cnt = MyFormPtSer->Points->Count;
if (pts_cnt > 0) {
double x_val;
array<double>^ y_val;
for (int q = 0; q < pts_cnt; q++) {
x_val = MyFormPtSer->Points[q]->XValue;
y_val = MyFormPtSer->Points[q]->YValues;
try {ptSeries->Points->AddXY(x_val, y_val[0]);}
catch (Exception^ e) { MessageBox::Show(e->Message, "Add0XY"); }
}
}
/* for(int i = 0; i<2; i++)
ptSeries->Points->AddXY(timeStamp->AddSeconds(i), 23+i/10); //timeStamp->ToOADate()*/
} else {
//if (MyFormPtSer->Points->Count > 0) {
int lastPnt = MyFormPtSer->Points->Count - 1;
double x_val = MyFormPtSer->Points[lastPnt]->XValue;
array<double>^ y_val = MyFormPtSer->Points[lastPnt]->YValues;
try { ptSeries->Points->AddXY(x_val, y_val[0]); }
catch(Exception^ e){ MessageBox::Show(e->Message, "AddXY"); }
/*
if (y_val[0] < MinY) {
MinY = y_val[0] - 0.1;
chartGraphForm->ChartAreas[0]->AxisY->Minimum = MinY;
}
if (y_val[0] > MaxY) {
MaxY = y_val[0] + 0.1;
chartGraphForm->ChartAreas[0]->AxisY->Maximum = MaxY;
}*/
}
/*
// remove all points from the source series older than 20 seconds.
double removeBefore = timeStamp->AddSeconds((double)(20) * (-1)).ToOADate();
//remove oldest values to maintain a constant number of data points
while (ptSeries->Points[0]->XValue < removeBefore) {
try { ptSeries->Points->RemoveAt(0); }
catch (Exception^ e) { MessageBox::Show(e->Message, "Remove oldest value"); }
}
chartGraphForm->ChartAreas[0]->AxisX->Minimum = ptSeries->Points[0]->XValue;
chartGraphForm->ChartAreas[0]->AxisX->Maximum = DateTime::FromOADate(ptSeries->Points[0]->XValue).AddSeconds(30).ToOADate();
*/
chartGraphForm->Invalidate();
//chartGraphForm->Update();
//chartGraphForm->Refresh();
}
private: System::Void GraphForm_FormClosing(System::Object^ sender, System::Windows::Forms::FormClosingEventArgs^ e) {
this->Hide();
e->Cancel = true; //запрет ликвидации объекта
}
//[UIPermissionAttribute(SecurityAction::LinkDemand, Window = UIPermissionWindow::AllWindows)]
protected: virtual bool ProcessDialogKey(Keys keyData) override {
// Avoid dialog processing of arrow keys
if (keyData == Keys::Left || keyData == Keys::Right) {
return false;
}
//return this->ProcessDialogKey(keyData);
}
private: System::Void chartGraphForm_Click(System::Object^ sender, System::EventArgs^ e) {
// Set input focus to the chart control
chartGraphForm->Focus();
// set the selection start variable to that of the current position
this->SelectionStart = chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position;
/*DateTime^ timeStamp = DateTime();
double position = chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position;
timeStamp = DateTime::FromOADate(position);
myAnno->Text = timeStamp->ToString("dd MMM, hh:mm:ss");*/
/* rectangleAnnotation1->Text = L"Annotation Text";
Annotation^ annotation = (Annotation^)sender;
AnnotationX.Text = annotation.X.ToString("#.#");
AnnotationY.Text = annotation.Y.ToString("#.#");*/
}
private: System::Void ProcessSelect(System::Windows::Forms::KeyEventArgs^ e) {
// Process keyboard keys
if (e->KeyCode == Keys::Right)
{
// make sure the selection start value is assigned
if (this->SelectionStart == myNan)//
this->SelectionStart = chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position;
// set the new cursor position
chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position += chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Interval;
}
else if (e->KeyCode == Keys::Left)
{
// make sure the selection start value is assigned
if (this->SelectionStart == myNan)
this->SelectionStart = chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position;
// set the new cursor position
chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position -= chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Interval;
}
// if the cursor is outside the view, set the view
// such that the cursor can be seen
SetView();
chartGraphForm->ChartAreas["ChartArea1"]->CursorX->SelectionStart = this->SelectionStart;
chartGraphForm->ChartAreas["ChartArea1"]->CursorX->SelectionEnd = chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position;
}
private: System::Void SetView() {
// keep the cursor from leaving the max and min a axis points
if (chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position < 0)
chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position = 0;
else if (chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position > 75)
chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position = 75;
// move the view to keep the cursor visible
if (chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position < chartGraphForm->ChartAreas["ChartArea1"]->AxisX->ScaleView->Position)
chartGraphForm->ChartAreas["ChartArea1"]->AxisX->ScaleView->Position = chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position;
else if ((chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position >
(chartGraphForm->ChartAreas["ChartArea1"]->AxisX->ScaleView->Position + chartGraphForm->ChartAreas["ChartArea1"]->AxisX->ScaleView->Size)))
{
chartGraphForm->ChartAreas["ChartArea1"]->AxisX->ScaleView->Position =
(chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position - chartGraphForm->ChartAreas["ChartArea1"]->AxisX->ScaleView->Size);
}
}
private: System::Void ProcessScroll(System::Windows::Forms::KeyEventArgs^ e) {
// Process keyboard keys
int curr_tick = System::Environment::TickCount;
time_press_button = curr_tick - time_press_button; // time in milliseconds
if (time_press_button>500 && time_press_button<1000 && mult<30)//threshold
mult++;
DateTime^ timeStamp = DateTime();
double position = chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position;
if (double::IsNaN(position))
return;
timeStamp = DateTime::FromOADate(position);
if (e->KeyCode == Keys::Right) { // set the new cursor position
//chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position += chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Interval;
double intervalPlus = DateTime::FromOADate(position).AddSeconds((double)(mult)).ToOADate();
chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position = intervalPlus;//+= 0.000057870369;
}
else if (e->KeyCode == Keys::Left) { // set the new cursor position
//chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position -= chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Interval;
double intervalMinus = DateTime::FromOADate(position).AddSeconds((double)(mult)*(-1)).ToOADate();
chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position = intervalMinus;
}
/*position = chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position;
timeStamp = DateTime::FromOADate(position);*/
myAnno->Text = timeStamp->ToString("dd MMM, HH:mm:ss");
// if the cursor is outside the view, set the view such that the cursor can be seen
//SetView();
// set the selection start variable in case shift arrows are selected...
this->SelectionStart = chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position;
//reset the old selection start and end
chartGraphForm->ChartAreas["ChartArea1"]->CursorX->SelectionStart = myNan;
chartGraphForm->ChartAreas["ChartArea1"]->CursorX->SelectionEnd = myNan;
}
private: System::Void chartGraphForm_KeyDown(System::Object^ sender, System::Windows::Forms::KeyEventArgs^ e) {
if ((e->KeyCode == Keys::Right) || (e->KeyCode == Keys::Left))
{
// if the key event is shifted, process as a selection
if (e->Shift)
ProcessSelect(e);
else // process as a scroll
ProcessScroll(e);
}
// on enter, zoom the selection
else if (e->KeyCode == Keys::Enter)
{
double start, end;
if (chartGraphForm->ChartAreas["ChartArea1"]->CursorX->SelectionStart > chartGraphForm->ChartAreas["ChartArea1"]->CursorX->SelectionEnd)
{
start = chartGraphForm->ChartAreas["ChartArea1"]->CursorX->SelectionEnd;
end = chartGraphForm->ChartAreas["ChartArea1"]->CursorX->SelectionStart;
}
else
{
end = chartGraphForm->ChartAreas["ChartArea1"]->CursorX->SelectionEnd;
start = chartGraphForm->ChartAreas["ChartArea1"]->CursorX->SelectionStart;
}
// return if no selection actually made
if (start == end)
return;
// zoom the selection
chartGraphForm->ChartAreas["ChartArea1"]->AxisX->ScaleView->Zoom(start, (end - start), DateTimeIntervalType::Number, true);
// reset selection values
this->SelectionStart = chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position;
chartGraphForm->ChartAreas["ChartArea1"]->CursorX->SelectionStart = myNan;
chartGraphForm->ChartAreas["ChartArea1"]->CursorX->SelectionEnd = myNan;
}
else if (e->KeyCode == Keys::Back)
{
// reset zoom back to previous view state
chartGraphForm->ChartAreas["ChartArea1"]->AxisX->ScaleView->ZoomReset(1);
// reset selection values
this->SelectionStart = chartGraphForm->ChartAreas["ChartArea1"]->CursorX->Position;
chartGraphForm->ChartAreas["ChartArea1"]->CursorX->SelectionStart = myNan;
chartGraphForm->ChartAreas["ChartArea1"]->CursorX->SelectionEnd = myNan;
}
}
private: System::Void chartGraphForm_KeyUp(System::Object^ sender, System::Windows::Forms::KeyEventArgs^ e) {
if (e->Shift)
{
chartGraphForm_KeyDown(sender, e);
}
time_press_button = 0;
mult = 1;
}
private: System::Void SetPosition(Axis^ axis, double position) {
if (double::IsNaN(position))
return;
if (axis->AxisName == AxisName::X) {
// Convert Double to DateTime.
DateTime^ dateTimeX = DateTime::FromOADate(position);
// Set X cursor position to edit Control
//CursorX.Text = dateTimeX.ToString("ddd, dd MMM");
myAnno->Text = dateTimeX->ToString("dd MMM, HH:mm:ss");
}
else {
// Set Y cursor position to edit Control
//CursorY.Text = position.ToString();
}
}
private: System::Void chartGraphForm_CursorPositionChanged(System::Object^ sender, System::Windows::Forms::DataVisualization::Charting::CursorEventArgs^ e) {
SetPosition(e->Axis, e->NewPosition);
}
};
}
#include "MyForm.h"
using namespace System;
using namespace System::Windows::Forms;
using namespace TermGraph;
[STAThreadAttribute]
void main(array<String ^> ^args)
{
// Включение визуальных эффектов Windows XP до создания каких-либо элементов управления
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
//Ter
// Создание главного окна и его запуск
//Application::Run(gcnew MyForm());
TermGraph::MyForm formo4ka;
Application::Run(%formo4ka);
}
#pragma once
#include "setupComPortForm.h"
#include "var_glb.h"
#include "GraphForm.h"
//WinSamplesChart\WorkingWithData\RealTimeData\RealTimeThread\RealTimeSample.cs
//WinSamplesChart\ChartTypes\LineCharts\FastLine\FastLineChartType.cs
namespace TermGraph {
#pragma region namespace,private,protected,WFDgen code, etc...
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::IO;
using namespace System::Xml;
/// <summary>
/// Сводка для MyForm
/// </summary>
public ref class MyForm : public System::Windows::Forms::Form
{
public:
MyForm(void)
{
InitializeComponent();
//
//TODO: добавьте код конструктора
//
checkFlag = false;//флаг на НЕ усыпление потока чтения СОМ порта
rwFlag = true;
//************************************//
// Initialize an instance of the //
// Second Form //
//************************************//
//COMPortForm = gcnew setupComPortForm(comPort);
//******************************************//
// Set UpdateTextControl as the event //
// handler. The UpdateTextControl //
// function should be of the same //
// type as the CustomEventsHandler //
// function defined as delegate in //
// Second_Form.h: //
// 1st arg. of type System::Object^ //
// 2nd arg. of type CustomEvents_EventArgs^ //
//******************************************//
/*COMPortForm->UpdateTextControl +=
gcnew setupComPortForm::CustomEventsHandler(
this, &MyForm::UpdateControl);*/
}
protected:
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
~MyForm()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::MenuStrip^ menuStrip1;
private: System::Windows::Forms::ToolStripMenuItem^ setupToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^ serialPortToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^ fileToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^ GraphToolStripMenuItem;
private: System::Windows::Forms::TextBox^ terminalTextBox;
private: IO::Ports::SerialPort^ comPort;
private: Threading::Thread^ readThread; //доп поток для чтения с COM порта
private: bool checkFlag; //управление потоком true=усыпление
private: bool rwFlag; //флаг чтения/записи true=чтение
//************************************//
// COMPortForm is a member of the //
// main form (MyForm) //
//************************************//
private: setupComPortForm^ COMPortForm;
GraphForm^ graphForm;
System::Windows::Forms::DataVisualization::Charting::Chart^ chart1;
DateTime^ timeStamp;
System::ComponentModel::IContainer^ components;
System::Windows::Forms::DataVisualization::Charting::Series^ ptSeries;
/// <summary>
/// Обязательная переменная конструктора.
/// </summary>
#pragma region Windows Form Designer generated code
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
void InitializeComponent(void)
{
this->menuStrip1 = (gcnew System::Windows::Forms::MenuStrip());
this->setupToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->serialPortToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->fileToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->GraphToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->terminalTextBox = (gcnew System::Windows::Forms::TextBox());
this->menuStrip1->SuspendLayout();
this->SuspendLayout();
//
// menuStrip1
//
this->menuStrip1->Items->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^ >(2) {
this->setupToolStripMenuItem,
this->fileToolStripMenuItem
});
this->menuStrip1->Location = System::Drawing::Point(0, 0);
this->menuStrip1->Name = L"menuStrip1";
this->menuStrip1->Padding = System::Windows::Forms::Padding(7, 2, 0, 2);
this->menuStrip1->Size = System::Drawing::Size(339, 24);
this->menuStrip1->TabIndex = 0;
this->menuStrip1->Text = L"menuStrip1";
//
// setupToolStripMenuItem
//
this->setupToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^ >(1) { this->serialPortToolStripMenuItem });
this->setupToolStripMenuItem->Name = L"setupToolStripMenuItem";
this->setupToolStripMenuItem->Size = System::Drawing::Size(49, 20);
this->setupToolStripMenuItem->Text = L"&Setup";
//
// serialPortToolStripMenuItem
//
this->serialPortToolStripMenuItem->Name = L"serialPortToolStripMenuItem";
this->serialPortToolStripMenuItem->Size = System::Drawing::Size(136, 22);
this->serialPortToolStripMenuItem->Text = L"Serial port...";
this->serialPortToolStripMenuItem->Click += gcnew System::EventHandler(this, &MyForm::serialPortToolStripMenuItem_Click);
//
// fileToolStripMenuItem
//
this->fileToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^ >(1) { this->GraphToolStripMenuItem });
this->fileToolStripMenuItem->Name = L"fileToolStripMenuItem";
this->fileToolStripMenuItem->Size = System::Drawing::Size(63, 20);
this->fileToolStripMenuItem->Text = L"&Window";
//
// GraphToolStripMenuItem
//
this->GraphToolStripMenuItem->Name = L"GraphToolStripMenuItem";
this->GraphToolStripMenuItem->Size = System::Drawing::Size(106, 22);
this->GraphToolStripMenuItem->Text = L"&Graph";
this->GraphToolStripMenuItem->Click += gcnew System::EventHandler(this, &MyForm::GraphToolStripMenuItem_Click);
//
// terminalTextBox
//
this->terminalTextBox->BackColor = System::Drawing::SystemColors::Desktop;
this->terminalTextBox->BorderStyle = System::Windows::Forms::BorderStyle::None;
this->terminalTextBox->Dock = System::Windows::Forms::DockStyle::Fill;
this->terminalTextBox->Font = (gcnew System::Drawing::Font(L"Consolas", 11.25F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(204)));
this->terminalTextBox->ForeColor = System::Drawing::SystemColors::ScrollBar;
this->terminalTextBox->Location = System::Drawing::Point(0, 24);
this->terminalTextBox->Multiline = true;
this->terminalTextBox->Name = L"terminalTextBox";
this->terminalTextBox->ReadOnly = true;
this->terminalTextBox->ScrollBars = System::Windows::Forms::ScrollBars::Vertical;
this->terminalTextBox->Size = System::Drawing::Size(339, 198);
this->terminalTextBox->TabIndex = 1;
//
// MyForm
//
this->AutoScaleDimensions = System::Drawing::SizeF(7, 11);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(339, 222);
this->Controls->Add(this->terminalTextBox);
this->Controls->Add(this->menuStrip1);
this->Font = (gcnew System::Drawing::Font(L"Lucida Console", 8.25F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(204)));
this->ForeColor = System::Drawing::SystemColors::ControlDark;
this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::Fixed3D;
this->MainMenuStrip = this->menuStrip1;
this->Name = L"MyForm";
this->Text = L"MyForm";
this->FormClosing += gcnew System::Windows::Forms::FormClosingEventHandler(this, &MyForm::MyForm_FormClosing);
this->Load += gcnew System::EventHandler(this, &MyForm::MyForm_Load);
this->menuStrip1->ResumeLayout(false);
this->menuStrip1->PerformLayout();
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
#pragma endregion
private: System::Void MyForm_Load(System::Object^ sender, System::EventArgs^ e) {
this->comPort = gcnew IO::Ports::SerialPort();
this->comPort->ErrorReceived +=
gcnew System::IO::Ports::SerialErrorReceivedEventHandler(
this, &MyForm::serialPort_ErrorReceived);
COMPortForm = gcnew setupComPortForm(comPort);
COMPortForm->UpdateTextControl +=
gcnew setupComPortForm::CustomEventsHandler(this, &MyForm::UpdateControl);
this->ptSeries = gcnew System::Windows::Forms::DataVisualization::Charting::Series;
this->readThread = gcnew Threading::Thread(
gcnew Threading::ThreadStart(this, &MyForm::readThreadHandler));
this->readThread->IsBackground = true;
this->readThread->Start();
if (!comPort->IsOpen)
this->Text = L"Terminal - [disconnected]";//MyForm::Text =
this->COMPortForm->setupComPortForm_Load(this); //auto connect
}
private: System::Void MyForm_FormClosing(System::Object^ sender, System::Windows::Forms::FormClosingEventArgs^ e) {
readThread->Abort();
SavePropsXml();
if (comPort->IsOpen)
comPort->Close();
//delete comPort;
}
private: delegate void applyAnswDelegate(String^ s);
private: System::Void applyAnsw(String^ str_dat) { //вывод вх данных на консоль и заполнение массива температур
if (this->InvokeRequired) {
applyAnswDelegate^ aad = gcnew applyAnswDelegate(this, &MyForm::applyAnsw);
this->BeginInvoke(aad, str_dat);
}
else {
if (!checkFlag) rwFlag = true;
this->terminalTextBox->AppendText(">> " + str_dat);
//start_SetRes complete_SetRes T = 22.75*C incoming messages
array<Char>^chars = { 'c','C','o','m','p','l','s','S','t','T','a','r','R','e','*','_','=','\r','\n',' ' };
array<String^>^splt = str_dat->Split(chars, StringSplitOptions::RemoveEmptyEntries);
if (splt->Length != 0) {
//if (splt[0] != "") {
Double Y;
try { Y = Convert::ToDouble(splt[0]); }
catch (Exception^ e) { MessageBox::Show(e->Message); }
timeStamp = DateTime::Now;
ptSeries->Points->AddXY(timeStamp->ToOADate(), Y);
//}
}
//this->terminalTextBox->AppendText("\r\n");
}
}
private: System::Void readThreadHandler() //чтение данных из ком порта
{
String^ COMPortRdBuf = "";
while (true)
{
try {
if (comPort->IsOpen)//COM порт открыт
{
if (checkFlag) { //флаг на усыпление потока
Threading::Thread::Sleep(Threading::Timeout::Infinite);
}
COMPortRdBuf = comPort->ReadExisting();
if (COMPortRdBuf->Length > 0) { //если что-то прочитано
this->applyAnsw(COMPortRdBuf);
}
/* if (this->Text != comPort->PortName + ":"+ comPort->BaudRate + "baud - Terminal")
setMyFormHeadText(comPort->PortName + ":" + comPort->BaudRate + "baud - Terminal");*/
}
/*else { //COM порт закрыт //MyForm::Text this->Text
if(MyForm::Text != "Terminal - [disconnected]") //ест оперативную память
setMyFormHeadText("Terminal - [disconnected]");
} */
Threading::Thread::Sleep(250);
}
catch (Threading::ThreadInterruptedException^) { //обработка выхода из сна (Interrupt)
checkFlag = false;
}
catch (TimeoutException^) { //если чтение затягивается
applyAnsw("Закончено время ожидания данных из COM порта");
}
}
}
private: System::Void serialPort_ErrorReceived(System::Object^ sender, System::IO::Ports::SerialErrorReceivedEventArgs^ e) {
this->Text = L"Terminal - [disconnected]";
MessageBox::Show(L"Ошибка COM порта.\r\n" + e, "COM порт", MessageBoxButtons::OK, MessageBoxIcon::Error);
}
private: delegate void setHeadDlgt(String^ value);
public: System::Void setMyFormHeadText(String^ str_head) {
if (InvokeRequired) {
setHeadDlgt^ sdd = gcnew setHeadDlgt(this, &MyForm::setMyFormHeadText);
this->Invoke(sdd, str_head);
}
else {
this->Text = str_head;//MyForm::Text
}
}
private: System::Void serialPortToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
/* if (COMPortForm->WindowState == FormWindowState::Minimized)
{
COMPortForm->WindowState = FormWindowState::Normal; // if Second Form was minimized, first resize it
COMPortForm->Visible = true; // and make sure it's visible
}
else
COMPortForm->Visible = !(COMPortForm->Visible);*/
COMPortForm->Show();
}
//*****************************************************//
// Finally the event handler.
// Notice the following: 1st arg. of type System::Object^
// 2nd arg. of type CustomEvents_EventArgs^
// Conforming the delegate.
//******************************************************//
private: System::Void UpdateControl(System::Object^ sender, CustomEvents_EventArgs^ e) {
this->Text = e->TextControlText();
}
private: System::Void GraphToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
if (graphForm != nullptr) {
if (graphForm->WindowState == FormWindowState::Minimized)
{
graphForm->WindowState = FormWindowState::Normal; // if Second Form was minimized, first resize it
graphForm->Visible = true; // and make sure it's visible
}
else
graphForm->Visible = !(graphForm->Visible);
//graphForm->Show();
return;
}
else {
graphForm = gcnew GraphForm(ptSeries);//comPort
// Set Inside the Parent Form of the Child window.
//GraphForm->MdiParent = this;
graphForm->Show();// Display the new form.
}
}
private: System::Void SavePropsXml() {
if ((!comPort->IsOpen)||(comPort==nullptr))
return;
FileStream ^ fs = nullptr;
String^ xpath = Application::StartupPath + "\\Settings.xml";
XmlDocument^ doc = gcnew XmlDocument();
try { doc->Load(xpath); }
catch (Exception^ ex) {
//MessageBox::Show("Load: " + ex->Message, "SavePropsXml");
}
try {
fs = gcnew FileStream(xpath, FileMode::OpenOrCreate,
FileAccess::ReadWrite, FileShare::ReadWrite);
}
catch (IOException^ ex) {
MessageBox::Show("io: " + ex->Message, "SavePropsXml");
return;
}
catch (Exception^ ex) {
MessageBox::Show("fs: " + ex->Message, "SavePropsXml");
}
XmlWriterSettings^ xmlWrSett = gcnew XmlWriterSettings();
xmlWrSett->CloseOutput = true;
xmlWrSett->Encoding->UTF8; //кодировка для шапки
xmlWrSett->Indent = true; //добавляет отступы(табуляцию)
XmlWriter^ xmlWriter = XmlWriter::Create(fs, xmlWrSett);
//xmlWriter->WriteProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
xmlWriter->WriteStartDocument();//создает строку-шапку: <?xml version="1.0" encoding="utf-8"?>
xmlWriter->WriteComment("Do not edit this file!");
xmlWriter->WriteStartElement(L"Settings");
if (doc->HasChildNodes) {
String^ txt = " ";
String^ str = "";
XmlNode^ pNode;
System::Collections::Generic::List<String^>^ lines = gcnew System::Collections::Generic::List<String^>();
for (int i = 0; i<doc->ChildNodes->Count; i++) {
if (doc->ChildNodes[i]->Name == L"Settings") //Поиск корневого узла по имени
pNode = doc->ChildNodes[i];
}
if (pNode->HasChildNodes) { //переход к первым дочерним узлам корневого узла и затем перебор дочерних узлов данного узла, если они существуют.
for (int i = 0; i<pNode->ChildNodes->Count; i++) {
/*if (pNode->ChildNodes[i]->Name == L"CalibPath") {
txt = pNode->ChildNodes[i]->InnerText;
lines->Add(txt);
if (openFileDialog1->FileName != "" && openFileDialog1->CheckFileExists) {
xmlWriter->WriteElementString(L"CalibPath", openFileDialog1->FileName);
lines->Add(openFileDialog1->FileName);
}
else if (txt->Length == 0)
xmlWriter->WriteElementString(L"CalibPath", "");
else {
xmlWriter->WriteElementString(L"CalibPath", txt);
lines->Add(txt);
}
}*/
if (pNode->ChildNodes[i]->Name == L"ComPort") { //Поиск узла по имени
txt = pNode->ChildNodes[i]->InnerText;
if (txt != comPort->PortName) {//if (comPort->IsOpen) {
xmlWriter->WriteElementString(L"ComPort", comPort->PortName);
lines->Add(comPort->PortName);
}
else if (txt->Length == 0)
xmlWriter->WriteElementString(L"ComPort", "");
else {
xmlWriter->WriteElementString(L"ComPort", txt);
lines->Add(txt);//пишем в файл то что было до этого
}
}
if (pNode->ChildNodes[i]->Name == L"BoudRate") { //Поиск узла по имени
txt = pNode->ChildNodes[i]->InnerText;
String ^ bRate = Convert::ToString(comPort->BaudRate);
if (txt != bRate) {//if (comPort->IsOpen) {
xmlWriter->WriteElementString(L"BoudRate", bRate);
lines->Add(bRate);
}
else if (txt->Length == 0)
xmlWriter->WriteElementString(L"BoudRate", "");
else {
xmlWriter->WriteElementString(L"BoudRate", txt);
lines->Add(txt);//пишем в файл то что было до этого
}
}
/* if (pNode->ChildNodes[i]->Name == L"ViSigGen") {
txt = pNode->ChildNodes[i]->InnerText;
if (!lines->Contains(txt)) { //проверяем на отсутвие во вновь записаном файле ранее сделаную запись...
xmlWriter->WriteElementString(L"ViSigGen", txt);//записываем устр-во в файл
lines->Add(txt); //добавляем то, что уже записали в файл
}
if (sgDevice->vs != VI_NULL) { //если устр-во присутствует
str = charToString(sgDevice->devAlias);
if (!lines->Contains(str)) { //проверяем на отсутвие во вновь записаном файле...
xmlWriter->WriteElementString(L"ViSigGen", str); // и записываем в файл, если устр-во новое
lines->Add(str);
}
}
if (txt->Length == 0)
xmlWriter->WriteElementString(L"ViSigGen", "");
}*/
} //for
}
else {
xmlWriter->WriteElementString(L"ComPort", "");
xmlWriter->WriteElementString(L"BoudRate", "");
}
} //if (doc->HasChildNodes)
else { // в случае создания нового файла
/* if (openFileDialog1->FileName != "" && openFileDialog1->CheckFileExists) {
xmlWriter->WriteElementString(L"CalibPath", openFileDialog1->FileName);
}
else
xmlWriter->WriteElementString(L"CalibPath", "");*/
/////////////////////
if (comPort->IsOpen) {
xmlWriter->WriteElementString(L"ComPort", comPort->PortName);
}
else
xmlWriter->WriteElementString(L"ComPort", "");
/////////////////////
if (comPort->IsOpen) {
xmlWriter->WriteElementString(L"BoudRate", Convert::ToString(comPort->BaudRate));
}
else
xmlWriter->WriteElementString(L"BoudRate", "");
/////////////////////
/* if (sgDevice->vs != VI_NULL) { //если устр-во присутствует
String^ str = charToString(sgDevice->devAlias);
xmlWriter->WriteElementString(L"ViSigGen", str); //записываем в файл новое устр-во
}
else
xmlWriter->WriteElementString(L"ViSigGen", "");
/////////////////////
if (pmDevice->vs != VI_NULL) {
String^ str = charToString(pmDevice->devAlias);
xmlWriter->WriteElementString(L"ViPowMet", str);
}
else
xmlWriter->WriteElementString(L"ViPowMet", "");
/////////////////////
if (pmVxiDevice->sid != VI_NULL) {
String^ str = charToString(pmVxiDevice->devAlias);
xmlWriter->WriteElementString(L"VxiPowMet", str);
}
else
xmlWriter->WriteElementString(L"VxiPowMet", "");*/
}
xmlWriter->WriteEndElement(); //пишет </Settings> или <Settings />
try { xmlWriter->Flush(); }
catch (Exception^ ex) {}
xmlWriter->Close();
}
};
}
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by TermGraph.rc
// Следующие стандартные значения для новых объектов
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
#include "setupComPortForm.h"
#pragma once
#include "var_glb.h"
#ifndef setupComPortForm_h_
#define setupComPortForm_h_
#endif
namespace TermGraph {
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::IO;
using namespace System::Xml;
/// <summary>
/// Сводка для setupComPortForm
/// </summary>
#pragma region private,protected,WFDgen code, etc...
public ref class setupComPortForm : public System::Windows::Forms::Form
{
//************************************//
// Define delegate and event of the //
// delegate type //
//*************************************//
//add a delegate
public: delegate void CustomEventsHandler(System::Object^ sender, CustomEvents_EventArgs^ e); // this is the reason I needed the forward class declaration
//add an event of the delegate type
public: event CustomEventsHandler^ UpdateTextControl;
public: //create parameterized constructor _comPort
setupComPortForm(IO::Ports::SerialPort^ _comPort)
{
InitializeComponent();
//
//TODO: добавьте код конструктора
//
comPort = _comPort;
}
protected:
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
~setupComPortForm()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::ComboBox^ setupSelectCOM;
private: System::Windows::Forms::Label^ setupCOMPortLbl;
private: System::Windows::Forms::Label^ setupBaudRateLbl;
private: System::Windows::Forms::ComboBox^ setupBaudRate;
private: System::Windows::Forms::Button^ setupConnectCOM;
private: IO::Ports::SerialPort^ comPort;
private: System::Windows::Forms::Form^ mainForm;
//private: GlobalVariables^ glb_COMname;
protected:
private:
/// <summary>
/// Обязательная переменная конструктора.
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
void InitializeComponent(void)
{
this->setupSelectCOM = (gcnew System::Windows::Forms::ComboBox());
this->setupCOMPortLbl = (gcnew System::Windows::Forms::Label());
this->setupBaudRateLbl = (gcnew System::Windows::Forms::Label());
this->setupBaudRate = (gcnew System::Windows::Forms::ComboBox());
this->setupConnectCOM = (gcnew System::Windows::Forms::Button());
this->SuspendLayout();
//
// setupSelectCOM
//
this->setupSelectCOM->FormattingEnabled = true;
this->setupSelectCOM->Items->AddRange(gcnew cli::array< System::Object^ >(2) { L"COM1", L"COM2" });
this->setupSelectCOM->Location = System::Drawing::Point(151, 12);
this->setupSelectCOM->Name = L"setupSelectCOM";
this->setupSelectCOM->Size = System::Drawing::Size(121, 21);
this->setupSelectCOM->TabIndex = 0;
this->setupSelectCOM->DropDown += gcnew System::EventHandler(this, &setupComPortForm::setupSelectCOM_DropDown);
//
// setupCOMPortLbl
//
this->setupCOMPortLbl->AutoSize = true;
this->setupCOMPortLbl->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 9));
this->setupCOMPortLbl->ImeMode = System::Windows::Forms::ImeMode::NoControl;
this->setupCOMPortLbl->Location = System::Drawing::Point(12, 13);
this->setupCOMPortLbl->Name = L"setupCOMPortLbl";
this->setupCOMPortLbl->Size = System::Drawing::Size(32, 15);
this->setupCOMPortLbl->TabIndex = 50;
this->setupCOMPortLbl->Text = L"Port:";
//
// setupBaudRateLbl
//
this->setupBaudRateLbl->AutoSize = true;
this->setupBaudRateLbl->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 9));
this->setupBaudRateLbl->ImeMode = System::Windows::Forms::ImeMode::NoControl;
this->setupBaudRateLbl->Location = System::Drawing::Point(12, 46);
this->setupBaudRateLbl->Name = L"setupBaudRateLbl";
this->setupBaudRateLbl->Size = System::Drawing::Size(68, 15);
this->setupBaudRateLbl->TabIndex = 50;
this->setupBaudRateLbl->Text = L"Baud Rate:";
//
// setupBaudRate
//
this->setupBaudRate->FormattingEnabled = true;
this->setupBaudRate->Items->AddRange(gcnew cli::array< System::Object^ >(2) { L"9600", L"115200" });
this->setupBaudRate->Location = System::Drawing::Point(151, 46);
this->setupBaudRate->Name = L"setupBaudRate";
this->setupBaudRate->Size = System::Drawing::Size(121, 21);
this->setupBaudRate->TabIndex = 51;
//
// setupConnectCOM
//
this->setupConnectCOM->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
this->setupConnectCOM->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 9, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(204)));
this->setupConnectCOM->ImeMode = System::Windows::Forms::ImeMode::NoControl;
this->setupConnectCOM->Location = System::Drawing::Point(178, 76);
this->setupConnectCOM->Name = L"setupConnectCOM";
this->setupConnectCOM->Size = System::Drawing::Size(94, 31);
this->setupConnectCOM->TabIndex = 52;
this->setupConnectCOM->Text = L"Connect";
this->setupConnectCOM->UseVisualStyleBackColor = true;
this->setupConnectCOM->Click += gcnew System::EventHandler(this, &setupComPortForm::setupConnectCOM_Click);
//
// setupComPortForm
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(284, 119);
this->Controls->Add(this->setupConnectCOM);
this->Controls->Add(this->setupBaudRate);
this->Controls->Add(this->setupBaudRateLbl);
this->Controls->Add(this->setupCOMPortLbl);
this->Controls->Add(this->setupSelectCOM);
this->MaximizeBox = false;
this->MinimizeBox = false;
this->Name = L"setupComPortForm";
this->Text = L"Terminal: Serial Port Setup";
this->FormClosing += gcnew System::Windows::Forms::FormClosingEventHandler(this, &setupComPortForm::setupComPortForm_FormClosing);
this->Load += gcnew System::EventHandler(this, &setupComPortForm::setupComPortForm_Load);
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion WFDesigner generated code
#pragma endregion namespace and etc
private: System::Void setupComPortForm_Load(System::Object^ sender, System::EventArgs^ e) {
setupSelectCOM->Items->Clear();
setupSelectCOM->Items->AddRange(IO::Ports::SerialPort::GetPortNames());
try { setupSelectCOM->SelectedIndex = 0; }//error if comport doesnt exist in OS
catch (Exception^) {
MessageBox::Show("Отсутствует COM порт в системе", "COM порт",
MessageBoxButtons::OK, MessageBoxIcon::Information);
}
if (comPort->IsOpen)
this->setupConnectCOM->Text = "Disconnect";
setupBaudRate->SelectedIndex = 0;
//LoadProps();
LoadPropsXml();
}
private: System::Void setupSelectCOM_DropDown(System::Object^ sender, System::EventArgs^ e) {
/*UseWaitCursor = true;
System::Windows::Forms::Cursor::Current = Cursors::WaitCursor;*/
setupSelectCOM->Items->Clear();
setupSelectCOM->Items->AddRange(IO::Ports::SerialPort::GetPortNames());
// setupSelectCOM->SelectedIndex=0;
/*System::Windows::Forms::Cursor::Current = Cursors::Arrow;
UseWaitCursor = false;*/
}
private: System::Void setupConnectCOM_Click(System::Object^ sender, System::EventArgs^ e) {
if (setupConnectCOM->Text == "Connect")
{
comPort->Close();
comPort->PortName = setupSelectCOM->Text;
comPort->BaudRate = Convert::ToInt32(setupBaudRate->Text);
try {
comPort->Open();
}
catch (Exception^ e) {
MessageBox::Show("Ошибка при открытии COM порта.\r\nCOM порт недоступен.\r\n" + e->Message,
"COM порт", MessageBoxButtons::OK, MessageBoxIcon::Error);
return;
}
if (comPort->IsOpen)
{
comPort->ReadTimeout = 5000;
setupConnectCOM->Text = "Disconnect";
CustomEvents_EventArgs^ args = gcnew CustomEvents_EventArgs((System::String^)comPort->PortName + ":" + comPort->BaudRate + "baud - Terminal");
UpdateTextControl(this, args);
}
else {
MessageBox::Show("Ошибка при открытии COM порта.\r\nПроверьте настройки и попробуйте снова.",
"COM порт", MessageBoxButtons::OK, MessageBoxIcon::Error);
}
}
else { //disconnect com port
try {
if (comPort->IsOpen)
comPort->Close();
}
catch (Exception^) {
MessageBox::Show("Ошибка при открытии COM порта.", "COM порт",
MessageBoxButtons::OK, MessageBoxIcon::Error);
}
if (!comPort->IsOpen) {
this->setupConnectCOM->Text = "Connect";
CustomEvents_EventArgs^ args = gcnew CustomEvents_EventArgs("Terminal - [disconnected]");
UpdateTextControl(this, args);
}
}
}
private: System::Void setupComPortForm_FormClosing(System::Object^ sender, System::Windows::Forms::FormClosingEventArgs^ e) {
this->Hide();
e->Cancel = true;
//SaveProps();
}
private: System::Void SaveProps()
{
System::Collections::Generic::List<String^>^ lines = gcnew System::Collections::Generic::List<String^>();
String^ str = "";
String^ xpath = Application::StartupPath + "\\settings.cfg";
if (IO::File::Exists(xpath))
{
FileInfo^ fi1 = gcnew FileInfo(xpath);
if (fi1->Length == 0) { //если файл пустой
lines->Add("");
}
IO::StreamReader^ sr = gcnew IO::StreamReader(xpath);
while ((str = sr->ReadLine()) != nullptr) {
lines->Add(str);
}
/* if ((str = sr->ReadLine()) == nullptr) {
lines->Add("");
}*/
sr->Close();
delete sr;
}
else { //если файл отсутствует
lines->Add("");
}
if (comPort->IsOpen) {
IO::StreamWriter^ sw = gcnew IO::StreamWriter(xpath);
if( (lines[0]!=comPort->PortName)||(lines[1]!=Convert::ToString(comPort->BaudRate)) ) {
sw->WriteLine(comPort->PortName);
sw->WriteLine(Convert::ToString(comPort->BaudRate));
sw->Flush();
}
else if (lines[0]->Length == 0) {
sw->WriteLine("");
sw->Flush();
}
/*else {
sw->WriteLine(lines[0]);
sw->WriteLine(lines[1]);
}*/
/* for (int i = 2; i < lines->Count; i++)
sw->WriteLine(lines[i]);*/
//sw->Flush();
sw->Close();
delete sw;
}
}
private: System::Void LoadProps()
{
String^ xpath = Application::StartupPath + "\\settings.cfg";
if (IO::File::Exists(xpath))
{
IO::StreamReader^ sr = gcnew IO::StreamReader(xpath);
if (sr->EndOfStream) //если файл пустой
{
sr->Close();
delete sr;
return;
}
String^ str = sr->ReadLine();
if (setupSelectCOM->Items->Contains(str))
setupSelectCOM->SelectedItem = str;
str = sr->ReadLine();
if (setupBaudRate->Items->Contains(str))
setupBaudRate->SelectedItem = str;
sr->Close();
delete str;
delete sr;
}
}
private: System::Void LoadPropsXml() {
String^ xpath = Application::StartupPath + "\\Settings.xml";
String^ fileName = "";
FileStream^ fs = gcnew FileStream(xpath, FileMode::OpenOrCreate,
FileAccess::Read, FileShare::Read);
XmlReader^ reader = XmlReader::Create(fs);
try { reader->ReadToDescendant("Settings"); }
catch (Exception^ ex) {
//MessageBox::Show(ex->Message + " Settings","LoadPropsXml");
reader->Close();
fs->Close();
delete reader;
delete fs;
return;
}
XmlReader^ inner = reader->ReadSubtree();
while (inner->Read())
{
switch (inner->NodeType) {
case XmlNodeType::Element:
/* if (inner->Name == "CalibPath") {
inner->Read();
if (inner->NodeType == XmlNodeType::Text) {
fileName = inner->Value;
inner->Skip();
inner->Skip();
}
}*/
if (inner->Name == "ComPort") {
inner->Read();
if (inner->NodeType == XmlNodeType::Text) {
String^ port = inner->Value;
if (setupSelectCOM->Items->Contains(port))
setupSelectCOM->SelectedItem = port;
inner->Skip();
inner->Skip();
}
}
if (inner->Name == "BoudRate") {
inner->Read();
if (inner->NodeType == XmlNodeType::Text) {
String^ rate = inner->Value;
if (setupBaudRate->Items->Contains(rate))
setupBaudRate->SelectedItem = rate;
inner->Skip();
inner->Skip();
}
}
/* if (inner->Name == "ViSigGen") {
inner->Read();
if (inner->NodeType == XmlNodeType::Text) {
String^ vi_sg = inner->Value;
if (!installDevAddr->Items->Contains(vi_sg))
installDevAddr->Items->Add(vi_sg);
inner->Skip();
inner->Skip();
}
}
if (inner->Name == "ViPowMet") {
inner->Read();
if (inner->NodeType == XmlNodeType::Text) {
String^ vi_pm = inner->Value;
if (!installDevAddr->Items->Contains(vi_pm))
installDevAddr->Items->Add(vi_pm);
inner->Skip();
inner->Skip();
}
}
if (inner->Name == "VxiPowMet") {
inner->Read();
if (inner->NodeType == XmlNodeType::Text) {
String^ vxi_pm = inner->Value;
if (!installVxiAddr->Items->Contains(vxi_pm))
installVxiAddr->Items->Add(vxi_pm);
inner->Skip();
inner->Skip();
}
}*/
break;
default:
break;
}
}//while (inner->Read())
reader->Close();
fs->Close();
delete reader;
delete fs;
}
};
}
#pragma once
namespace TermGraph
{
using namespace System;
public ref class GlobalVariables
{
public: String^ COM_name;
//public: bool checkFlag;
};
//************************************//
// Need to do a forward declaration //
// since this class will be used in //
// class 'Second_Form'. Visual Studio //
// Designer expects the 'Second_Form' //
// class to be the first class //
// definition. //
//************************************//
ref class CustomEvents_EventArgs;
//**************************************//
// This class defines the arguments that will be send by the event
// (The designer of visual studio expects the Form class as the first
// class in this header, so I put a forward declaration in the
// beginning since the class is referenced to in the 'SecondForm' class)
//**************************************//
public ref class CustomEvents_EventArgs : public System::EventArgs
{
//add local members
private: System::String^ m_TextControlText;
//class constructor
public: CustomEvents_EventArgs(System::String^ m_Text)
{
m_TextControlText = m_Text;
}
//properties - viewable by each listener
public: String^ TextControlText(System::Void)
{
return m_TextControlText;
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment