4-Описание программы (1061346), страница 2
Текст из файла (страница 2)
hCom = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE,
/*FILE_SHARE_READ | FILE_SHARE_WRITE*/0, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if( hCom == INVALID_HANDLE_VALUE )
{ShowMessage("Не удалось открыть порт!");
Application->Terminate();}
else
{
BOOL retcode=PurgeComm(hCom,PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR);
if (!retcode) ShowMessage("Очистка не удалась");
retcode = ClearCommBreak(hCom);
if (!retcode) ShowMessage("Восстановление порта не удалось");
retcode = GetCommState(hCom,&dcb);
if (!retcode) ShowMessage("Невозможно получить параметры порта");
dcb.BaudRate = CBR_9600;
dcb.ByteSize = 8;
dcb.fParity=FALSE;
dcb.Parity = EVENPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fErrorChar = FALSE;
//dcb.ErrorChar=255;
dcb.fNull=FALSE;
ct.ReadIntervalTimeout=10;
ct.ReadTotalTimeoutMultiplier=ct.ReadTotalTimeoutConstant=0;
ct.WriteTotalTimeoutMultiplier=ct.WriteTotalTimeoutConstant=0;
int er = SetCommState(hCom,&dcb);
//if (!er) {strcpy(Message,"Ошибка утановки параметров порта");
// NeedInMsg=1;}
//if (!retcode) ShowMessage("SetCommState failed");
retcode = SetCommTimeouts(hCom,&ct);
if (!retcode) ShowMessage("Невозможно установить параметры порта");
}
}
//---------------------------------------------------------------------------
DWORD WINAPI ReadThread(LPVOID p)
{
//ShowMessage(s);
DWORD CommEventMask = EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING |
EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY;
BOOL retcode = SetCommMask(hCom,CommEventMask);
if( !retcode ) ShowMessage("Невозможно установить маску отслеживаемых событий");
OL.hEvent=CreateEvent(NULL, FALSE, FALSE, NULL);
OL.Offset=0;
OL.OffsetHigh=0;
DWORD EventMask = 0;
int cadr=0;
do
{
retcode = WaitCommEvent(hCom, &EventMask, &OL);
if ( ( !retcode ) && (GetLastError()==ERROR_IO_PENDING) )
WaitForSingleObject(OL.hEvent, INFINITE);
if (EventMask & EV_RXCHAR)
{
DWORD ErrorMask = 0;
COMSTAT CStat;
ClearCommError(hCom, &ErrorMask, &CStat);
DWORD quelen = CStat.cbInQue;
char *lpInBuffer = (char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,quelen+1);
if (!lpInBuffer)
{
ShowMessage("Невозможно выделить память");
Application->Terminate();
}
DWORD dwReaded = 0;
retcode = ReadFile(hCom, lpInBuffer, quelen, &dwReaded, &OL);
if( dwReaded == 0 && GetLastError() == ERROR_IO_PENDING )
retcode = GetOverlappedResult(hCom, &OL, &dwReaded, FALSE) ;
else
if (dwReaded>0)
{int num;
char * buffer;
// int cadr=0;
short int length;
if (lpInBuffer[0] == 0x01) //новый кадр
{
switch (lpInBuffer[1])
{
case 1: // информационный кадр
{
memcpy(&length,lpInBuffer+2,2);
buffer = (char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,length+1);
if (!buffer)
{
ShowMessage("Невозможно выделить память");
Application->Terminate();
}
if (length > 3) memcpy(buffer, lpInBuffer+4,4);
break;
}
case 2: // установка DCB
{
int baud_rate = lpInBuffer[2]-1;
int parity = lpInBuffer[4]-1;
INFOBITS = lpInBuffer[5]-1;
int stop = lpInBuffer[6]-1;
GetCommState(hCom, &dcb);
switch (baud_rate)
{
case 0: dcb.BaudRate=CBR_110;break;
case 1: dcb.BaudRate=CBR_300;break;
case 2: dcb.BaudRate=CBR_600;break;
case 3: dcb.BaudRate=CBR_1200;break;
case 4: dcb.BaudRate=CBR_2400;break;
case 5: dcb.BaudRate=CBR_4800;break;
case 6: dcb.BaudRate=CBR_9600;break;
case 7: dcb.BaudRate=CBR_14400;break;
case 8: dcb.BaudRate=CBR_19200;break;
case 9: dcb.BaudRate=CBR_38400;break;
case 10: dcb.BaudRate=CBR_56000;break;
case 11: dcb.BaudRate=CBR_57600;break;
case 12: dcb.BaudRate=CBR_115200;break;
case 13: dcb.BaudRate=CBR_128000;break;
case 14: dcb.BaudRate=CBR_256000;break;
}
dcb.fParity = FALSE;
switch (parity)
{
case 0: dcb.Parity=EVENPARITY;break;
case 1: dcb.Parity=MARKPARITY;break;
case 2: dcb.Parity=NOPARITY;break;
case 3: dcb.Parity=ODDPARITY;break;
case 4: dcb.Parity=SPACEPARITY;break;
}
switch (stop)
{
case 0: dcb.StopBits=ONESTOPBIT;break;
case 1: dcb.StopBits=ONE5STOPBITS;break;
case 2: dcb.StopBits=TWOSTOPBITS;break;
}
if (!SetCommState(hCom,&dcb)) ShowMessage("Ошибка утановки параметров порта");
lpInBuffer=lpInBuffer+8;
dwReaded=dwReaded-8;
break;
}
case 3: // заполнение канала для контроля соединения
{
char s[3]={1,3,2};
Form1->Timer2->Enabled=FALSE;
Form1->Timer2->Interval=5000;
int retcode=WriteFile(hCom, s, 3, (unsigned long*)&num, &OL);
Form1->Timer2->Enabled=TRUE;
lpInBuffer=lpInBuffer+3;
dwReaded=dwReaded-3;
break;
}
case 4: //установка соединения
{
char s[3]={1,4,2};
Form1->Button1->Enabled=TRUE;
if (!SENDCONNECT)
int retcode=WriteFile(hCom, s, 3, (unsigned long*)&num, &OL);
Form1->Timer2->Enabled=FALSE;
Form1->Timer2->Interval=5000;
lpInBuffer=lpInBuffer+3;
dwReaded=dwReaded-3;
// SENDCONNECT=0;
break;
}
case 5: //разрыв соединения
{Form1->Button1->Enabled=FALSE;
Form1->Timer2->Enabled=FALSE;
Form1->Timer2->Interval=5000;
lpInBuffer=lpInBuffer+3;
dwReaded=dwReaded-3;
TMsgDlgButtons buttons;
buttons << mbOK << mbCancel;
SENDCONNECT=0;
ShowMessage("Сеанс связи завершен");
if (BUFFER!=NULL)
HeapFree(GetProcessHeap(),0,BUFFER);
Form1->Button2->Enabled=TRUE;
Form1->Button1->Enabled=FALSE;
break;
}
case 6: //квитанция
Form1->Timer3->Enabled=FALSE; //успешно принято
Form1->Timer3->Interval=10000;
Form1->Button1->Enabled=TRUE;//SUCCESS = 1;
HeapFree(GetProcessHeap(),0,BUFFER);
lpInBuffer=lpInBuffer+3;
dwReaded=dwReaded-3;
break;
}
}
else // продолжение информационного кадра
{
if (!memchr(lpInBuffer, 2, dwReaded))
{memcpy(buffer+4+cadr*8, lpInBuffer, dwReaded);
cadr++;}
else //конец кадра
{
memcpy(buffer+4+cadr*8, lpInBuffer, dwReaded-1);
char *tmp=buffer+4+cadr*8;
char * b = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,length/2+1);
if (!b)
{
ShowMessage("Невозможно выделить память");
Application->Terminate();
}
Decode(b, buffer,length);
if (ERROR1)
{
HeapFree(GetProcessHeap(),0,buffer);
HeapFree(GetProcessHeap(),0,lpInBuffer);
PurgeComm(hCom, /*PURGE_TXCLEAR |*/ PURGE_RXCLEAR);
EventMask=0;
ResetEvent(OL.hEvent);
ERROR1=0;
HeapFree(GetProcessHeap(),0,b);
continue;
}
else
{unsigned long n;
WriteFile(hCom, "\x01\x06\x02",3, &n, &OL );
Form2->Memo1->Clear();
AddToMemo(Form2->Memo1,(char*)b);
AddToMemo(Form7->Memo1," <IN> ");
AddToMemo(Form7->Memo1,(char*)b);
}
HeapFree(GetProcessHeap(),0,buffer);
HeapFree(GetProcessHeap(),0,b);
cadr=0;
}
}
}
HeapFree(GetProcessHeap(),0,lpInBuffer);
} //ev_rxchar
PurgeComm(hCom, /*PURGE_TXCLEAR |*/ PURGE_RXCLEAR);
EventMask=0;
ResetEvent(OL.hEvent);
}
while(1);
}
//---------------------------------------------------------------------------
void __fastcall AddToMemo(TMemo * pMemo, char * str)
{
int len;
len = pMemo->GetTextLen();
char * buf1 = (char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, len+1);
if (!buf1)
{ShowMessage("Невозможно выделить память");
Application->Terminate();}
pMemo->GetTextBuf(buf1, len+1);
char * buf2 = (char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, len+strlen(str)+2);
if (!buf2)
{ShowMessage("Невозможно выделить память");
Application->Terminate();}
strcpy(buf2,buf1);
strcpy(buf2+len,str);
pMemo->SetTextBuf(buf2);
HeapFree(GetProcessHeap(),0,buf1);
HeapFree(GetProcessHeap(),0,buf2);
}
//--------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Form1->Memo2->Clear();
Form1->Button1->Enabled=FALSE;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if (!Memo2->Text.Length()) return;
char * outbuffer;
unsigned long num;
int len = Form1->Memo2->GetTextLen();
outbuffer = (char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+3);
if (!outbuffer)
{ ShowMessage("при отправке outbuffer=NULL");
Application->Terminate(); }
Form1->Memo2->GetTextBuf(outbuffer,len+1);
outbuffer[len]='\r';
outbuffer[len+1]='\n';
unsigned char *b = (char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,2*(len+2)+1);
if (!b)
{ ShowMessage("Невозможно выделить память");
Application->Terminate(); }
Code(b,outbuffer,len+2);
BUFFER = (char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, (len+2)*2+6);
if (!BUFFER)
{
ShowMessage("Невозможно выделить память");
Application->Terminate();
}
BUFFER[0] = 0x01; //заголовок кадра
BUFFER[1] = 0x01; //признак информационного кадра
int g=((len+2)*2);
char * s = (char*)&g;
BUFFER[2] = s[0];
BUFFER[3] = s[1];
memcpy(BUFFER+4, b, (len+2)*2); //информационное поле
BUFFER[(len+2)*2+4] = 0x02; //окончание кадра
LEN = (len+2)*2+5;
int retcode=WriteFile(hCom, BUFFER, LEN, &num, &OL);
Form1->Timer3->Enabled=TRUE;
//Button1->Enabled=FALSE;
AddToMemo(Form7->Memo1, " <OUT> ");
AddToMemo(Form7->Memo1, outbuffer);
HeapFree(GetProcessHeap(),0,outbuffer);
HeapFree(GetProcessHeap(),0,b);
Form1->Memo2->Clear();
Form1->Memo2->SetFocus();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
unsigned long num;
if (hCom!=INVALID_HANDLE_VALUE)WriteFile(hCom, "\x01\x05\x02", 3, &num, &OL);
CloseHandle(hCom);
CloseHandle(OL.hEvent);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
unsigned long num;
SENDCONNECT=1;
char buf[3] = {1,4,2};
int retcode=WriteFile(hCom, buf, 3, &num, &OL);
buf[1] = 3;
retcode=WriteFile(hCom, buf, 3, &num, &OL);
Form1->Timer2->Enabled=TRUE;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer2Timer(TObject *Sender)
{
TMsgDlgButtons buttons;
Form1->Timer2->Enabled=FALSE;
Form1->Timer2->Interval=5000;
buttons << mbOK << mbCancel;
int button = MessageDlg("Невозможно установить соединение со вторым компьютером или недоступна среда передачи. Закрыть приложение?",mtError,buttons,0);
if (button==mrOk)
Application->Terminate();
else
{if (BUFFER!=NULL)
HeapFree(GetProcessHeap(),0,BUFFER);
Button2->Enabled=TRUE;
Button1->Enabled=FALSE;}
}
//---------------------------------------------------------------------------
15