Figure 7: Client application model
UINT CMainFrame::MakeCallThread(PVOID pParam) { CMainFrame* pMainFrame = (CMainFrame*)pParam; // instantiate Remote Connect object - request outbound/use // default I/O thread CRemoteConnect obj(CRemoteConnect::MAKECALL,TRUE); if (!obj.PortInitOk()) return 1L; // put user interface algorithm here - do a simple loopback // as an example - start loopback by opening a file and // writing some text to output port ifstream infile("testfile.txt"); if (!infile) return 1L; ofstream outfile("modemecho.txt"); if (!outfile) return 1L; CByteArray inMsg; char outMsg[MAX_IO_BYTES+1]; infile.read(outMsg,MAX_IO_BYTES); obj.putMessage(outMsg,infile.gcount()); while (!infile.eof()) { if (WaitForSingleObject(pMainFrame->m_exitThreadEvent,0) != WAIT_TIMEOUT) return 0L; // file closes automatically // Block on read message up to 1sec if (obj.SyncRead(inMsg,1000)) while (inMsg.GetSize()) { BYTE inbyte = inMsg.GetAt(0); outfile << inbyte; inMsg.RemoveAt(0); } if (!infile.eof() && obj.txREADY()) { infile.read(outMsg,MAX_IO_BYTES); obj.putMessage(outMsg,infile.gcount()); } } // all done writing the file so while no terminate, // get the rest of it while (WaitForSingleObject(pMainFrame->m_exitThreadEvent,0) == WAIT_TIMEOUT) // Block on read message up to 1sec if (obj.SyncRead(inMsg,1000)) while (inMsg.GetSize()) { BYTE inbyte = inMsg.GetAt(0); outfile << inbyte; inMsg.RemoveAt(0); } return 0L; }