Fragen zur Nachrichtenbearbeitung der Klasse CSerialMFC



  • Hallo.

    In meinem Programm muss ich eine Digitalwaage und ein Multimeter messwerttechnisch erfassen. Beides besitzt eine serielle Schnittstelle. Um damit arbeiten zu können hab ich mir die viel empfohlene Klasse CSerial von www.codeprojekt.com besorgt und wie folgt verwendet:
    1. Erstellen eines Members meiner View-Klasse

    class CSerial2View : public CView
    {
    protected: // Nur aus Serialisierung erstellen
    	CSerial2View();
    	DECLARE_DYNCREATE(CSerial2View)
    
    // Attribute
    public:
    	CSerial2Doc* GetDocument() const;
    	CSerialMFC		m_serial;
    

    2. Initialisierung

    void CSerial2View::OnSchnittstelleStart()
    {
    	// TODO: Fügen Sie hier Ihren Befehlsbehandlungscode ein.
    	m_serial.Open(_T("COM1"),this,WM_NULL,0,0,0);
    	m_serial.Setup(CSerialMFC::EBaud9600,CSerialMFC::EData8,CSerialMFC::EParNone,CSerialMFC::EStop2);
    	m_serial.SetupHandshaking(CSerialMFC::EHandshakeHardware);
    	m_serial.SetMask(CSerialMFC::EEventRecv);
    }
    

    3. Aufräumen

    CSerial2View::~CSerial2View()
    {
    	if (m_serial.IsOpen())
    	m_serial.Close();
    }
    

    Das klappt soweit ganz gut. Meine Frage bezieht sich auf die Nachrichtenverarbeitung. Die Nachrichtenberabeitung habe ich wie in der Anleitung realisiert. Allerdings wird bei jedem Vorliegen von Daten zweimal in den Zweig "if (eEvent & CSerial::EEventRecv)" gesprungen (somit muss auch zweimal die Message abgeschickt werden, dass Daten anliegen). Jedoch ist abBuffer beim zweiten Mal leer. Warum? Um jetzt Daten rausziehen zu können überprüfe ich jedes Mal die Länge des Strings und nur wenn er Daten enthält übernehme ich die. Ich habe es so realisiert:

    LRESULT CSerial2View::OnSerialMsg (WPARAM wParam, LPARAM lParam)
    {
    	const CSerialMFC::EEvent eEvent = CSerialMFC::EEvent(LOWORD(wParam));
    	const CSerialMFC::EError eError = CSerialMFC::EError(HIWORD(wParam));
    
    	if (eError)
    		AfxMessageBox("Es ist ein interner Fehler aufgetreten!",MB_OK);
    
    	if (eEvent & CSerialMFC::EEventBreak)
    		AfxMessageBox("Breakevent",MB_OK);
    
    	if (eEvent & CSerialMFC::EEventError)
    		AfxMessageBox("Line-Status-Error",MB_OK);
    
    	if (eEvent & CSerialMFC::EEventRcvEv)
    		AfxMessageBox("Eventcharacter ist empfangen worden",MB_OK);
    
    	if (eEvent & CSerial::EEventRing)
    		AfxMessageBox("Ring",MB_OK);
    
    	if (eEvent & CSerialMFC::EEventSend)
    		AfxMessageBox("Alle Daten sind übertragen worden!",MB_OK);
    
    	if (eEvent & CSerialMFC::EEventCTS)
    		AfxMessageBox("CTS Signal",MB_OK);
    
    	if (eEvent & CSerialMFC::EEventDSR)
    		AfxMessageBox("DSR-Signal",MB_OK);
    
    	if (eEvent & CSerialMFC::EEventRLSD)
    		AfxMessageBox("RLSD-Signal",MB_OK);
    
    	if (eEvent & CSerial::EEventRecv)
    	{
    			DWORD dwBytesRead = 0;
        BYTE  abBuffer[100];
    	do
        {
            // Read data from the COM-port
    
            m_serial.Read(abBuffer,sizeof(abBuffer),&dwBytesRead);
    
    		abBuffer[dwBytesRead] = '\0';
    
         }
        while (dwBytesRead == sizeof(abBuffer));
    
    	CString TempString;
    	TempString=abBuffer;
    	if (TempString.GetLength()>0)
    		{
    			m_sAusgabe=abBuffer;
    			char testchar[256];
    			Invalidate();
    			RedrawWindow();
    		}
    
    	}
    	return 0;
    }
    

    Kennt jemand den Grund für dieses Verhalten? Weiterhin interessiert mich, warum die Schleifenbedingungen bitweise verknüft werden (also eEvent & CSerial::EEventRecv) und nicht mit &&?


Anmelden zum Antworten