Serielle Kommunikation und das WM_Nachrichtensystem
-
Vielleicht war es ja auch nur der übliche "Fehler" MFC dynamisch oder statisch.

Aber dazu hätte man die Meldung sehen müssen.
-
hallo erstmal,
ich schreib einfach mal in diesen beitrag rein da mein problem sich ebenfalls auf die oben genannte klasse bezieht.
ich bin neuling auf dem gebiet programmierung und habe mir gleich mal das gebiet kommunikation über die serielle schnittstelle als spielwiese ausgesucht.
als konsolenanwendung funktioniert auch alles einwandfrei.nun habe ich jedoch über den MFC-Anwendungsassistenten ein neues projekt erstellt, welches nur einen "EXIT-Button", einen "Empfangs-Button" und ein Kombinationsfeld zur darstellung der empfangenen daten besitzt.
nun mein problem:
wenn ich auf den empfangsbutton klicke bleibt das progrämmchen hängen bis eine nachricht eingegangen ist(danach ists wieder normal). ich möchte jedoch quasi nur auf empfangsbereitschaft gehen und dann alle nachrichten "abfangen".hier mal der codeschnippsel:
void CTesgui2Dlg::OnEmpfangen() { char str[100]; // TODO: Code für die Behandlungsroutine der Steuerelement-Benachrichtigung hier einfügen CSerial serial; LONG lLastError = ERROR_SUCCESS; // Attempt to open the serial port (COM1) lLastError = serial.Open(_T("\\\\.\\COM1"),0,0,false); // Setup the serial port (9600,8N1, which is the default setting) lLastError = serial.Setup(CSerial::EBaud9600,CSerial::EData8,CSerial::EParNone,CSerial::EStop1); // 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). lLastError = serial.SetupReadTimeouts(CSerial::EReadTimeoutNonblocking); // 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[2]; 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 sprintf(str,"%s", szBuffer); m_Ausgabe.AddString(str); } } while (dwBytesRead == sizeof(szBuffer)-1); } // Close the port again serial.Close(); }schon mal danke für evtl. hilfe und sorry für diesen textberg^^
grüssle
balu
-
hmm sry ich musste noch nix mit der Seriellen Schnittstelle machen... aber ich würde evt. einfach das Empfangen in einen Thread packen und das GUI in einen anderen

-
Oder wenn Du schon MFC verwendest, dann verwende doch CSerialMFC! Dann bekommst Du eine Message, wenn sich was tut...
-
ok, die idee hatte ich auch schon. allerdings werde ich aus dem MFC-Beispiel welches bei der klasse beiliegt nicht schlau.
vom ablauf her müsste es doch eigentlich wie folgt gehen oder?1. klick auf empfangsbereitschaft
2. warten auf event
3. event verarbeiten (anzeigen der daten)
4. wieder bei 2.vielen dank nochmal für die hilfe. hoffe ich komme damit noch weiter

gruss
balu
-
Wenn Du die MFC-Klasse verwendest musst Du gar nicht warten, da Du dann eine Message bekommst (bzw. die "OnSerialMsg" wird aufgerufen).
-
ok, von der logik her denk ich mal das es mir klar ist.
mein problem liegt wahrscheinlich eher darin, das ich bisher nur mit der konsole gearbeitet habe und das hier meine "MFC-entjungferung" ist.
kannst du mir vieleicht ein einfaches beispiel sagen, wie ich "OnSerialMsg" anwende?
hab mich hier irgendwie total festgefahren und wär für eine hilfe von einem pro riesig dankbar.
gruss balu
-
Balu123321 schrieb:
kannst du mir vieleicht ein einfaches beispiel sagen, wie ich "OnSerialMsg" anwende?
Du musst Dir eigentlich nur das mitgelieferte Beispiel genau anschauen... was anderes kann ich Dir auch nicht zeigen

-
Ich fürchte, es scheitert daran, dass er noch nicht mit dem Prizip und der Handhabung von Nachrichten vertraut ist.

-
naj...dank dir auf jeden fall. hast es ja versucht.
das mitgelieferte beispiel ist halt für nen anfänger ziemlich komplex, da es aus mehreren dialogen besteht und ich da einfach nich durchblicke wo ich überhaupt anfangen soll.
und ich schau es mir ja schon seit 3 tagen an und bin noch keinen millimeter weiter gekommen.
aber dann guck ichs mir halt immer weiter an
..aber sollte ich dann doch weiterkommen und konkretere fragen haben scheue ich mich nicht diesten tread aus der versenkung zu holen

gruss
baluedit: @estartu: du sprichst mir aus dem herzen aber ohne das ohne hilfe zu verstehen ist halt für nen anfänger ein brocken
-
habt ihr vielleicht irgendwo irgendwie ein sehr einfaches bespiel zu nachrichtenhandling?
vielleicht komm ich ja dann auf den trichter
gruss balu
-
Ein ganz einfaches Beispiel:
Du hast einen Dialog. Dadrauf ist ein Knopf.
Der Knopf hat eine Nachricht BN_CLICKED, diese wird dem Dialog von Windows geschickt, wenn der User auf dem Knopf die linke Maustaste drückt.
In der MessageMap (such im Code) steht das Makro ON_BN_CLICKED, was dem Dialog sagt, welche Funktion er in dem Fall aufrufen soll, wenn der Knopf geklickt wird.ON_BN_CLICKED(IDC_KNOPF, OnBnClickedKnopf)Es wird also OnBnClickedKnopf aufgerufen, ganz automatisch.

So, das war die Kurzversion, aber jetzt hast du ne Grundlage zum Fragen stellen.

-
Les dir am besten mal ein MFC-Tutorial durch, ich kann dir dieses hier sehr empfehlen: http://www.cpp-tutor.de/mfc/toc.htm
Dort wird auch das Nachrichtensystem von Windows sehr gut erklärt. Kurz, übersichtlich und mit vielen Beispielen.

-
ok, so langsam bekomm ich wieder hoffnung.
des mit dem ON_BN_CLICKED hab ich ja schon mal herausgefunden und konnt auch was damit anfangen.
prinzipiel stell ich mir das jtz so vor, dass ich zu meinem "IDC_COMBO1"-objekt irgendwie die Nachricht "OnSerialMsg" hinzufüge ( da ich ja die daten im Combofenster darstellen will) oder muss ich dafür ein eigenes objekt erstellen?aber nu erstmal fleissig tutorial lesen

vielen dank bis jtz
balups: kann man dem thema eigentlich nachträglich noch nen richtigen namen geben?
-
Ich hoffe diese Überschrift ist etwas besser;-)
Vielen Dank für die guten Antworten und Fragen.
Viele Grüße
Sven
-
^^up
hallo mal wieder,
wollt mich nur mal bei euch allen bedanken... seit 5 min fang ich jtz erfolgreich die OnSerialMsg ab
*freu*hat zwar etwas länger gedauert abe besser spät als nie.
aber bei meinem nächsten problem bin ich wieder hier mit fragen
vielen dank!!!
gruss balups:hoffe das war jtz nich zu viel spam

-
Könntest du beschreiben wie du da vorgegangen bist?
Ich würde das gerne nachvollziehen.
Du würdest mir wirklich sehr helfen!Viele Grüße
Sven!
-
ok...da selber anfänger versuch ichs mal mit einfachen worten.
ich hab das ganzew in meinen dialog reingefummelt
dafür:1. in die klasse (in die headerdatei) folgendes reinschreiben
class NameDeinerKlasse : public CDialog { //... public: //... protected: //... //}}AFX_MSG afx_msg LRESULT OnSerialMsg (WPARAM wParam, LPARAM lParam); DECLARE_MESSAGE_MAP() //...2. in deine cpp-datei
BEGIN_MESSAGE_MAP(NameDeinerKlasse, CDialog) //{{AFX_MSG_MAP(NameDeinerKlasse) //... //}}AFX_MSG_MAP ON_WM_SERIAL(OnSerialMsg) END_MESSAGE_MAP()3. ebenfalls in deine cpp-datei
LRESULT NameDeinerKlasse::OnSerialMsg (WPARAM wParam, LPARAM /*lParam*/) { MessageBox("Serialle Nachricht erhalten", "Hinweis"); return 0; }und schon musste wenn bei dir was über die serielle schnittstelle kommt ne messagebox auftauchen (taucht bei jedem zeichen auf also nich gleich riesige datenmengen drüberschicken sonst biste ewig am klicken
)
kannst anstelle der messagebox hier natürlich alles machen was du willst sobald was über die leitung kommt.noch ein hinweise:
immer erst nach dem//}}AFX_MSGwas schreiben sonst kommt der "klassen-assistent" durcheinander
und noch was fast vergessen...du musst an geeigneter stelle natürlich noch den port öffnen und einstellen.
hoffe jtz klappt es dann auch bei dir
gruss
balu
-
Balu123321 schrieb:
noch ein hinweise:
immer erst nach dem//}}AFX_MSGwas schreiben sonst kommt der "klassen-assistent" durcheinander
Das AFX_MSG gibts bei der Version 2003 nicht mehr, da kannst Du es in die Messagemap direkt reinschreiben. Ich mache das im Grunde auch so wie Du. Allerdings wird bei mir die OnSerialMsg beim Anliegen von Daten zweimal aufgerufen. Als Bsp.: Du schickst von dem angeschlossenen Gerät einen Buchstaben. Dann wird die Message abgeschickt und wenn man dann mit serial.read() das ganze ausliest steht dann auch der Buchstabe im String drin. Danach wird die Message aber nochmal aufgerufen und der String beim auslesen ist leer (muss er ja auch, hat ja keine weiteren Daten gegeben). Ist das bei Dir auch so? Müssten ja dann 2 Messageboxen erscheinen.
-
ok...ich hab msvc++ 6.0 . da kommt er durcheinander

naja...des mit der messagebox war nur zur veranschaulichung. die kommt aber nur einmal pro gesendetes zeichen.
wenn ich alles in einen string schreibe wir aber auch für jedes zeichen OnSerialMsg aufgerufen(jedenfalls laut debugger).
was mich nur wundert ist, ich gebe die ankommenden datenin einem combobox-feld aus und der macht mir immer ne leerenstring dazwischen
also quasi
1.zeile "string der gesendeten daten"
2.zeile "leer"
3.zeile "string"
...
aber aufgerufen wird es wie gesagt nur für jedes zeichen
gruss baluedit: achso und einlesen tue ich wie im beispiel, welches bei der klasse beiliegt