📄 terminal.cpp
字号:
/**************************************************************************
Project: WinAVRIDE Class: Terminal Form
Copyright (C) 2005 Philipp Schober
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
History
19.Feb 2005 - First Release (V1.0)
****************************************************************************/
#include <vcl.h>
#pragma hdrstop
#include "Terminal.h"
#include "PortSettings.h"
#include "Programmer.h"
#include "FileTrans.h"
#define MAX_ROWLEN 18
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "PSLed"
#pragma resource "*.dfm"
TTermForm *TermForm;
//---------------------------------------------------------------------------
__fastcall TTermForm::TTermForm(TComponent* Owner)
: TForm(Owner)
{
position.col = 0;
position.row = 0;
crlf = true;
Comm = new TRS232Comm (this);
Comm->OnRxChar = OnRxData;
Comm->InQSize = 1024;
Comm->OutQSize = 1024;
Comm->BaudRate = 9600;
Comm->DataBits = 8;
Comm->Parity = 'N';
Comm->StopBits = 10;
Comm->FlowControl = fcNone;
Comm->OnRing = OnSignalChange;
Comm->OnCTSChange = OnSignalChange;
Comm->OnDSRChange = OnSignalChange;
Comm->OnDCDChange = OnSignalChange;
Comm->OnBreak = OnBreak;
Comm->OnError = OnError;
recordstream = NULL;
}
//---------------------------------------------------------------------------
__fastcall TTermForm::~TTermForm(void)
{
Comm->OnRing = NULL;
Comm->OnCTSChange = NULL;
Comm->OnDSRChange = NULL;
Comm->OnDCDChange = NULL;
Comm->OnBreak = NULL;
Comm->OnError = NULL;
forbidupdate = true;
Timer1->Enabled = false;
if (Comm->PortIsOpen) Comm->Close ();
if (recordstream != NULL) delete recordstream;
}
//---------------------------------------------------------------------------
void __fastcall TTermForm::ShowWindow (void)
{
if (PortBox->Items->Count == 0)
{
Application->MessageBox ("No COM Ports available", "Error",
MB_OK | MB_ICONERROR);
return;
}
if (WindowState == wsMinimized) WindowState = wsNormal;
if (PortBox->ItemIndex == -1) PortBox->ItemIndex = 0;
if (!Visible)
{
Show ();
forbidupdate = false;
modechanged = true;
RichEdit1->Clear ();
position.col = 0;
position.row = 0;
if (hexmode) AddHex (" ", true);
}
ToolBar1->SetFocus ();
commandmode = false;
}
//---------------------------------------------------------------------------
void __fastcall TTermForm::CloseFormClick(TObject *Sender)
{
Close ();
}
//---------------------------------------------------------------------------
void __fastcall TTermForm::AddText (char *text, bool locecho)
{
int len, i, l, len2;
AnsiString temp;
modechanged = false;
DefocusControl (RichEdit1, false); // Reduce Flickering
len = strlen (text);
for (i = 0;i < len;i++)
{
if (*(text + i) == '\r') position.col = 0;
else if (*(text + i) == '\n')
{
len2 = position.col;
position.row++;
position.col = 0;
if (crlf)
{
PlaceInString (' ');
for (l = 0;l < len2;l++)
{
PlaceInString (' ');
position.col++;
}
}
else PlaceInString (' ');
}
else if (*(text + i) == '\f')
{
RichEdit1->Clear ();
position.row = 0;
position.col = 0;
}
else if (*(text + i) == '\b')
{
if (position.col != 0 || position.row != 0)
{
position.col--;
if (position.col < 0)
{
position.row--;
position.col = RichEdit1->Lines->Strings[position.row].Length ();
RichEdit1->Lines->Delete (position.row + 1);
}
else PlaceInString (' ');
}
}
else if (*(text + i) == '\a') Beep ();
else if (*(text + i) == 0x1b && !locecho) commandmode = true;
else if (commandmode && !locecho)
{
if (*(text + i) == '{') esccommand = ecInitDownload;
else if (*(text + i) == '}') esccommand = ecInitUpload;
commandmode = false;
escprocessed = false;
}
else if (*(text + i) > 31 || *(text + i) < 0)
{
PlaceInString (text[i]);
position.col++;
}
}
RichEdit1->SetFocus();
SetRowCol (position.row, position.col);
}
//---------------------------------------------------------------------------
void __fastcall TTermForm::PlaceInString (char ch)
{
AnsiString temp;
int col = position.col + 1;
if (RichEdit1->Lines->Count <= position.row)
{
RichEdit1->Lines->Add (ch);
return;
}
if (RichEdit1->Lines->Strings[position.row].Length () < col)
{
temp = RichEdit1->Lines->Strings[position.row];
temp += ch;
RichEdit1->Lines->Strings[position.row] = temp;
return;
}
temp = RichEdit1->Lines->Strings[position.row];
temp[col] = ch;
RichEdit1->Lines->Strings[position.row] = temp;
}
//---------------------------------------------------------------------------
void __fastcall TTermForm::AddHex (char *text, bool init)
{
int i, l, len, b;
AnsiString temp, t;
DefocusControl (RichEdit1, false); // Reduce Flickering
if (init)
{
temp = "";
for (i = 0;i < (MAX_ROWLEN * 3) + 3;i++) temp += " ";
RichEdit1->Lines->Add (" ");
RichEdit1->Lines->Strings[position.row] = temp;
position.col = 0;
return;
}
modechanged = false;
len = strlen (text);
if (len == 0) len = 1; // NULL received
for (l = 0;l < len;l++)
{
temp = RichEdit1->Lines->Strings[position.row];
if (position.col >= MAX_ROWLEN)
{
position.row++;
position.col = 0;
b = *(text + l);
if (b < 0) b += 256;
t.printf ("%2.2X ", b);
temp = t;
for (i = 0;i < (MAX_ROWLEN * 3);i++) temp += " ";
if (*(text + l) > 31 || *(text + l) < 0) temp += *(text + l);
else temp += ".";
RichEdit1->Lines->Add (temp);
}
else
{
b = *(text + l);
if (b < 0) b += 256;
t.printf ("%2.2X ", b);
temp = RichEdit1->Lines->Strings[position.row];
temp.Delete ((position.col * 3) + 1, 3);
temp.Insert (t, (position.col * 3) + 1);
if (*(text + l) > 31 || *(text + l) < 0) temp += *(text + l);
else temp += ".";
RichEdit1->Lines->Strings[position.row] = temp;
}
position.col++;
}
SetRowCol (position.row, (position.col * 3) - 1);
RichEdit1->SetFocus();
}
//---------------------------------------------------------------------------
void __fastcall TTermForm::SetRowCol (int row, int col)
{
RichEdit1->SelStart = SendMessage (RichEdit1->Handle, EM_LINEINDEX,
row, 0) + col;
SendMessage(RichEdit1->Handle, EM_SCROLLCARET, 0, 0);
}
//---------------------------------------------------------------------------
void __fastcall TTermForm::GetRowCol (int *row, int *col)
{
*row = SendMessage (RichEdit1->Handle, EM_LINEFROMCHAR,
RichEdit1->SelStart, 0);
*col = RichEdit1->SelStart - SendMessage (RichEdit1->Handle,
EM_LINEINDEX, *row, 0);
}
//---------------------------------------------------------------------------
void __fastcall TTermForm::ConButtonClick(TObject *Sender)
{
int idx;
escprocessed = false;
idx = PortBox->ItemIndex;
if (idx == -1) return;
RTSLED->LEDOn = false;
DTRLED->LEDOn = false;
TXBRKLED->LEDOn = false;
commandmode = false;
esccommand = ecNone;
Comm->PortName = PortBox->Items->Strings[idx];
if (!Comm->Open ())
{
Application->MessageBox ("Unable to Open COM Port", "Error",
MB_OK | MB_ICONERROR);
}
else
{
ConButton->Enabled = false;
DisconButton->Enabled = true;
PortBox->Enabled = false;
StatusBar1->Panels->Items[5]->Text = "Connected";
StatusBar1->Panels->Items[6]->Text = "No Error";
OnSignalChange (this);
Timer1->Enabled = true;
switch (Comm->FlowControl)
{
case fcNone:
case fcXFlow: RTSLED->Enabled = true;
DTRLED->Enabled = true;
break;
case fcRTSCTS: RTSLED->Enabled = false;
DTRLED->Enabled = true;
break;
case fcDTRDSR: RTSLED->Enabled = true;
DTRLED->Enabled = false;
break;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TTermForm::DisconButtonClick(TObject *Sender)
{
Timer1->Enabled = false;
Comm->Close ();
ConButton->Enabled = true;
DisconButton->Enabled = false;
PortBox->Enabled = true;
StatusBar1->Panels->Items[5]->Text = "Disconnected";
}
//---------------------------------------------------------------------------
void __fastcall TTermForm::HexInputKeyPress(TObject *Sender, char &Key)
{
int len, l;
if (Key == 0x08) return; // Backspace
len = HexInput->Text.Length();
l = HexInput->SelLength;
Key = toupper (Key);
if (len >= 2 && l == 0) Key = 0;
if (!isxdigit (Key)) Key = 0;
}
//---------------------------------------------------------------------------
void __fastcall TTermForm::HexSendClick(TObject *Sender)
{
int len;
char buf[2] = {0};
unsigned char ch, t;
if (forbidupdate) return;
len = HexInput->Text.Length();
if (len == 0) return;
ch = HexInput->Text[1];
if (ch > '9') ch = ch - 'A' + 10;
else ch -= '0';
if (len == 2)
{
ch *= 16;
t = HexInput->Text[2];
if (t > '9') t = t - 'A' + 10;
else t -= '0';
ch += t;
}
buf[0] = ch;
if (localecho && !hexmode) AddText (buf, true);
if (localecho && hexmode) AddHex (buf, false);
if (Comm->PortIsOpen) Comm->Write (buf, 1);
}
//---------------------------------------------------------------------------
void __fastcall TTermForm::RichEdit1KeyPress(TObject *Sender, char &Key)
{
char buf[3] = {0};
if (forbidupdate)
{
Key = 0;
return;
}
if (Key == '\r' && !crlf) Key = '\n';
buf[0] = Key;
if (Key == '\r' && crlf) buf[1] = '\n';
if (Comm->PortIsOpen) Comm->Write (buf, strlen(buf));
//if (Key == '\r') buf[1] = '\n';
Key = 0;
if (localecho && !hexmode) AddText (buf, true);
if (localecho && hexmode) AddHex (buf, false);
}
//---------------------------------------------------------------------------
void __fastcall TTermForm::ClearEditClick(TObject *Sender)
{
RichEdit1->Clear ();
position.row = 0;
position.col = 0;
if (hexmode) AddHex ("", true);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -