0

I am working on a MFC app that need to get the same output with the console app. The console app can display the input data from serial port. I want to get the input with the MFC dialog app and display it into edit control box. Since I am still new to C++, it seems quite challenging to me. Any suggestions for the workaround? Thanks in advance!

The console app code:

enum { EOF_Char = 27 };

int ShowError (LONG lError, LPCTSTR lptszMessage)
{
    // Generate a message text
    TCHAR tszMessage[256];
    wsprintf(tszMessage,_T("%s\n(error code %d)"), lptszMessage, lError);
    return 1;
}

int __cdecl _tmain (int /*argc*/, char** /*argv*/)
{
    CSerial serial;
    LONG    lLastError = ERROR_SUCCESS;
    lLastError = serial.Open(_T("COM1"), 0, 0, false);
    lLastError = serial.Setup(CSerial::EBaud9600, CSerial::EData8,CSerial::EParNone, CSerial::EStop1);
    lLastError = serial.SetupHandshaking(CSerial::EHandshakeHardware);

    // ** The query command to get input data **
    lLastError = serial.Write(":MEAS:FREQuency?\n");

    // Register only for the receive event
    lLastError = serial.SetMask(CSerial::EEventBreak |
                                CSerial::EEventCTS   |
                                CSerial::EEventDSR   |
                                CSerial::EEventError |
                                CSerial::EEventRLSD  |
                                CSerial::EEventRecv);
    if (lLastError != ERROR_SUCCESS)
         return ::ShowError(serial.GetLastError(), _T("Unable to set COM-port event mask"));

    // Use 'non-blocking' reads,cuz we don't know how many bytes will be received. 
    lLastError = serial.SetupReadTimeouts(CSerial::EReadTimeoutNonblocking);

    if (lLastError != ERROR_SUCCESS)
        return ::ShowError(serial.GetLastError(), _T("Unable to set COM-port read timeout."));

    // Keep reading data, until an EOF (CTRL-Z) has been received
    bool fContinue = true;

    do
    {
        // Wait for an event
        lLastError = serial.WaitEvent();

        if (lLastError != ERROR_SUCCESS)
            return ::ShowError(serial.GetLastError(), _T("Unable to wait for a COM-port event."));

        // Save event
        const CSerial::EEvent eEvent = serial.GetEventType();

    // Handle break event
    if (eEvent & CSerial::EEventBreak)
    {   printf("\n### BREAK received ###\n");  }
    // Handle CTS event
    if (eEvent & CSerial::EEventCTS)
    {   printf("\n### Clear to send %s ###\n", serial.GetCTS()?"on":"off");           }
    // Handle error event
    if (eEvent & CSerial::EEventError)
    {
        printf("\n### ERROR: ");
        switch (serial.GetError())
        {
        case CSerial::EErrorBreak:      printf("Break condition");          break;
        case CSerial::EErrorMode:       printf("Unsupported mode");         break;
        case CSerial::EErrorOverrun:    printf("Buffer overrun");           break;
        case CSerial::EErrorTxFull:     printf("Output buffer full");       break;
        default:                        printf("Unknown");                  break;
        }
        printf(" ###\n");
    }
    // Handle RLSD/CD event
    if (eEvent & CSerial::EEventRLSD)
    {   printf("\n### RLSD/CD %s ###\n", serial.GetRLSD()?"on":"off"); }

    // Handle data receive event
    if (eEvent & CSerial::EEventRecv)
    {
        // Read data, until there is nothing left
        DWORD dwBytesRead = 0;
        char szBuffer[101];
        do
        {
            // Read data from the COM-port
            lLastError = serial.Read(szBuffer,sizeof(szBuffer)-1,&dwBytesRead);
            if (lLastError != ERROR_SUCCESS)
                return ::ShowError(serial.GetLastError(), _T("Unable to read from COM-port."));

            if (dwBytesRead > 0)
            {
                // Finalize the data, so it is a valid string
                szBuffer[dwBytesRead] = '\0';

                // **Display the data/Need the same output for EditBox**
                printf("%s", szBuffer);
                // Check if EOF (CTRL+'[') has been specified
                if (strchr(szBuffer,EOF_Char))
                    fContinue = false;
            }
        }
        while (dwBytesRead == sizeof(szBuffer)-1);
    }
}
while (fContinue);

// Close the port again
serial.Close();
return 0;
}
jbapple
  • 3,297
  • 1
  • 24
  • 38
NguyenHai
  • 57
  • 1
  • 8
  • 1
    You are getting ahead of yourself. If you want to use MFC, you have to learn C++ **and** the Windows API first (see [Prerequisites for learning MFC programming](http://stackoverflow.com/q/18165076/1889329) for rationale). – IInspectable Sep 20 '16 at 11:40
  • @IInspectable Thanks for your advice, I am reviewing winAPI, but it is gonna take awhile. Can you help me some suggestions about which parts of learning MFC programming should I pay more attention to solve my question ? Thanks ! – NguyenHai Sep 21 '16 at 03:12
  • Anything you invest in MFC at this point will be wasted time. Nothing will make sense, and you will keep writing code based on ritualized observations. At some point you will have to **unlearn** all of those bad habits from your [cargo cult programming](https://en.wikipedia.org/wiki/Cargo_cult_programming) days again, wasting even more time. It's recommended that you [Learn to Program for Windows in C++](https://msdn.microsoft.com/en-us/library/windows/desktop/ff381399.aspx) (without MFC) first. – IInspectable Sep 21 '16 at 16:39
  • @IInspectable ! Thanks for your advice again ! I will follow it and get rid all of my bad habits in programming. – NguyenHai Sep 22 '16 at 23:46

1 Answers1

0

Since my knowledge in C++ was not good enough, so I was not aware of my problems were how to break the loop in the above code & the conversion between char array and CString. This is my answer :

 void Singlemode::OnBnClickedButton3()
 {
     CString str3;
    // TODO: Add your control notification handler code here
    CSerial serial;
    LONG    lLastError = ERROR_SUCCESS;
    lLastError = serial.Open(_T("COM1"), 0, 0, false);
    lLastError = serial.Setup(CSerial::EBaud9600, CSerial::EData8, CSerial::EParNone, CSerial::EStop1);
    lLastError = serial.SetupHandshaking(CSerial::EHandshakeHardware);
    lLastError = serial.Write(":MEAS:FREQuency?\n");

    // Register only for the receive event

    // Use 'non-blocking' reads, because we don't know how many bytes
    // will be received. This is normally the most convenient mode
    // (and also the default mode for reading data).
  bool fContinue = true;
   do
    {
        // Wait for an event
       lLastError = serial.WaitEvent();
       // Save event
      const CSerial::EEvent eEvent = serial.GetEventType();
      // Handle data receive event
      if (eEvent & CSerial::EEventRecv)
        {
        // Read data, until there is nothing left
        DWORD dwBytesRead = 0;
        char szBuffer[101];
        do
        {
            // Read data from the COM-port
            lLastError = serial.Read(szBuffer, sizeof(szBuffer) - 1, &dwBytesRead);

            if (dwBytesRead > 0)
              {
                // Finalize the data, so it is a valid string
                szBuffer[dwBytesRead] = '\0';

                // Display the data
                str3 = CString(szBuffer); // conversion to display
                show_result.SetWindowText(str3);
                fContinue = false;   // break the loop
                }
            } while (dwBytesRead == sizeof(szBuffer) - 1);
         }
    } while (fContinue);
  }
NguyenHai
  • 57
  • 1
  • 8