⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 comm.~cpp

📁 1.用RS-232的零MODEM的连接法连好两机的连线; 2.用DOS的MODE命令设置好两机的通讯格式
💻 ~CPP
字号:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Comm.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#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; //准备发送的字符长度,实际发出的字符数
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)
{   Shape1->Brush->Color=clRed;
     if(m_hComm)
     {
         CloseHandle(m_hComm);
         m_hComm=NULL;
     }
    m_ComName=CmbComName->Text;
    m_hComm=CreateFile(m_ComName.c_str(),           //串口号
                       GENERIC_READ|GENERIC_WRITE,  //允许读写
                       0,                           //通讯设备必须以独占方式打开
                       NULL,                        //无安全属性
                       OPEN_EXISTING,               //通讯设备已存在
                       FILE_FLAG_OVERLAPPED,        //异步I/O
                       0);                          //通讯设备不能用模板打开
    if(m_hComm==INVALID_HANDLE_VALUE)
    {
        MessageDlg("端口打开出错!", mtWarning, TMsgDlgButtons() << mbOK, 0);
        m_hComm=NULL;
        return;
    }
    StatusBar->Panels->Items[0]->Text=m_ComName+"串口已打开!";
    EnableCmp(false,true);
    BtnCancelSend->Enabled=false;
    BtnCancelRece->Enabled=false;
    // 设置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状态
//  m_dcb.fRtsControl = RTS_CONTROL_ENABLE;   // set RTS bit high!
    m_dcb.BaudRate=CmbBaudRate->Text.ToInt();  //设置波特率
    m_dcb.ByteSize=CmbByteSize->Text.ToInt();  //设置数据位
    m_dcb.StopBits=CmbStopBits->ItemIndex;     //设置停止位
    m_dcb.Parity=CmbParity->ItemIndex;         //设置校验位
    SetCommState(m_hComm, &m_dcb);             //

    ReadThread=new RecThread(true);
    ReadThread->Resume();
}
//---------------------------------------------------------------------------

void __fastcall TSerialPort::BtnCloseClick(TObject *Sender)
{  Shape1->Brush->Color=clGreen;
    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+"串口已关闭!";
    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("已发送数据"+IntToStr(BytesWritten)+"字节");
    else MessageDlg("发送字符不能为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,             //调用成功返回非零,失败返回零
                  Buffer,             //输出缓冲区
                  length,             //准备发送的字符长度
                  LengthWrited,       //实际发出的字符数
                  lpOverlappedWrite)) //重叠结构)
    {
        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("退出前请关闭串口!", 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("打开文件出错!", mtError, TMsgDlgButtons() << mbOK, 0);
            return;
        }
        iFileLength = FileSeek(iFileHandle,0,2); //取得文件长度(文件指针指向文件尾)
        fFileFlag.length=iFileLength;
        FileSeek(iFileHandle,0,0);               //文件指针指向文件头
        if(iFileLength<0)
        {
            MessageDlg("打开文件出错!", 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); //发送文件握手信号

        DWORD waitevent=WaitForSingleObject(hReceiveReady,20000);
        if(waitevent==WAIT_TIMEOUT)     //超时,对方没有响应
        {
            MessageDlg("对方没有响应!", mtInformation, TMsgDlgButtons() << mbOK, 0);
            FileClose(iFileHandle);
            return;
        }     //  if(waitevent==WAIT_TIMEOUT)
        else if(waitevent!=WAIT_OBJECT_0 )  //其他错误
            {
                MessageDlg("发送出错!", mtInformation, TMsgDlgButtons() << mbOK, 0);
                FileClose(iFileHandle);
                return;
            }  //  else if(waitevent!=WAIT_OBJECT_0 )
        else     //接收方准备好,发送文件
            {
//                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("发送完毕!", 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);
}
//---------------------------------------------------------------------------


void __fastcall TSerialPort::FormCreate(TObject *Sender)
{
 Shape1->Brush->Color=clGreen;       
}
//---------------------------------------------------------------------------





⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -