Sehr dringend: Objekt einer Klasse wird innerhalb eines Forms erzeugt. Wie IN der Klasse auf Form zugreifen?
-
Ich wünsche einen, hoffentlich, guten Montag Morgen.
Ich habe hier ein kleines Problem. Und zwar habe ich eine Klasse A (beispielhafter Name) geschrieben, die ich in einer simplen Form Anwendung verwende. Ein Objekt dieser Klasse wird im Formular erzeugt. Nun möchte ich allerdings in Funktionen INNERHALB dieser Klasse A auf das Formular zugreifen.
Ein Beispiel: Es liegt ein TShape im Formular. Dieses möchte ich mittels der Eigenschaft Top verschieben. Das Ganze möchte ich allerdings in einer Funktion in Klasse A machen.
Mein erster Ansatz war einfach einen Wertekonstruktor zu benutzen und diesem einen Zeiger auf Form zu verpassen. Vor der Implementierung der Klasse A hat das wunderbar funktioniert. Sobald ich sie implementiert hatte war es geschehen. (A.h ist im Header von Form1 eingebunden. Objekt von A wird unter public der Form Klasse erzeugt.
Das Problem ist ich bräuchte relativ dringend Hilfe. Auch wenn das Problem für einige Trivial ist. Ich bin eben noch im Anfangsstadium der Oberflächenprogrammierung.
Vielen Dank für die Hilfe
-
Hallo
Mein erster Ansatz war einfach einen Wertekonstruktor zu benutzen und diesem einen Zeiger auf Form zu verpassen.
Das ist auch der richtige Ansatz
Vor der Implementierung der Klasse A hat das wunderbar funktioniert. Sobald ich sie implementiert hatte war es geschehen. (A.h ist im Header von Form1 eingebunden. Objekt von A wird unter public der Form Klasse erzeugt.
Was verstehst du unter "war es geschehen"? Fehlermeldung? Code?
bis bald
akari
-
Ach sorry falsche Formulierung. Ich habe das auf dem Sprung zu einem Kunden geschrieben.
Also folgendes. Standard C++ Builder Form Anwendung. Ich habe eine Klasse CElevator erzeugt (Bin etwas eingerostet und spiele nun ein wenig rum um wieder rein zu kommen. Also bitte nicht über die Sinnlosigkeit des Programms lachen. Es geht um grundlegene Dinge. Diese Kommunikation Klasse<->Form werde ich brauchen.)
Der Header der Klasse ist im Header des Forms eingebunden. Ich kopiere einfach mal die Header hier rein.
Hauptapplikation. Hier ist alles wie vom Builder erzeugt. Nichts geändert.
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop //--------------------------------------------------------------------------- USEFORM("Form.cpp", Form1); //--------------------------------------------------------------------------- WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { try { Application->Initialize(); Application->CreateForm(__classid(TForm1), &Form1); Application->Run(); } catch (Exception &exception) { Application->ShowException(&exception); } catch (...) { try { throw Exception(""); } catch (Exception &exception) { Application->ShowException(&exception); } } return 0; } //---------------------------------------------------------------------------Hier der Kopf des Forms.
//--------------------------------------------------------------------------- #ifndef FormH #define FormH //--------------------------------------------------------------------------- #include "CElevator.h" #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> #include <ExtCtrls.hpp> //--------------------------------------------------------------------------- class TForm1 : public TForm { __published: // Von der IDE verwaltete Komponenten TRadioButton *OStateB1; TRadioButton *OStateB2; TRadioButton *StateCallUp; TRadioButton *StateCallDown; TButton *BCallUp; TButton *BCallDown; TRadioButton *IStateB1; TRadioButton *IStateB2; TButton *IB2; TButton *IB1; TImage *Image1; TShape *Shape1; TButton *Button1; TButton *Button2; void __fastcall Button1Click(TObject *Sender); void __fastcall Button2Click(TObject *Sender); private: // Benutzer-Deklarationen public: // Benutzer-Deklarationen int nWidthPB; int nHeightPB; __fastcall TForm1(TComponent* Owner); void TForm1::DrawElevator(); }; //--------------------------------------------------------------------------- extern PACKAGE TForm1 *Form1; //--------------------------------------------------------------------------- #endifUnd der Kopf meiner Klasse:
//--------------------------------------------------------------------------- #include <Form.h> #ifndef CElevatorH #define CElevatorH class CElevator { public: //Konstruktor CElevator (); // CElevator (TForm1* fom) {Formu=fom;}; //Destruktor ~CElevator (); // TForm1* Formu; //Drücken der Knöpfe void Press_Up(); void Press_Down(); void Press_G(); void Press_B(); private: //Standort des Fahrstuhls. -1 fährt, 1 Bahnsteig, 2 Galerie int nFloor; //Tür 0 geschlossen, 1 offen bool bDoor; //Kontrolllampen outside/inside Bahnsteig/Galerie bool bLoG; bool bLoB; bool bLiG; bool bLiB; //Tür offen oder geschlossen? bool Check_Door(); void Open_Door(); void Close_Door(); //Wo steht der Fahrstuhl gerade? int Check_Floor(); //Motorsteuerung void CElevator::Motor(int nDir); };Aufruf sollte dann im public: Bereich des Forms geschehen. Bzw. Das Objekt soll da erzeugt werden.
CElevator Elev(this);
Der Compiler meldet mir allerdings dann bei
CElevator (TForm1* fom) {Formu=fom;};
, daß er einen Datentyp will. Verwende ich ein normales Form, so habe ich zwar ein Formular, aber eben die Buttons und so nicht
Ich weiß es ist viel Arbeit in den Code zu schauen. Aber was nützt es wenn ich 20 Seiten drumrum erkläre...
-
Shogun schrieb:
Aufruf sollte dann im public: Bereich des Forms geschehen. Bzw. Das Objekt soll da erzeugt werden.
CElevator Elev(this);
um das Objekt zu erstellen mußt du in public von TForm einfach nur
CElevator *Elev;angeben, im Konstruktor von TForm muß dann
Elev = new CElevator(this);stehen und im Destruktor von TForm
delete Elev;
-
Hallo
Du hast noch einen Cross-Include : Der Form-Header bindet den Elevator-Header ein, und der Elevator-Header bindet den Form-Header ein. Der Compiler landet in einer Endlosschleife und bricht die mit einer zugegebenermaßen nicht aussagekräftigen Fehlermeldung ab.
Um das Problem zu lösen must du nur eine Forward Declaration verwenden :
Verlagere den Include des Form-Headers vom Elevator-Header in die Elevator-Implementation. Und im Elevator-Header fügst du stattdessen vor der Klassendefinition nochclass TForm1;ein. Da du im folgenden Header nun nur Pointer auf Form1 verwendest kommt der Compiler damit zurecht.
bis bald
akari
-
Hi
Die Kombination beider Posts hat perfekt funktioniert.
Ich muss noch vieeeel lernen. Leider sind es solche kleinen Dinge, die mich immer aufhalten.Was bedeutet "class TForm1;" nun genau? Das ist einfach nur die Definition der Klasse und fertig?
Auf alle Fälle vielen Dank für die extrem schnelle und treffende Hilfe.

Habe noch kein Forum erlebt, in dem das so flott und ohne große Diskussionen geht. Hier bleib ich gerne
Grüße Shogun
EDIT: Ahhh! Ich habs verstanden. Googlen hilft manchmal wunder. Diese Form ist die Forward Declaration. Lasse die dumme Frage trotzdem mal stehen für die Suchfunktion.
-
Hallo
Das sagt dem Compiler das es eine Klasse namens TForm1 gibt. Mehr nicht. Damit kann der Compiler Pointer und Referenzen auf diese Klasse behandeln. Mehr aber nicht.
Das heißt um die Member der Klasse nun effektiv benutzen zu können must du noch den Include nachschieben, und den brauchst du eben erst in der Implementationsdatei./Edit : zu langsam...
bis bald
akari
-
Hallo,
das mit dem gegenseitigen include könntest Du in diesem Fall auch ohne
Forward-Deklaration auflösen. Da Du in der Header-Datei des Formulars die
Klasse CElevator nicht referenzierst, brauchst Du hier auch kein include
darauf. Du kannst den include einfach in die .cpp verschieben.Falls Deine Formularklasse doch CElevator kennen muss (z.B. Member-Variable),
dann ist die Forward-Deklaration wohl die einfachste Lösung.Gruß
Alexander
-
Ihr seid echt schneller als die Polizei erlaubt. Dankeschön.