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

📄 bcb_n9.htm

📁 C++Builder教学大全
💻 HTM
📖 第 1 页 / 共 2 页
字号:
      rlappedStr <br> 

      uct.hEvent is set, <br> 

      // but there are no bytes available to read. If you pro <br> 

      eed and ca <br> 

      ll <br> 

      // ReadFile(), it will return immediatly due to the asyn <br> 

      port setu <br> 

      p, but <br> 

      // GetOverlappedResults() will not return until the next <br> 

      character <br> 

      arrives. <br> 

      // <br> 

      // It is not desirable for the GetOverlappedResults() fu <br> 

      ction to b <br> 

      e in <br> 

      // this state. The thread shutdown event (event 0) and <br> 

      he WriteFi <br> 

      le() <br> 

      // event (Event2) will not work if the thread is blocked <br> 

      by GetOver <br> 

      lappedResults(). <br> 

      // <br> 

      // The solution to this is to check the buffer with a ca <br> 

      l to Clear <br> 

      CommError(). <br> 

      // This call will reset the event handle, and if there a <br> 

      e no bytes <br> 

      to read <br> 

      // we can loop back through WaitCommEvent() again, then <br> 

      roceed. <br> 

      // If there are really bytes to read, do nothing and pro <br> 

      eed. <br> 

      <br> 

      bResult = ClearCommError(port-&gt;m_hComm, &amp;dwError, &amp;comst <br> 

      t); <br> 

      <br> 

      if (comstat.cbInQue == 0) <br> 

      continue; <br> 

      } // end if bResult <br> 

      <br> 

      // Main wait function. This function will normally block the th <br> 

      ead <br> 

      <br> 

      <br> 

      // until one of nine events occur that require action. <br> 

      Event = WaitForMultipleObjects(3, port-&gt;m_hEventArray, false, IN <br> 

      INI <br> 

      TE); <br> 

      <br> 

      switch (Event) <br> 

      { <br> 

      case 0: <br> 

      { <br> 

      // Shutdown event. This is event zero so it wil <br> 

      be <br> 

      // the higest priority and be serviced first. <br> 

      <br> 

      port-&gt;m_bThreadAlive = false; <br> 

      <br> 

      // Kill this thread. break is not needed, but m <br> 

      kes me feel bette <br> 

      r. <br> 

      ExitThread(100); <br> 

      break; <br> 

      } <br> 

      case 1: // read event <br> 

      { <br> 

      GetCommMask(port-&gt;m_hComm, &amp;CommEvent); <br> 

      if (CommEvent &amp; EV_CTS) <br> 

      ::SendMessage(port-&gt;m_pOwner-&gt;Handle, WM <br> 

      COMM_CTS_DETECTED, (WPAR <br> 

      AM) 0, (LPARAM) port-&gt;m_nPortNr); <br> 

      if (CommEvent &amp; EV_RXFLAG) <br> 

      ::SendMessage(port-&gt;m_pOwner-&gt;Handle, WM <br> 

      COMM_RXFLAG_DETECTED, (W <br> 

      PARAM) 0, (LPARAM) port-&gt;m_nPortNr); <br> 

      if (CommEvent &amp; EV_BREAK) <br> 

      ::SendMessage(port-&gt;m_pOwner-&gt;Handle, WM <br> 

      COMM_BREAK_DETECTED, (WP <br> 

      ARAM) 0, (LPARAM) port-&gt;m_nPortNr); <br> 

      if (CommEvent &amp; EV_ERR) <br> 

      ::SendMessage(port-&gt;m_pOwner-&gt;Handle, WM <br> 

      COMM_ERR_DETECTED, (WPAR <br> 

      AM) 0, (LPARAM) port-&gt;m_nPortNr); <br> 

      if (CommEvent &amp; EV_RING) <br> 

      ::SendMessage(port-&gt;m_pOwner-&gt;Handle, WM <br> 

      COMM_RING_DETECTED, (WPA <br> 

      RAM) 0, (LPARAM) port-&gt;m_nPortNr); <br> 

      <br> 

      if (CommEvent &amp; EV_RXCHAR) <br> 

      // Receive character event from port. <br> 

      ReceiveChar(port, comstat); <br> 

      <br> 

      break; <br> 

      } <br> 

      case 2: // write event <br> 

      { <br> 

      // Write character event from port <br> 

      WriteChar(port); <br> 

      break; <br> 

      } <br> 

      <br> 

      } // end switch <br> 

      <br> 

      } // close forever loop <br> 

      <br> 

      return 0; <br> 

      } <br> 

      <br> 

      // <br> 

      // <br> 

      // start comm watching <br> 

      // <br> 

      BOOL TSerialPort::StartMonitoring() <br> 

      { <br> 

      DWORD lpThreadId; <br> 

      m_HThread =CreateThread(NULL, <br> 

      0, <br> 

      CommThread, <br> 

      this, <br> 

      0, <br> 

      &amp;lpThreadId); <br> 

      if(m_HThread==NULL) <br> 

      { <br> 

      ProcessErrorMessage("Create Thread Error"); <br> 

      return false; <br> 

      } <br> 

      return true; <br> 

      } <br> 

      <br> 

      // <br> 

      // Restart the comm thread <br> 

      // <br> 

      // <br> 

      BOOL TSerialPort::RestartMonitoring() <br> 

      { <br> 

      ResumeThread(m_HThread); <br> 

      return true; <br> 

      } <br> 

      <br> 

      // <br> 

      // Suspend the comm thread <br> 

      // <br> 

      BOOL TSerialPort::StopMonitoring() <br> 

      { <br> 

      SuspendThread(m_HThread); <br> 

      return true; <br> 

      } <br> 

      <br> 

      // <br> 

      // If there is a error, give the right message <br> 

      // <br> 

      void TSerialPort::ProcessErrorMessage(char* ErrorText) <br> 

      { <br> 

      char *Temp = new char[200]; <br> 

      <br> 

      <br> 

      LPVOID lpMsgBuf; <br> 

      <br> 

      FormatMessage( <br> 

      FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, <br> 

      NULL, <br> 

      GetLastError(), <br> 

      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language <br> 

      (LPTSTR) &amp;lpMsgBuf, <br> 

      0, <br> 

      NULL <br> 

      ); <br> 

      <br> 

      sprintf(Temp, "WARNING: %s Failed with the following error: \n%s\nPo <br> 

      rt: %d\n", (char*)ErrorText, lpMsgBuf, m_nPortNr); <br> 

      Application-&gt;MessageBox(Temp, "Application Error", MB_ICONSTOP); <br> 

      <br> 

      LocalFree(lpMsgBuf); <br> 

      delete[] Temp; <br> 

      } <br> 

      <br> 

      // <br> 

      // Write a character. <br> 

      // <br> 

      void TSerialPort::WriteChar(TSerialPort* port) <br> 

      { <br> 

      BOOL bWrite = true; <br> 

      BOOL bResult = true; <br> 

      <br> 

      DWORD BytesSent = 0; <br> 

      <br> 

      ResetEvent(port-&gt;m_hWriteEvent); <br> 

      <br> 

      // Gain ownership of the critical section <br> 

      EnterCriticalSection(&amp;port-&gt;m_csCommunicationSync); <br> 

      <br> 

      if (bWrite) <br> 

      { <br> 

      // Initailize variables <br> 

      port-&gt;m_ov.Offset = 0; <br> 

      port-&gt;m_ov.OffsetHigh = 0; <br> 

      <br> 

      // Clear buffer <br> 

      PurgeComm(port-&gt;m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_R <br> 

      ABO <br> 

      ABO <br> 

      RT | PURGE_TXABORT); <br> 

      <br> 

      bResult = WriteFile(port-&gt;m_hComm, <br> 

      / Handle to COMM Port <br> 

      port-&gt;m_szWriteBuffer, / <br> 

      / Pointer to message buffer in call <br> 

      ing finction <br> 

      strlen((char*)port-&gt;m_sz <br> 

      riteBuffer), // Length of message to s <br> 

      end <br> 

      &amp;BytesSent, <br> 

      / Where to store the number of bytes sent <br> 

      &amp;port-&gt;m_ov); <br> 

      / Overlapped structure <br> 

      <br> 

      // deal with any error codes <br> 

      if (!bResult) <br> 

      { <br> 

      DWORD dwError = GetLastError(); <br> 

      switch (dwError) <br> 

      { <br> 

      case ERROR_IO_PENDING: <br> 

      { <br> 

      // continue to GetOverlappedResu <br> 

      ts() <br> 

      BytesSent = 0; <br> 

      bWrite = false; <br> 

      break; <br> 

      } <br> 

      default: <br> 

      { <br> 

      // all other error codes <br> 

      port-&gt;ProcessErrorMessage("Write <br> 

      ile()"); <br> 

      } <br> 

      } <br> 

      } <br> 

      else <br> 

      { <br> 

      LeaveCriticalSection(&amp;port-&gt;m_csCommunicationSync); <br> 

      } <br> 

      } // end if(bWrite) <br> 

      <br> 

      if (!bWrite) <br> 

      { <br> 

      bWrite = true; <br> 

      <br> 

      bResult = GetOverlappedResult(port-&gt;m_hComm, // Handle to COM <br> 

      port <br> 

      <br> 

      &amp;port- <br> 

      m_ov, // Overlapped structure <br> 

      &amp;Bytes <br> 

      ent, // Stores number of bytes sent <br> 

      true); <br> 

      // Wait flag <br> 

      <br> 

      LeaveCriticalSection(&amp;port-&gt;m_csCommunicationSync); <br> 

      <br> 

      // deal with the error code <br> 

      if (!bResult) <br> 

      { <br> 

      port-&gt;ProcessErrorMessage("GetOverlappedResults() in Wri <br> 

      eFile()"); <br> 

      <br> 

      } <br> 

      } // end if (!bWrite) <br> 

      <br> 

      // Verify that the data size send equals what we tried to send <br> 

      if (BytesSent != strlen((char*)port-&gt;m_szWriteBuffer)) <br> 

      { <br> 

      printf("WARNING: WriteFile() error.. Bytes Sent: %d; Message Len <br> 

      th: <br> 

      %d\n", BytesSent, strlen((char*)port-&gt;m_szWriteBuffer)); <br> 

      } <br> 

      } <br> 

      <br> 

      // <br> 

      // Character received. Inform the owner <br> 

      // <br> 

      void TSerialPort::ReceiveChar(TSerialPort* port, COMSTAT comstat) <br> 

      { <br> 

      BOOL bRead = true; <br> 

      BOOL bResult = true; <br> 

      DWORD dwError = 0; <br> 

      DWORD BytesRead = 0; <br> 

      unsigned char RXBuff; <br> 

      <br> 

      <br> 

      for (;;) <br> 

      { <br> 

      // Gain ownership of the comm port critical section. <br> 

      // This process guarantees no other part of this program <br> 

      // is using the port object. <br> 

      <br> 

      EnterCriticalSection(&amp;port-&gt;m_csCommunicationSync); <br> 

      <br> 

      // ClearCommError() will update the COMSTAT structure and <br> 

      // clear any other errors. <br> 

      <br> 

      bResult = ClearCommError(port-&gt;m_hComm, &amp;dwError, &amp;comstat);  

      <br> 

      <br> 

      LeaveCriticalSection(&amp;port-&gt;m_csCommunicationSync); <br> 

      <br> 

      // start forever loop. I use this type of loop because I <br> 

      // do not know at runtime how many loops this will have to <br> 

      // run. My solution is to start a forever loop and to <br> 

      // break out of it when I have processed all of the <br> 

      // data available. Be careful with this approach and <br> 

      // be sure your loop will exit. <br> 

      // My reasons for this are not as clear in this sample <br> 

      // as it is in my production code, but I have found this <br> 

      // solutiion to be the most efficient way to do this. <br> 

      <br> 

      if (comstat.cbInQue == 0) <br> 

      { <br> 

      // break out when all bytes have been read <br> 

      break; <br> 

      } <br> 

      <br> 

      EnterCriticalSection(&amp;port-&gt;m_csCommunicationSync); <br> 

      <br> 

      if (bRead) <br> 

      { <br> 

      bResult = ReadFile(port-&gt;m_hComm, // Handl <br> 

      to COMM port <br> 

      &amp;RXBuff, <br> 

      / RX Buffer Pointer <br> 

      1, <br> 

      / Read one byte <br> 

      &amp;BytesRead, <br> 

      / Stores number of bytes read <br> 

      &amp;port-&gt;m_ov); <br> 

      / pointer to the m_ov structure <br> 

      // deal with the error code <br> 

      if (!bResult) <br> 

      { <br> 

      switch (dwError = GetLastError()) <br> 

      { <br> 

      case ERROR_IO_PENDING: <br> 

      { <br> 

      // asynchronous i/o is s <br> 

      ill in progress <br> 

      // Proceed on to GetOver <br> 

      appedResults(); <br> 

      bRead = false; <br> 

      break; <br> 

      } <br> 

      default: <br> 

      { <br> 

      // Another error has occ <br> 

      red. Process this error. <br> 

      port-&gt;ProcessErrorMessag <br> 

      ("ReadFile()"); <br> 

      break; <br> 

      } <br> 

      } <br> 

      } <br> 

      else <br> 

      { <br> 

      // ReadFile() returned complete. It is not neces <br> 

      ary to call GetOv <br> 

      erlappedResults() <br> 

      bRead = true; <br> 

      } <br> 

      } // close if (bRead) <br> 

      <br> 

      if (!bRead) <br> 

      { <br> 

      bRead = true; <br> 

      bResult = GetOverlappedResult(port-&gt;m_hComm, // Handl <br> 

      to COMM port <br> 

      <br> 

      <br> 

      &amp;port-&gt;m_ov, // Overlapped structure <br> 

      <br> 

      &amp;BytesRead, // Stores number of bytes read <br> 

      <br> 

      true); // Wait flag <br> 

      <br> 

      // deal with the error code <br> 

      if (!bResult) <br> 

      { <br> 

      port-&gt;ProcessErrorMessage("GetOverlappedResults( <br> 

      in ReadFile()"); <br> 

      <br> 

      } <br> 

      } // close if (!bRead) <br> 

      <br> 

      LeaveCriticalSection(&amp;port-&gt;m_csCommunicationSync); <br> 

      <br> 

      // notify parent that a byte was received <br> 

      ::SendMessage((port-&gt;m_pOwner)-&gt;Handle, WM_COMM_RXCHAR, (WPARAM) <br> 

      RXB <br> 

      uff, (LPARAM) port-&gt;m_nPortNr); <br> 

      } // end forever loop <br> 

      <br> 

      } <br> 

      <br> 

      <br> 

      // <br> 

      // Write a string to the port <br> 

      // <br> 

      void TSerialPort::WriteToPort(char* string) <br> 

      { <br> 

      assert(m_hComm != 0); <br> 

      <br> 

      memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer)); <br> 

      strcpy(m_szWriteBuffer, string); <br> 

      <br> 

      // set event for write <br> 

      SetEvent(m_hWriteEvent); <br> 

      } <br> 

      <br> 

      // <br> 

      // Return the device control block <br> 

      // <br> 

      DCB TSerialPort::GetDCB() <br> 

      { <br> 

      return m_dcb; <br> 

      } <br> 

      <br> 

      <br> 

      // <br> 

      // Return the communication event masks <br> 

      // <br> 

      DWORD TSerialPort::GetCommEvents() <br> 

      { <br> 

      return m_dwCommEvents; <br> 

      } <br> 

      <br> 

      // <br> 

      // Return the output buffer size <br> 

      // <br> 

      DWORD TSerialPort::GetWriteBufferSize() <br> 

      { <br> 

      return m_nWriteBufferSize; <br> 

      } <br> 

      <br> 

      //----------------------------------------------------------------<br> 

     </td> 

  </tr> 

</table> 

<br> 

</body> 

</html> 

⌨️ 快捷键说明

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