MVC mit Borland C++ (GUI)



  • Hi,

    was meinst du mit "wird direkt von Objektinspektor oder über freigegebene Property Parent zugewiesen"?

    Simon



  • witte schrieb:

    Das hat doch aber mit MVC nichts zu tun. Das ist doch einfache Vererbung wo nicht klar ist wozu sich der Aufwand lohnen soll.

    Das war vermutlich auch nur ein Anfang. Das "Feld" soll die View-Klasse sein.

    Wenn Du Deinen Lehrer/Mentor beeinducken willst dann kannst du ja die Spiellogik in extra Klassen auslagern, vllt sogar mit 2-3 Strategieklassen mit unterschiedlicher intelligenter Kompetenz/Stärke, von denen dann der Spieler eine als Gegner wählen kann.

    Und wenn man dann noch GUI-Kompoennten und Spieldaten voneinander trennt, dann hat man ein MVC. Ob sich das lohnt, ist eine Frage ob man die Beschäftigung mit dem Thema als Ziel ansieht.

    $phpler schrieb:

    was meinst du mit "wird direkt von Objektinspektor oder über freigegebene Property Parent zugewiesen"?

    Der Builder ist ein sogenanntes RAD-Tool. Er bietet an das die GUI-Komponenten zur Designzeit bequem mit Maus auf dem Form-Prototypen gesetzt werden können und mit dem Objektinspektor, der die Eigenschaften einer Komponente anzeigt, konfiguriert werden können. Damit das auch mit deinen View-Komponenten möglich wäre, müßen sie sich an gewisse Konventionen halten.

    bis bald
    akari



  • Der Builder ist ein sogenanntes RAD-Tool. Er bietet an das die GUI-Komponenten zur Designzeit bequem mit Maus auf dem Form-Prototypen gesetzt werden können und mit dem Objektinspektor, der die Eigenschaften einer Komponente anzeigt, konfiguriert werden können. Damit das auch mit deinen View-Komponenten möglich wäre, müßen sie sich an gewisse Konventionen halten.

    Achso... Ok, aber das wäre jetzt nicht so wichtig.
    Ich erzeuge alle Elemente mit Code, ich bin nicht so der Klicki-Fan.

    Was ich nicht verstehe, ist warum du das Top, Left, Height und Width-Zeugs alles auskommtentiert hast. Diese Werte brauche ich doch.

    SImon



  • Hallo

    Da du dein Feld von TLabel public ableitest, hat Feld auch alle Eigenschaften von TLabel. Du kannst also die Eigenschaften auch über die Properties setzen :

    // Deine Variante :
    Feld* feld = new Feld(owner, ... , 100, 200, 300, 400);
    // Meine Variante :
    Feld* feld = new Feld(owner);
    feld->Top = 100;
    feld->Left = 200;
    ...
    

    Natürlich ist auch deine Variante nicht falsch. Aber warum sollte man so einen umfangreichen Konstruktor definieren, wenn die Eigenschaften sowieso da sind? Ob du dadurch Übersichtlichkeit gewinnst ist Geschmackssache. Die VCL-Konformität verlierst du aber.

    bis bald
    akari



  • Achso, so meinst du das!

    Mir ist das mit dem Konstruktor lieber, wenn ich ehrlich bin.
    Dann kann ich nämlich im Konstrutkor noch überprüfen, ob die Werte auch alle passen.

    Simon



  • Wieso nicht einfach eine uebergeordnete Klasse TSpielfeld , die Objekte der Klasse TFeld als mehrschichtiges Array besitzt? Dann kannst du in deinem Programm einfach ein Objekt von TSpielfeld implementieren und entsprechende Funktionen, die das Bedienen des Spielfeldes angehen, in dieser Klasse zusammenfassen. 😉



  • So mach ich das jetzt.

    Allerdings habe ich ein Problem.

    Wenn ich im Form1 die Klasse Spielfeld instanziieren will, geht das.
    Wenn ich sie allerdigns als Attribut "abspeichern" will, komtm die Meldung "Typname erwartet".

    //---------------------------------------------------------------------------
    
    #ifndef tictactoeH
    #define tictactoeH
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    #include <ExtCtrls.hpp>
    #include <Menus.hpp>
    
    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    __published:	// Von der IDE verwaltete Komponenten
            TPanel *Panel1;
            TMainMenu *MainMenu1;
            TMenuItem *Spiel1;
            TMenuItem *Optionen1;
            TMenuItem *Neu1;
            TMenuItem *Hilfe1;
            TMenuItem *Info1;
            TMenuItem *Anleitung1;
            TMenuItem *Beenden1;
            void __fastcall FormCreate(TObject *Sender);
            void __fastcall Optionen1Click(TObject *Sender);
            void __fastcall Beenden1Click(TObject *Sender);
    private:	// Anwender-Deklarationen
    
            void __fastcall TForm1::onClick(TObject *Sender);
    
            void __fastcall adjust(TObject *Sender);
            Spielfeld* spielfeld;
    public:		// Anwender-Deklarationen
            __fastcall TForm1(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif
    

    (tictactoe.h)

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "tictactoe.h"
    #include "feld.h"
    #include "optionen.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    
    #pragma resource "*.dfm"
    TForm1 *Form1;
    TForm2 *Form2;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
      this->spielfeld = new Spielfeld(this);
      spielfeld->create();
    }
    
    void __fastcall TForm1::Optionen1Click(TObject *Sender)
    {
      Form2->Visible = true;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Beenden1Click(TObject *Sender)
    {
     Application->Terminate();
    }
    //---------------------------------------------------------------------------
    

    (tictactoe.cpp)

    Weiß jemand, was ich falsch mache?
    Kann es sein, dass die Klasse noch nicht bekannt ist, wenn ich sie in der Klassensignatur ankündige?

    Simon



  • Wenn ich class Spielfeld; ganz oben in der tictactoe.h schreibe, geht es.
    Es war wohl einfach so, dass die Klasse noch nicht bekannt war, als ich sie hier verwendet habe:

    private:	// Anwender-Deklarationen
    
            void __fastcall TForm1::onClick(TObject *Sender);
    
            void __fastcall adjust(TObject *Sender);
            Spielfeld* spielfeld;
    

    Ist das sauber so? (class Spielfeld;)

    SImon



  • Es wuerde genuegen, wenn du deine Headerdatei mit der Klasse Spielfeld vor oder gar in der Projekt-Headerdatei einbindest.



  • Dazu habe ich noch eine Frage.

    Ich komme immer wieder in Probleme, weil ich eine Klasse irgendwo verwende, die erst später deklariert wird. Dann muss ich entweder die Reihenfolge der Header-Dateien ändern oder die Klasse "bekannt machen".

    Allerdings gibt es auch Probleme, wenn ich zwar die Klasse kenne, aber ihre genauen Methoden noch nicht.

    Ich implementiere die Methoden immer direkt in der Klasse und nicht so:

    int Klasse::Methode()
    {
    return 0;
    }

    Sollte man das so machen?

    Wenn ja, wie mache ich das dann mit den Header-Dateien? SOll ich die "Signatur" der Klasse, die alle Attribute und Methoden enthält in einer anderen Datei speichern?

    Phpler


Anmelden zum Antworten