?? comm.cpp
字號(hào):
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Comm.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "CGAUGES"
#pragma resource "*.dfm"
TSerialPort *SerialPort;
HANDLE m_hComm;
HANDLE hReceiveReady;
DCB m_dcb;
AnsiString m_ComName,m_SendBuf;
AnsiString FileName;
char filename[100];
char FileBuf[1024];
RecThread *ReadThread;
COMMTIMEOUTS m_CommTimeouts;
LPOVERLAPPED lpOverlappedWrite;
unsigned long BytesToWrite,BytesWritten; //準(zhǔn)備發(fā)送的字符長度,實(shí)際發(fā)出的字符數(shù)
unsigned long lWriteLength;
unsigned long lBytesRead,lBytesWrited;
unsigned long send;
unsigned long iFileLength;
int iFileHandle;
bool bOpen;
//---------------------------------------------------------------------------
__fastcall TSerialPort::TSerialPort(TComponent* Owner)
: TForm(Owner)
{
m_hComm = NULL;
lpOverlappedWrite=new OVERLAPPED;
memset(lpOverlappedWrite,0,sizeof(OVERLAPPED));
lpOverlappedWrite->hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
lpOverlappedRead=new OVERLAPPED;
memset(lpOverlappedRead,0,sizeof(OVERLAPPED));
lpOverlappedRead->hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
hReceiveReady=CreateEvent(NULL,TRUE,FALSE,NULL);
EnableCmp(true,false);
}
//---------------------------------------------------------------------------
bool TSerialPort::EnableCmp(bool x,bool y)
{
CmbComName->Enabled=x;
CmbBaudRate->Enabled=x;
CmbByteSize->Enabled=x;
CmbStopBits->Enabled=x;
CmbParity->Enabled=x;
BtnOpen->Enabled=x;
BtnClose->Enabled=y;
BtnSendChar->Enabled=y;
BtnSendFile->Enabled=y;
BtnBrowse->Enabled=y;
BtnCancelSend->Enabled=y;
BtnCancelRece->Enabled=y;
return true;
}
//---------------------------------------------------------------------------
void __fastcall TSerialPort::BtnOpenClick(TObject *Sender)
{
if(m_hComm)
{
CloseHandle(m_hComm);
m_hComm=NULL;
}
m_ComName=CmbComName->Text;
m_hComm=CreateFile(m_ComName.c_str(), //串口號(hào)
GENERIC_READ|GENERIC_WRITE, //允許讀寫
0, //通訊設(shè)備必須以獨(dú)占方式打開
NULL, //無安全屬性
OPEN_EXISTING, //通訊設(shè)備已存在
FILE_FLAG_OVERLAPPED, //異步I/O
0); //通訊設(shè)備不能用模板打開
if(m_hComm==INVALID_HANDLE_VALUE)
{
MessageDlg("端口打開出錯(cuò)!", mtWarning, TMsgDlgButtons() << mbOK, 0);
m_hComm=NULL;
return;
}
StatusBar->Panels->Items[0]->Text=m_ComName+"串口已打開!";
EnableCmp(false,true);
BtnCancelSend->Enabled=false;
BtnCancelRece->Enabled=false;
// 設(shè)置timeout
m_CommTimeouts.ReadIntervalTimeout = 100;
m_CommTimeouts.ReadTotalTimeoutMultiplier = 0;
m_CommTimeouts.ReadTotalTimeoutConstant = 0;
m_CommTimeouts.WriteTotalTimeoutMultiplier = 0;
m_CommTimeouts.WriteTotalTimeoutConstant = 0;
SetCommTimeouts(m_hComm, &m_CommTimeouts);
SetCommMask(m_hComm, EV_RXCHAR);
SetupComm(m_hComm,1024,1024);
GetCommState(m_hComm, &m_dcb); //獲得DCB狀態(tài)
// m_dcb.fRtsControl = RTS_CONTROL_ENABLE; // set RTS bit high!
m_dcb.BaudRate=CmbBaudRate->Text.ToInt(); //設(shè)置波特率
m_dcb.ByteSize=CmbByteSize->Text.ToInt(); //設(shè)置數(shù)據(jù)位
m_dcb.StopBits=CmbStopBits->ItemIndex; //設(shè)置停止位
m_dcb.Parity=CmbParity->ItemIndex; //設(shè)置校驗(yàn)位
SetCommState(m_hComm, &m_dcb); //
ReadThread=new RecThread(true);
ReadThread->Resume();
}
//---------------------------------------------------------------------------
void __fastcall TSerialPort::BtnCloseClick(TObject *Sender)
{
if(m_hComm!=INVALID_HANDLE_VALUE) CloseHandle(m_hComm);
m_hComm=NULL;
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
StatusBar->Panels->Items[0]->Text=m_ComName+"串口已關(guān)閉!";
EnableCmp(true,false);
}
//---------------------------------------------------------------------------
void __fastcall TSerialPort::BtnSendCharClick(TObject *Sender)
{
m_SendBuf=EdtSend->Text;
BytesToWrite=EdtSend->Text.Length();
SendData(m_hComm,m_SendBuf.c_str(),BytesToWrite,&BytesWritten);
if (BytesWritten>0)
SerialPort->Memo->Lines->Add("已發(fā)送數(shù)據(jù)"+IntToStr(BytesWritten)+"字節(jié)");
else MessageDlg("發(fā)送字符不能為0!", mtError, TMsgDlgButtons() << mbOK, 0);
}
//---------------------------------------------------------------------------
bool SendData(HANDLE h_Comm,char *Buffer,unsigned long length,unsigned long *LengthWrited)
{
if(!h_Comm) return false;
if(!WriteFile(h_Comm, //調(diào)用成功返回非零,失敗返回零
Buffer, //輸出緩沖區(qū)
length, //準(zhǔn)備發(fā)送的字符長度
LengthWrited, //實(shí)際發(fā)出的字符數(shù)
lpOverlappedWrite)) //重疊結(jié)構(gòu))
{
if(GetLastError()== ERROR_IO_PENDING)
{
DWORD RESULT;
do
{
RESULT=WaitForSingleObject(lpOverlappedWrite->hEvent,2000);
}while(RESULT!=WAIT_OBJECT_0);
GetOverlappedResult(m_hComm,lpOverlappedWrite,LengthWrited,false);
return true;
}
return false;
}
return true;
}
//---------------------------------------------------------------------------
void __fastcall TSerialPort::BtnExitClick(TObject *Sender)
{
if(!BtnClose->Enabled) Close();
else MessageDlg("退出前請關(guān)閉串口!", mtWarning, TMsgDlgButtons() << mbOK, 0);
}
//---------------------------------------------------------------------------
void __fastcall TSerialPort::BtnBrowseClick(TObject *Sender)
{
// FILEFLAG fFileFlag;
bOpen=OpenDialog->Execute();
FileName=OpenDialog->FileName;
EdtFile->Text=FileName;
}
//---------------------------------------------------------------------------
void __fastcall TSerialPort::BtnSendFileClick(TObject *Sender)
{
FILEFLAG fFileFlag;
lBytesWrited=0;
lBytesRead=0;
if(bOpen)
{
int index=FileName.LastDelimiter("\\");
strcpy(fFileFlag.name,&FileName[index+1]); //保存文件名
iFileHandle = FileOpen(FileName, fmOpenRead);
if(iFileHandle==-1)
{
MessageDlg("打開文件出錯(cuò)!", mtError, TMsgDlgButtons() << mbOK, 0);
return;
}
iFileLength = FileSeek(iFileHandle,0,2); //取得文件長度(文件指針指向文件尾)
fFileFlag.length=iFileLength;
FileSeek(iFileHandle,0,0); //文件指針指向文件頭
if(iFileLength<0)
{
MessageDlg("打開文件出錯(cuò)!", mtError, TMsgDlgButtons() << mbOK, 0);
FileClose(iFileHandle);
return;
}
strcpy(fFileFlag.flag,"FileFlag");
char *fileflag=(char*)&fFileFlag;
unsigned long fileflaglength=sizeof(FILEFLAG);
SendData(m_hComm,fileflag,fileflaglength,&fileflaglength); //發(fā)送文件握手信號(hào)
DWORD waitevent=WaitForSingleObject(hReceiveReady,10000);
if(waitevent==WAIT_TIMEOUT) //超時(shí),對方?jīng)]有響應(yīng)
{
MessageDlg("對方?jīng)]有響應(yīng)!", mtInformation, TMsgDlgButtons() << mbOK, 0);
FileClose(iFileHandle);
return;
} // if(waitevent==WAIT_TIMEOUT)
else if(waitevent!=WAIT_OBJECT_0 ) //其他錯(cuò)誤
{
MessageDlg("發(fā)送出錯(cuò)!", mtInformation, TMsgDlgButtons() << mbOK, 0);
FileClose(iFileHandle);
return;
} // else if(waitevent!=WAIT_OBJECT_0 )
else //接收方準(zhǔn)備好,發(fā)送文件
{
// tcsReadyLock->Acquire();
bool bReady=true;
// tcsReadyLock->Release();
ResetEvent(hReceiveReady);
while(bReady&&lBytesWrited<iFileLength)
{
lBytesRead=FileRead(iFileHandle,FileBuf,1024);
SendData(m_hComm,FileBuf,lBytesRead,&send);
lBytesWrited=lBytesWrited+send;
PbSend->Position=100*lBytesWrited/iFileLength;
}
//MessageDlg("發(fā)送完畢!", mtInformation, TMsgDlgButtons() << mbOK, 0);
lBytesWrited=0;
FileClose(iFileHandle);
//tcsReadyLock->Acquire();
bReady=false;
//tcsReadyLock->Release();
}
} //if(bOpen)
PbSend->Position=0;
}
//---------------------------------------------------------------------------
void __fastcall TSerialPort::BtnCancelSendClick(TObject *Sender)
{
FILEFLAG FileFlag;
unsigned long SignalLength;
bReady=false;
SendData(m_hComm,"CancelS",7,&SignalLength);
}
//---------------------------------------------------------------------------
void __fastcall TSerialPort::BtnCancelReceClick(TObject *Sender)
{
FILEFLAG FileFlag;
unsigned long SignalLength;
SendData(m_hComm,"CancelR",7,&SignalLength);
}
//---------------------------------------------------------------------------
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -