/*----------------------------------------------------------------------------- FUNCTION: StatusDlgProc(HWND, UINT, WPARAM, LPARAM) PURPOSE: Provides the dialog procedure for the status dialog PARAMETERS: hWndDlg - Dialog window handle uMsg - Window message wParam - message parameter (depends on message) lParam - message parameter (depends on message) RETURN: TRUE if message is handled FALSE if message is not handled Exception is WM_INITDIALOG: returns FALSE since focus is not set HISTORY: Date: Author: Comment: 10/27/95 AllenD Wrote it -----------------------------------------------------------------------------*/ BOOL CALLBACK StatusDlgProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; switch(uMsg) { case WM_INITDIALOG: // setup dialog with defaults SendMessage(GetDlgItem(hWndDlg, IDC_STATUSEDIT), WM_SETFONT, (WPARAM)ghFontStatus, 0); InitStatusMessage(); break; case WM_COMMAND: { switch(LOWORD(wParam)) { case IDC_ABORTBTN: SendMessage(ghwndMain, WM_COMMAND, ID_TRANSFER_ABORTSENDING, MAKELPARAM(IDC_ABORTBTN,0) ); fRet = TRUE; break; case IDC_STATCTS: case IDC_STATDSR: case IDC_STATRING: case IDC_STATRLSD: CheckModemStatus(TRUE); fRet = TRUE; break; case IDC_CTSHOLDCHK: case IDC_DSRHOLDCHK: case IDC_RLSDHOLDCHK: case IDC_XOFFHOLDCHK: case IDC_XOFFSENTCHK: case IDC_EOFSENTCHK: case IDC_TXIMCHK: CheckComStat(TRUE); fRet = TRUE; break; default: break; } } break; default: break; } return fRet; }
DWORD CSerialServer::ReadProc() { OVERLAPPED osReader; // Overlapped structure for read operations OVERLAPPED osStatus; // Overlapped structure for status operations HANDLE arEvents[3]; // Event Array DWORD dwStoredFlags; // Local copy of event flags DWORD dwCommEvent=0; // Result from WaitCommEvent DWORD dwRead; // Bytes actually read #ifndef WINCE DWORD dwResult; // Result from WaitForSingleObject #endif BOOL fWaitingOnRead; BOOL fWaitingOnStat; BOOL fThreadDone; #ifndef WINCE DWORD dwOvRes; // Result from GetOverlappedResult #endif m_pSaveSession = NewSession(m_hComPort, m_szDevice); OnEnterSession(m_pSaveSession); dwStoredFlags = 0xFFFFFFFF; fWaitingOnRead = FALSE; fWaitingOnStat = FALSE; fThreadDone = FALSE; // Create two overlapped structures, one for read events // and another for status events memset(&osReader, 0, sizeof(OVERLAPPED)); osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (osReader.hEvent == NULL) XDEBUG("[CSerialServer] CreateEvent (Reader Event).\n"); memset(&osStatus, 0, sizeof(OVERLAPPED)); osStatus.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (osStatus.hEvent == NULL) XDEBUG("[CSerialServer] CreateEvent (Status Event).\n"); arEvents[0] = m_hReadStopEvent; arEvents[1] = osReader.hEvent; arEvents[2] = osStatus.hEvent; // Initial Check, Forces Updates CheckModemStatus(TRUE); CheckComStat(TRUE); m_bRecvReady = TRUE; while(!fThreadDone && !m_bDisconnectPending) { if (m_bPassiveMode) { Sleep(100); continue; } if (!ReadFile(m_hComPort, m_szBuffer, DEFAULT_SIO_BUFFER, &dwRead, &osReader)) { // Read not delayed? if (GetLastError() != ERROR_IO_PENDING) XDEBUG("[CSerialComm] ReadFile in ReaderAndStatusProc.\r\n"); } #ifndef WINCE else { // Read Completed Immediately if ((dwRead != MAX_READ_BUFFER) && m_bDisplayTimeouts) XDEBUG("[CSerialComm] Read timed out immediately.\r\n"); } dwResult = WaitForMultipleObjects(3, arEvents, FALSE, STATUS_CHECK_TIMEOUT); switch(dwResult) { case WAIT_OBJECT_0 : // Thread Exit Event fThreadDone = TRUE; break; case WAIT_OBJECT_0 + 1 : // Read Completed if (!GetOverlappedResult(m_hComPort, &osReader, &dwRead, FALSE)) { if (GetLastError() == ERROR_OPERATION_ABORTED) XDEBUG("[CSerialComm] Read aborted.\r\n"); else ErrorHandler(const_cast<char*>("[CSerialServer] GetOverlappedResult (in Reader).\r\n")); } else { // Read Completed Successfully if ((dwRead != MAX_READ_BUFFER) && m_bDisplayTimeouts) XDEBUG("[CSerialComm] Read timed out overlapped.\r\n"); if (dwRead > 0) OnReceiveSession(m_pSaveSession, (char *)m_szBuffer, dwRead); } fWaitingOnRead = FALSE; break; case WAIT_OBJECT_0 + 2 : // Status Completed if (!GetOverlappedResult(m_hComPort, &osStatus, &dwOvRes, FALSE)) { if (GetLastError() == ERROR_OPERATION_ABORTED) XDEBUG("[CSerialServer] WaitCommEvent aborted.\n"); else ErrorHandler(const_cast<char*>("[CSerialServer] GetOverlappedResult (in Reader).\r\n")); } else { // status check completed successfully ReportStatusEvent(dwCommEvent); } fWaitingOnStat = FALSE; break; case WAIT_TIMEOUT: // If status checks are not allowed, then don't issue the // modem status check nor the com stat check if (!m_bNoStatus) { CheckModemStatus(FALSE); CheckComStat(FALSE); } break; default: XDEBUG("[CSerialServer] WaitForMultipleObjects(Reader & Status handles).\r\n"); break; } #else if (dwRead > 0) OnReceiveSession(m_pSaveSession, (char *)m_szBuffer, dwRead); #endif } OnLeaveSession(m_pSaveSession); DeleteSession(m_pSaveSession); // Set SendThread Exit Event SetEvent(m_hThreadExitEvent); m_bExitWriter = TRUE; WaitForSingleObject(m_hSendTerminateEvent, 5000); // Close event handles CloseHandle(osReader.hEvent); CloseHandle(osStatus.hEvent); // Set Terminate Signal SetEvent(m_hReadTerminateEvent); return 0; }
void CSerialServer::ReportStatusEvent(DWORD dwStatus) { BOOL fRING, fRLSD, fRXCHAR, fRXFLAG, fTXEMPTY; BOOL fBREAK, fCTS, fDSR, fERR; #ifdef WINCE CString strMessage; #else char szMessage[80]; #endif // Get status event flags. fCTS = EV_CTS & dwStatus; fDSR = EV_DSR & dwStatus; fERR = EV_ERR & dwStatus; fRING = EV_RING & dwStatus; fRLSD = EV_RLSD & dwStatus; fBREAK = EV_BREAK & dwStatus; fRXCHAR = EV_RXCHAR & dwStatus; fRXFLAG = EV_RXFLAG & dwStatus; fTXEMPTY = EV_TXEMPTY & dwStatus; // Construct status message indicating the // status event flags that are set. #ifdef WINCE strMessage = _T("[CSerialServer] EVENT: "); strMessage += fCTS ? _T("CTS ") : _T(""); strMessage += fDSR ? _T("DSR ") : _T(""); strMessage += fERR ? _T("ERR ") : _T(""); strMessage += fRING ? _T("RING ") : _T(""); strMessage += fRLSD ? _T("RLSD ") : _T(""); strMessage += fBREAK ? _T("BREAK ") : _T(""); strMessage += fRXFLAG ? _T("RXFLAG ") : _T(""); strMessage += fRXCHAR ? _T("RXCHAR ") : _T(""); strMessage += fTXEMPTY ? _T("TXEMPTY ") : _T(""); // If dwStatus == NULL, then no status event flags are set. // This happens when the event flag is changed with SetCommMask. if (dwStatus == 0x0000) strMessage += _T("NULL"); strMessage += _T("\r\n"); // Queue the status message for the status control XDEBUG(strMessage); #else strcpy(szMessage, "[CSerialServer] EVENT: "); strcat(szMessage, fCTS ? "CTS " : ""); strcat(szMessage, fDSR ? "DSR " : ""); strcat(szMessage, fERR ? "ERR " : ""); strcat(szMessage, fRING ? "RING " : ""); strcat(szMessage, fRLSD ? "RLSD " : ""); strcat(szMessage, fBREAK ? "BREAK " : ""); strcat(szMessage, fRXFLAG ? "RXFLAG " : ""); strcat(szMessage, fRXCHAR ? "RXCHAR " : ""); strcat(szMessage, fTXEMPTY ? "TXEMPTY " : ""); // If dwStatus == NULL, then no status event flags are set. // This happens when the event flag is changed with SetCommMask. if (dwStatus == 0x0000) strcat(szMessage, "NULL"); strcat(szMessage, " ------------\r\n"); // Queue the status message for the status control XDEBUG(szMessage); #endif // If an error flag is set in the event flag, then // report the error with the status message // If not, then just report the comm status. // if (fERR) // ReportCommError(); // Might as well check the modem status and comm status now since // the event may have been caused by a change in line status. // Line status is indicated by the CheckModemStatus function. CheckModemStatus(FALSE); // Since line status can affect sending/receiving when // hardware flow-control is used, ReportComStat should // be called to show comm status. This is called only if no error // was reported in the event flag. If an error was reported, then // ReportCommError was called above and CheckComStat was already called // in that function. if (!fERR) CheckComStat(FALSE); }