📄 unit1.cpp
字号:
//and put the information into ModemInfo
//Result < 0 indicates an error
if (lineGetID(Line, 0, 0, LINECALLSELECT_LINE, (LPVARSTRING)&ModemInfo,
"comm/datamodem") < 0)
{
//Report the error and return because we cannot connect to the comm file
mMessage->Lines->Add("Error on line get id " + IntToStr(GetLastError()));
return;
}
//The file handle to the communications device is contained in ModemInfo
hCommDevice = ModemInfo.hComm;
//If this is not a valid file handle
if (hCommDevice == INVALID_HANDLE_VALUE) {
//Report the error and return
mMessage->Lines->Add("Error on open " + IntToStr(GetLastError()));
return;
}
//Get the config of the modem connection
GetCommState(hCommDevice, &dcb);
//Set to 8 bits, no parity, 1 stopbit
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
//Actually set the config
SetCommState(hCommDevice, &dcb);
//Get timeout information for the communications channel
GetCommTimeouts(hCommDevice, &ct);
//Set the timeout to 1 second so that a pending read
//will complete when more that 1 second has elapsed between the arrival
//of two consecutive characters
ct.ReadIntervalTimeout = 1000;
//Set the new timeout value
SetCommTimeouts(hCommDevice, &ct);
//Put the input focus on the input memo box
Input->SetFocus();
//Start the threads that actually read and write the communications file
FileWriteThread = new TFileWriteThread(hCommDevice);
FileReadThread = new TFileReadThread(hCommDevice);
//Terminal status is connected
TerminalConnected = TRUE;
}
//Stop the dump terminal
void __fastcall TForm1::ShutdownTerminal(void)
{
//If the terminal is connected
if (TerminalConnected)
{
//Shutdown the writing thread if it exists
if (FileWriteThread)
FileWriteThread->Terminate();
//Shutdown the reading thread if it exists
if (FileReadThread)
FileReadThread->Terminate();
//Close the communications channel
CloseHandle(hCommDevice);
}
//The terminal is now disconnected
TerminalConnected = FALSE;
}
//---------------------------------------------------------------------------
//TFileThread
//Basic functionality for file reading and file writing threads
//Constructor
__fastcall TFileThread::TFileThread(HANDLE CommFile)
: TThread(True)
{
//Initialize an event object
hFileEvent = CreateEvent(NULL, //no security attribute
FALSE, //Auto-reset event
FALSE, //initial state unsignaled
NULL); //Unnamed
//Assign the communications file handle
hCommDevice = CommFile;
//Assign the auto-reset event to the event field of the structure
//used by overlapped i/o calls
oOverlap.hEvent = hFileEvent;
//Initialize the error message
ErrorMess = "";
}
//Destructor
__fastcall TFileThread::~TFileThread(void)
{
//Close the event object
CloseHandle(hFileEvent);
}
//Error routine to call
void __fastcall TFileThread::Error(String ErrMess)
{
//Set the current error message
ErrorMess = ErrMess;
//Call ShowError in the context of the main thread
Synchronize(ShowError);
//Clear the error message
ErrorMess = "";
}
//Internal error routine
//Must always be called with synchronize
void __fastcall TFileThread::ShowError(void)
{
//Display the current error message in the message memo
Form1->mMessage->Lines->Add(ErrorMess);
}
//Tell the thread to terminate
void __fastcall TFileThread::Terminate(void)
{
//Call the parent's terminate event to set the termination flag
TThread::Terminate();
//Raise the file event so that the thread will actually terminate
//see the execute method of TFileWriteThread and TFileReadThread
//for more info
SetEvent(hFileEvent);
}
//-----------------------------------------------------------------------------
//TFileWriteThread
//Manage writing the communications file
//Constructor
__fastcall TFileWriteThread::TFileWriteThread(HANDLE hCommFile)
: TFileThread(hCommFile)
{
//Create the critical section
InitializeCriticalSection(&CriticalSection);
//Start execution of the thread which was started in the suspended state
Resume();
}
//Destructor
__fastcall TFileWriteThread::~TFileWriteThread(void)
{
//Free the memory associated with the critical section
DeleteCriticalSection(&CriticalSection);
}
//Store user input and wake up the thread to process the input
void __fastcall TFileWriteThread::WriteData(String s)
{
//Start the critical section
EnterCriticalSection(&CriticalSection);
//Set the data to be written
WriteString = s;
//End the critical section
LeaveCriticalSection(&CriticalSection);
//Raise the event so that the waiting data can be written
SetEvent(hFileEvent);
}
//Main loop
void __fastcall TFileWriteThread::Execute(void)
{
DWORD BytesWritten, ErrCode;
//As long as the thread is supposed to run
while (!Terminated)
{
//If there is data waiting to write
if (WriteString != "")
{
//Initalize the write buffer
strnset(Buffer, '\0', sizeof(Buffer));
//Start the critical section
EnterCriticalSection(&CriticalSection);
//Copy the data to the write buffer
strcpy(Buffer, WriteString.c_str());
//Clear the data
WriteString = "";
//End critical section
LeaveCriticalSection(&CriticalSection);
//Start a pending write operation
if (!WriteFile(hCommDevice, Buffer, strlen(Buffer),
&BytesWritten, &oOverlap))
//If an error occured get the error code
//if the error code is not ERROR_IO_PENDING
if ((ErrCode = GetLastError()) != ERROR_IO_PENDING)
//Report the error
Error("Error on write file " + IntToStr(ErrCode));
}
//Otherwise wait for the IO to finish )which will raise this event) or
//for the user to enter a line of information (event will be raised by
//the WriteData method) or for the thread to be terminated (which will
//also raise the event)
WaitForSingleObjectEx(hFileEvent, INFINITE, TRUE);
}
}
//--------------------------------------------------------------------------
//TFileReadThread
//Handle reading the communications file
__fastcall TFileReadThread::TFileReadThread(HANDLE hCommFile)
: TFileThread(hCommFile)
{
//Start the thread which was born in the suspended state
Resume();
}
void __fastcall TFileReadThread::UpdateWindow(void)
{
//Write data to the output window in the context of the main thread
Form1->Output->Lines->Add(Buffer);
}
void __fastcall TFileReadThread::Execute(void)
{
DWORD BytesRead, ErrCode;
//While the thread is not terminated
while (!Terminated)
{
//Initialize the buffer
strnset(Buffer, '\0', sizeof(Buffer));
//Start a pending read operation
if (!ReadFile(hCommDevice, Buffer, BUFSIZE, &BytesRead, &oOverlap))
{
//If an error occured get the error code
//If the error code is not ERROR_IO_PENDING
if ((ErrCode = GetLastError()) != ERROR_IO_PENDING)
//Report the error
Error("Error on read file " + IntToStr(ErrCode));
//Otherwise
else
{
//Wait for the IO to complete or for the thread to terminate
WaitForSingleObjectEx(hFileEvent, INFINITE, TRUE);
//If there is some data in the buffer
if (strlen(Buffer))
{
//Write it to the output window
Synchronize(UpdateWindow);
}
}
}
}
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -