Hey, ich schreibe gerade ein Programm zum Senden und Empfangen von Daten über USB. Für das Senden werden die Daten in einen Frame verpackt: Anzahl Bytes: 1 1 1 ? 1 : CODE SUBCODE DATEN ; Nun soll es möglich sein mehrere Befehle Hintereinander zu verschicken. Dafür sollen die zu sendenen Befehle in einer Liste gespeichert (später soll diese Liste in einer Datei gespeichert werden). Für einen Befehl erstell ich mir folgende struct. struct befehl { int code; int subcode; CString daten; }; Die Liste soll nun diesen Typ verwalten. Dafür definiert ich sie wie folgt: CList<befehl,befehl&> befehlliste; Das ganze läuft als MDI Projekt, die struct hab ich in der CTestDoc-Klasse ganz unten hingeschrieben. Die Definition der Liste befindet sich in BOOL CTestDoc::OnNewDocument() Nun meine Frage zu struct in Visual C++, werden diese noch genutz? Normal würde man ja ne eigene Klasse erstellen, aber das lohnt sich doch net wirklcih. Wieso geht das mit dem struct nicht? Bzw. ist an der Definition der Liste was falsch?
Hallo Sebastian, probier's mal mit CList<struct befehl, struct befehl&>... Eine Struktur in C++ ist quasi wie ein Klasse, nur dass alle Member public sind. Gruß Patrick
Sebastian Ulmer wrote: > struct befehl > { > int code; > int subcode; > CString daten; > }; > > Die Liste soll nun diesen Typ verwalten. Dafür definiert ich sie wie > folgt: > > CList<befehl,befehl&> befehlliste; > > Das ganze läuft als MDI Projekt, die struct hab ich in der > CTestDoc-Klasse ganz unten hingeschrieben. Die Definition der Liste > befindet sich in > > BOOL CTestDoc::OnNewDocument() > > > Nun meine Frage zu struct in Visual C++, werden diese noch genutz? Sicher. Warum nicht. Ist ein legales C++ Sprachmittel. Für Typen wie du sie hast, also Container die im Wesentlichen eigentlich nur Daten halten ohne irgendwelche große Intelligenz mitzubringen, sind sie nach wie vor gut zu gebrauchen. (PS: Wusstest du, dass auch structs Member Funktionen haben können? Tatsächlich gibt es nur einen Unterschied zwischen struct und class: In einer struct ist per default alles public. Ansonsten sind struct und class absolut gleichwertig.) > Normal würde man ja ne eigene Klasse erstellen, aber das lohnt sich doch > net wirklcih. Wieso nicht? Bis auf das eine public ist doch alles gleich class befehl { public: int code; int subcode; CString daten; }; = vollwertiger Ersatz für deine Struct. > Wieso geht das mit dem struct nicht? Bzw. ist an der Definition der > Liste was falsch? Ne. Was soll daran falsch sein? Bis zu diesen letzten 2 Sätzen hast du noch gar nicht erwähnt, dass du ein Problem hast, bzw. wie sich das Problem manifestiert. Also: Hast du eine Fehlermeldung oder dergleichen?
Patrick wrote: > Hallo Sebastian, > > probier's mal mit CList<struct befehl, struct befehl&>... > Macht keinen Unterschied. Im Gegensatz zu C ist der Strukturname in C++ bereits ein eigener Datentyp.
Ich bekomm die Meldung das CList nicht deklariert wurde. Muss ich die Liste "befehlsliste" nochmal extra in der Header Datei deklarieren?
ok hatte nen tipfehler, hab "aftempl.h" statt "afxtempl.h" included, komischer das er das include geschluckt hat jetzt tut jedenfalls
was ist eigetnlcih der unterschied zwischen #include "afxtempl.h" und #include <afxtempl.h>
Sebastian Ulmer wrote: > was ist eigetnlcih der unterschied zwischen > > #include "afxtempl.h" > und > #include <afxtempl.h> Unterschiedliche Suchpfade auf denen ein Include File gesucht wird. Normalerweise wird <> für System-Includes verwendet, während "" für Projektspezifische Includes benutzt wird.
ok soweit funktioniert es, nur bisschen doof das ich die CList in der OnNewDocument deklariere. Ich muss die ja nachher serialisieren, dafür sollte es wohl eine Membervariable sein. Wenn ich nun aber die Deklaration als Membervariable reinmachen möchte, so meckert der Kompiler rum.
Sebastian Ulmer wrote:
> so meckert der Kompiler rum.
Mitlerweile solltest du schon wissen, dass eine
Aussage "der Compiler meckert" so wenig hilfreich ist, wie
ein Kühlschrank im Iglu eines Eskimo.
Der Compiler gibt eine Fehlermeldung. Welche?
Sry hatte mich verklickt und wollte den Beitrag dann nochmal ändern, aber das geht irgendwie nicht. Also der Kompiler sag was wegen 'CList' : Fehlende Speicherklasse oder Typbezeichner
Ich habe es auch schon mit einer Beispiel Headerdatei in der CList verwendet wird verglichen, aber eigentlich ist nichts anderst
Das ist soweit in Ordnung. stdafx.h ist inkludiert? afxtemp.h ist in der stdafx.h inkludiert? Wenn alles nichts hilft: Hast du schon mal einen "Rebuild All" probiert. Wenn der auch nicht hilft: Händisch das Debug Verzeichnis löschen und nochmal neu builden lassen. PS: Wozu brauchst du eigentlich soviele unterschiedliche Documente. Das ist schon etwas ungewöhnlich. Ich hatte zwar oft den Fall, daß ich zu einem Dokument viele verschiedene Views brauchte. Aber mehrere unteschiedliche Dokumenttypen in einem Programm, den Fall hatte ich noch nie. Und ich benutze die MFC seit immerhin 15 Jahren. Das heist natürlich nicht, dass es den Fall nicht gibt. Es mag schon Programme geben, die in ein und demselben Programm gleichzeit Bilder bearbeiten und Böresnkurse aus dem Web holen müssen, aber der Regelfall ist das nicht.
Hatte den include nur in der cpp-Datei drin, dachte das reicht. Naja viele Dokumente sind es net, nur 2. Das eine Dient zum Verwalten von Befehlslisten, die über USB versendet werden. Und da es sich dabei oft um viele kurze Befehle handelt, soll man die Listen abspeichern und wieder neu laden können. Das zweite Dokument dient zum Erstellen eines Testberichts aufgrund der Antworten die auf die Befehle über USB zurück kommen.
Sebastian Ulmer wrote: > Hatte den include nur in der cpp-Datei drin, dachte das reicht. > > Naja viele Dokumente sind es net, nur 2. > Das eine Dient zum Verwalten von Befehlslisten, die über USB versendet > werden. Und da es sich dabei oft um viele kurze Befehle handelt, soll > man die Listen abspeichern und wieder neu laden können. > Das zweite Dokument dient zum Erstellen eines Testberichts aufgrund der > Antworten die auf die Befehle über USB zurück kommen. Da würde ich mal eher sagen: Das ist ein Designfehler. Mehrere Dokumenttypen benutzt man dann, wenn das Programm 2 radikal verschiedene Funktionalitäten unterstützen muss und die Daten von dem einen Dokument nichts mit den Daten des anderen Dokuments zu tun haben. Wie im bereits angesprochenen Fall, dass ein und dasselbe Programm sowohl als Bildbearbeitungssoftware als auch als Web Server fungieren soll. Das eine hat mit dem anderen nichts zu tun aber aus irgendwelchen unerfindlichen Gründen möchte der Programmierer beide Funktionalitäten in einem Programm haben. Das ist aber in deinem Fall nicht so. Du hast nur ein Dokument, wobei das Dokument verschiedene Daten speichert. Auf der einen Seite die Befehlslisten. Auf der anderen Seite die tatsächlich abgesendeten Befehle und die Antworten darauf. Es spricht nichts dagegen sich jeweils eigene Klassen für die Liste von möglichen Befehlen zu machen und eine zweite Klasse die abgesendete Befehle und die Antworten darauf speichert. Dann hält das Dokument diese beiden Container als Member und verteilt die Aufträge entsprechend. Aber 2 getrennte Dokumente dafür würde ich nicht machen. Schon alleine aus dem Grund nicht, weil ja für das Versenden von Befehlen wahrscheinlich auf die Befehlsliste zurückgegriffen werden soll. Nur: Wie kommt den das 2. Dokument an diese Befehlsliste ran? Gar nicht! Weil die Daten im 2.ten Dokument (aus gutem Grund) vom 1ten Dokument komplett abgeschottet sind.
Klingt soweit ganz logisch. Dann werf ich das 2. Dokument wieder raus^^. Naja mein erstes Projekt in Visual C++, da kommen sicher noch mehr Fehler. Bin schon froh wenn das tut was es soll und ich mich wieder auf die Programmierung des Mikrocontollers an die die USB Befehle gehn widmen kann.
Nun hab ich meine Liste, die ich mit Daten befüllen kann. Diese soll in dem View als Tabelle mit 3 Spalten (Code,Subcode,Data)angezeigt werden. Dazu verwende ich einen CListCtrl. Befüllen tu ich die Liste am besten in der OnDraw-Methode der Viewklasse oder?
Sebastian Ulmer wrote: > Nun hab ich meine Liste, die ich mit Daten befüllen kann. > Diese soll in dem View als Tabelle mit 3 Spalten > (Code,Subcode,Data)angezeigt werden. > Dazu verwende ich einen CListCtrl. > Befüllen tu ich die Liste am besten in der OnDraw-Methode der Viewklasse > oder? Ja und nein. Der prinzipielle Datenfluss sieht immer so aus: Der Benutzer macht irgendeine Aktion an der Oberfläche. Handelt es sich um eine Manipulation der Daten, dann geht der Befehl an das Dokument. Das Dokument seinerseits macht die Änderung entweder selbst oder beauftragt einen seiner Member mit der Manipulation. Ist die Datenänderung abgeschlossen, so wird im Dokument: * SetModifiedFlag( TRUE ); aufgerufen, damit das Dokument als verändert markiert ist und die MFC beim Programmende nachfrägt, ob man nicht speichern möchte * UpdateAllViews aufgerufen Der UpdateAllViews geht alle zum Dokument registrierten Views durch und ruft bei jedem die Funktion OnUpdate auf. OnUpdate im View seinerseits wertet die Übergebenen Parameter aus (auf die Art kann man vom Dokument gezielt Befehle an jeden View durchbringen) und behandelt diese. Die Default Aktion von OnUpdate ist es, einen Invalidate() aufzurufen, der dafür sorgt, dass die OnDraw Funktion des Views aufgerufen wird. Damit zeichnet sich jeder View neu und zu diesem Behufe holt er sich vom Dokument die neuesten Daten. Man kann jetzt einige Punkte überspringen bzw. anpassen. In deinem Fall wäre das sogar angebracht. Denn OnDraw soll ja eigentlich nur das Fenster neu zeichnen. In deinem Fall hätte das dann den Nachteil, dass die Liste jedesmal neu befüllt wird, wenn zb das Fenster wieder in den Vordergrund geholt wird oder ein Fenster welches das Programmfenster verdeckte geschlossen wird. Das führt dann jedesmal zu einem kurzen Geflacker, wenn die Liste neu aufgebaut wird. Der Punkt ist der, dass das ListControl seinen OnDraw schon ganz alleine richtig macht. Das Befüllen der Liste ist aber nur dann notwendig, wenn sich die Daten auch tatsächlich ändern. Und genau da ist dein Einstiegspunkt. Das Dokument kann dem View gezielt mitteilen: "Jetzt haben sich die Daten verändert". Und zwar kann es das tun, indem es beim UpdateAllViews einen Code für das Hint Argument mitgibt (den Code vergiebst du selber). Die View sieht sich in ihrer eigenen OnUpdate Funktion diesen Code an und entscheidet: Jetzt haben sich die Daten geändert, ich muss das Control neu befüllen. Um damit nochmal zur Frage zurückzukommen: Macht man das im OnDraw. Ja: man kann es so machen und ist damit auf jeden Fall auf der sicheren Seite. Nein: man wird sinnvollerweise nicht so machen, weil sonst die Liste bei jeder Fensteroperation flackern wird.
Wie serialisier ich nun diese Liste? Ich hab ja die Funktion void CSendeDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // ZU ERLEDIGEN: Code zum Speichern hier einfügen } else { // ZU ERLEDIGEN: Code zum Laden hier einfügen } } vorgegeben. Kann ich die komplette Liste serialisieren? Oder muss ich mir jeden einzelnen Knoten holen und dort die einzelnen Werte serialisieren?
http://msdn.microsoft.com/en-us/library/6s70zdb8(VS.80).aspx http://msdn.microsoft.com/en-us/library/6bz744w8(VS.80).aspx http://msdn.microsoft.com/en-us/library/00hh13h0(VS.80).aspx Besonders der erste Link ist wichtig!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.