"Datenschnittstelle" zwischen Objekten - wie realisieren?



  • Hallo!

    Ich habe mal ein Programm zur Kommunikation mit der seriellen Schnittstelle geschrieben. Das ist ein Konsolenprogramm, und hat eine Klasse, die die komplette Kommunikation mit der Schnittstelle beinhaltet.

    Jetzt möchte ich das ganz gerne als Windows Programm mit der MFC umsetzen, aber weiterhin meine eigene Schnittstellenklasse benutzen.

    Ich habe eine Dialogfeldbasierte Anwendung angefangen, in der ich einen Hauptdialog habe, und einen Dialog, wo ich über Comboboxen die Parameter der seriellen Schnittstelle einstelle.
    Diese Parameter muss ich dann irgendwie meiner eigenen Klasse übergeben.

    Da ich es noch nicht so mit der MFC-Programmierung habe, weiß ich jetzt nicht genau, wie ich diese Daten in meine Klasse bekomme.(So eine Frage hat BlackViper unten ja auch schon mal gestellt, aber ich hätte ganz gerne ein paar konkrete Antworten auf meine konkreten Fragen).

    Also, wenn ich die Daten in den ComboBoxen eingestellt habe, dann kann ich ja quasi Membervariabeln des Dialogobjektes mit den Comboboxen mit den Werten füllen.

    Frage 1: Wenn ich jetzt den Dialog über OK verlasse, dann sind doch meine Membervariabeln (mit den Werten) futsch, da doch dann auch ihre Lebenszeit abgelaufen ist, oder?

    Frage 2: Wie kann ich dann eine Methode realisieren, die mir die eingegebenen Werte aus dem Dialog zurückgibt?(Kleines Codebeispiel wäre klasse !!)

    Frage 3: Wo speichere ich diese Werte dann am Besten? In der Aplikationsklasse, in der Hauptdialogsklasse, oder gebe ich sie am Besten gleich an meine eigene Klasse weiter?

    Frage 4: Wie gehe ich vor, wenn ich am liebsten so viele Membervariabeln wie möglich als private deklarieren möchte? Ist das in diesem Fall überhaupt möglich, oder braucht man zum Datenaustausch zwischen Klassen eben ein paar public deklarierte Variabeln, weil es anders nicht geht?

    Frage 5: Gibt es vielleicht irgendwo gute Literatur/Internetlinks, wo so etwas wie das "Schnittstellenerstellen" für (MFC-)Klassen beschrieben ist?

    Ich hoffe ihr versteht mein Problem, und könnt mir weiterhelfen.

    Gruß
    Maik



  • Kiamur schrieb:

    Frage 1: Wenn ich jetzt den Dialog über OK verlasse, dann sind doch meine Membervariabeln (mit den Werten) futsch, da doch dann auch ihre Lebenszeit abgelaufen ist, oder?

    sorry, ist mir jetzt zu viel, ich beantworte aber frage 1, brauchst nur noch 4 andere, die dir die andern fragen beantworten 🙂

    wenn du OK drueckst, ist die komplette anwendung zu. du kannst aber das OK abfangen und kurz davor noch etwas ausfuehren; zB kannst du deinem schnittstellenobjekt noch ein Objekt uebergeben, dass die gewaehlten einstellungen enthaelt, oder eben in die variablen der schnittstelle die comboboxinhalte schreiben und dann die SchickeDatenUeberSchnittstelle methode aufrufen.
    alternativ kannst du ja auch einen 'schicken' button zeichnen, der dann die daten schicken laesst, und der dialog bleibt offen 🙂

    Esco



  • Kiamur schrieb:

    Ich habe eine Dialogfeldbasierte Anwendung angefangen, in der ich einen Hauptdialog habe, und einen Dialog, wo ich über Comboboxen die Parameter der seriellen Schnittstelle einstelle.

    Also wenn ich dich richtig verstehe, wird aus dem Hauptdialog der Dialog zum Einstellen der Parameter geöffnet. Macht der HAuptdialog noch mehr?

    Kiamur schrieb:

    Frage 3: Wo speichere ich diese Werte dann am Besten? In der Aplikationsklasse, in der Hauptdialogsklasse, oder gebe ich sie am Besten gleich an meine eigene Klasse weiter?

    Das kommt ganz darauf an, wo du die Werte brauchst. Ich gehe mal davon aus, daß du die Einstellungen für die serielle Schnittstelle einmal oder zumindest nicht all zu oft vornimmst und dann aus dem Hauptdialog verschiedenste Daten über deine bestehende Schnittstellenklasse an die serielle Schnittstelle schicken willst. In dem Fall wäre sicherlich die der Hauptdialog die richtige Stelle. Sollen die Einsellungen der seriellen Schnittstelle jedoch nur einmal vorgenommen werden, dann kannst du sie auch gleich an deine Klasse schicken.

    Kiamur schrieb:

    Frage 4: Wie gehe ich vor, wenn ich am liebsten so viele Membervariabeln wie möglich als private deklarieren möchte? Ist das in diesem Fall überhaupt möglich, oder braucht man zum Datenaustausch zwischen Klassen eben ein paar public deklarierte Variabeln, weil es anders nicht geht?

    private-Variablen sind ansich kein Problem. Entweder du deklarierst diverse Funktionen, mit denen du diese Variablen setzt bzw. abrufst, oder due deklarierst die Klasse, die auf die private-Variablen zugreifen dürfen als friend.

    Gruß WinCoder



  • Zu 2.: Wenn Du eine Dialog öffnest erstellst du ja eine Instanz der DLG-Klasse und über die rufst du DoModal auf.

    DoModal kehrt erst zurück wenn der aufgerufenen DLG geschlossen wird.
    Und gem. den Grundlagen von C++ existiert die Klasseninstanz noch. SIOmit kann man auch auf Variablen, Funktionen, etc. dieser Klasse zugreifen.
    Eine Suche nach DoMOdal im Forum hilft.

    Zu. 3:
    Die Parameter haben im HauptDialog eigentlich nichts verloren. Ein Dialog soll Daten ausgeben und nicht speichern. Da du bereits ein Kalsse für die SChnittstelle hast kannst du die Daten auch dort ablegen. Ist aber Designsache. Funktion soll aber von GUI getrennt werden und die Parameter haben mit GUI nichts zu tun. Weiters benötigst sie ja sowieso in deiner SER-Klasse.



  • Hab mir das ganze jetzt nicht durchgelesen aber:

    Ich habe den Standartkonstruktor so abgeändert das ich eine Struktur (kannst du auch anders handhaben zB. alle Daten einzeln übergeben) übergebe in welcher alle benötigten Daten stehen.
    Dadurch kann ich meinen Dialog schon mal auf die alten Werte einstellen und bei verlassen mit ONOK kann ich die Werte ändern (beim verlassen mit ONCANCEL mach ich nichts).

    class CComSetDlg : public CDialog
    {
    // Konstruktion
    public:
    	CComSetDlg(SPort *port,CWnd* pParent = NULL);   // Standardkonstruktor
    

    Sieht bei mir so aus:

    struct SPort
    {
    	int iPort;
    	int Baud;
    	int Size;
    	int Parity;
    	int stopbit;
    	int fRtsControl;
    	int Timeout;
    	int TotalTimeout;
    };
    

    Andere Möglichkeit

    Beim verlassen des Dialogs mit ONOK führe ein UpdateData durch um deine Memaber Variablen zu aktualisieren. Danach rufst du aus der aufrufenden Klasse die Funktion "zum Holen der Daten aus dem Dialog" auf.

    int iPort;
    int Baud;
    int Size;
    int Parity;
    int stopbit;
    int fRtsControl;
    int Timeout;
    int TotalTimeout;
    
    CComSetDlg comDlg;
    
    if(comDlg.DoModal()==IDOK)//Wenn mit OK beendet wurde (ONOK)
    {
    	//entweder so
    	comDlg.GetData(&Baud,&Size,&.....);
    	//oder so
    	Baud = comDlg.GetBaud();
    	Size = comDlg.GetSize();
    	//.............
    }
    

    Hoffe diese Ansätze helfen ein wenig weiter.

    Mfg, BigSigi

    PS: Die Daten im Dialog verschwinden erst wenn das Objekt des Dialoges die Gültigkeit verliert (in meinem Fall comDlg)!



  • Hallo an alle!

    Vielen Dank erst einmal für eure Tips!

    Ich hoffe, dass ich damit etwas zu Stande bringe.

    Vielleicht noch einmal eine Frage:

    Ich habe den Hauptdialog:

    class Hauptdialog : public CDialog
    {
    ...
    public:
    datenstruct DatenHolen(){int BaudRate, ...}
    ...
    }
    

    und meinen Einstellungsdialog, der vom Hauptdialog aus aufgerufen wird

    class Einstellungsdialog : public CDialog
    {
    ...
    }
    

    Müsste ich dann z.B beim klicken auf OK im Einstellungsdialog die DatenHolen() Methode vom Hauptdialog aufrufen können, um die Einstellungen weiterzureichen?

    Ich weiß, ich könnte das ausprobieren (werde ich auch), aber falls etwas bei mir nicht klappen sollte, dann weiß ich wenigstens, dass ich bei der Umsetzung etwas falsch gemacht habe . . .

    Gruß
    Maik



  • void Hauptdialog::OnButtenPortSettings
    {
       Einstellungsdialog dlg(/*Daten übergeben wenn Dialog die alten Daten anzeigen soll*/);
       if(dlg.DoModal()==IDOK)//Wenn OK gedrückt wurde
       {
          //Im Hauptdialog werden dann die Daten vom Einstellungsdialog geholt
          //Dazu rufen wir die Methode aus dem Einstellungsdialog auf
    
          .... dlg.GetData(......);
       }
    }
    
    class Einstellungsdialog : public CDialog
    {
       //Entweder so
       SData GetData(){return datastrukt;};
       //Oder so
       void GetData(SData *data){data->Baut = m_Baud; usw.....};
       //oder so
       int GetBaut(){return m_Baud;};
       int Get........
       //oder ... ;-) es gibt viele Möglichkeiten
    
       OnOK(){UpdateData(); CDialog::OnOK()};
    
    }
    

    Ich würd auf jeden Fall beim Aufruf des Einstellungsdialoges die alten Daten übergeben. Dann sieht man im Dialog gleich was eingestellt ist. Dann muß man nicht alle Werte neu einstellen.

    Das geht meiner Meinung nach am besten wenn du im Konstruktor einen Zeiger auf die alten Daten übergibst. Den Zeiger im Einstellungsdialog zwischenspeicherst, und beim Beenden mit OnOk die Daten auf die der Zeiger zeigt veränderst.
    Dadurch ersparst du dir auch das zurückholen der Daten aus dem Dialog.
    Jetzt brauchst du nur mehr im Hauptdialog abfragen ob mit OK beendet wurde und dann den COM-Port neu Initialisieren.

    Mfg, BigSigi

    PS: 3xEditieren 😃 und das wegen Rechtschreibfehler 🤡 Hab sicher noch ein paar, aber jetzt is Schluß 😉



  • Hallo BigSigi!

    Ich glaube jetzt verstehe ich es schon etwas besser.

    Vielen Dank!

    Gruß
    Maik



  • ja hoffendlich 😉

    bye, BigSigi



  • Ähm, ich bins noch mal . . .

    also, falls BigSigi hier noch mal reinschaut, oder jemand anders . . .

    Wie kann ich meinem Einstellungsdialog eine Datenstruktur beim Aufruf mitgeben? Also ich habe versucht den Konstruktor zu erweitern, wie BigSigi vorgeschlagen hat, aber leider führt das nicht zum Erfolg, sondern zu fehlermeldungen

    class CComSetDlg : public CDialog
    {
    // Konstruktion
    public:
        CComSetDlg(SPort *port,CWnd* pParent = NULL);   // Standardkonstruktor
    

    Mir ist auch irgendwie nicht klar, wie die SPort Struktur als Datentyp übergeben werden soll.
    Mal angenommen ich deklariere die SPort Struktur im Haupddialog, dann ist der Datentyp doch in dem Einstellungsdialog nicht vorhanden.
    Deklariere ich im Einstellungsdialog auch eine SPort Struktur, dann denkt der Compiler es handelt sich um inkompatible Datentypen. Zumindest habe ich das aus den Fehlermeldungen herausgelesen.

    Irgendwo klemmt es noch bei mir.

    Könnt ihr mir vielleicht mal Code posten, wo ihr einen Dialog aus einem anderen Dialog aufruft, und dem neuen Dialog dabei einen Zeiger auf eine Struktur mitgebt?

    Vielen Dank!

    Gruß
    Maik

    P.S.: Einzelne Daten mit einem Grunddatentyp zurückgeben klappt schon, aber die Idee mit der Struktur finde ich irgendwie doch eleganter . . .



  • Deklariere die Struktur in der .h-Datei deiner Comschnittstellenklasse.
    In der .h-Datei des Einstellungsdialoges includiere deine .h-Datei deiner Comschnittstellenklasse.

    Mfg, Sigi


Anmelden zum Antworten