TForm erweitern
-
Hallo,
ich möchte gerne die klassische TForm um einige Gimmicks erweitern. Diese erweiterte TExForm soll dann Basisklasse für alle Nutzerformulare im Programm sein. Wie würde ich da vorgehen?
class TExForm : public TForm { private: TApplicationEvents* FAppEvents; void __fastcall WMNCRButtonDown(Messages::TMessage &Message); void __fastcall WMNCRButtonUp(Messages::TMessage &Message); void __fastcall WMSysCommand(Messages::TWMSysCommand &Message); BEGIN_MESSAGE_MAP MESSAGE_HANDLER(WM_NCRBUTTONDOWN, TMessage, WMNCRButtonDown); MESSAGE_HANDLER(WM_NCRBUTTONUP, TMessage, WMNCRButtonUp); MESSAGE_HANDLER(WM_SYSCOMMAND, TWMSysCommand, WMSysCommand); END_MESSAGE_MAP(TForm); protected: virtual void __fastcall Loaded(); void __fastcall CreateParams(TCreateParams &Params); void __fastcall OnCloseForm(TObject* Sender, TCloseAction &Action); DYNAMIC void __fastcall KeyPress(wchar_t &Key); DYNAMIC void __fastcall KeyUp(unsigned short &Key, TShiftState Shift); public: __fastcall TExForm(TComponent* Owner, String initString); __fastcall ~TExForm(); bool __fastcall CloseQuery(); };
class TLoginForm : public TExForm { __published: // IDE-verwaltete Komponenten void __fastcall FormCreate(TObject *Sender); private: // Benutzer Deklarationen public: // Benutzer Deklarationen __fastcall TLoginForm(TComponent* Owner, String initString); //, TKremaCore* ACore); };
Geht das so?
Danke und Grüße!
-
Hallo
Ja, du kannst natürlich immer manuell ableiten.
Allerdings weiß ich jetzt nicht ob dann auch der OI damit zusammenarbeitet, vor allem der erweiterte Konstruktor ist gar nicht VCL-konform.Ach und noch nebenbei : niemals die OnCreate oder OnDestroy-Events benutzen, dafür sind in C++ die Konstruktoren bzw. Destruktoren zuständig.
bis bald
akari
-
Also mit dem OI gibt es keine Probleme...
Wie mache ich den Konstruktor VCL-konform? Vorallem was heißt in diesem Zusammenhang VCL-konform?
-
Hallo
Für VCL-Komponenten ist ein Konstruktor notwendig, der sich mit dem Owner-Parameter begnügt. Zum Beispiel so :
TLoginForm(TComponent* Owner, String initString = "");
wenn ein leerer String ein gültiger Standardwert für initString ist.
bis bald
akari
-
Habe eben den Konstruktor VCL-konform geändert, indem ich den string wieder entfernt habe.
Das wäre also verstanden... kommen wir nun zum eigentlichen Problem
!
Wenn ich jetzt versuche aus meiner Hauptkomponente (welche ein TDataModul ist), die TLoginForm aufzurufen
TLoginForm *loginForm = new TLoginForm(this); loginForm->ShowModal();
Erhalte ich:
*Erste Gelegenheit für Exception bei $7C812A6B. Exception-Klasse EOSError mit Meldung 'Systemfehler. Code: 1400.
Ungültiges Fensterhandle'. Prozess Project1.exe (3692)
*Vielen Dank übrigens bis hierhin...
-
Hallo
Das läßt sich jetzt von deinem Codeausszug nur schwer erklären. Ich vermute mal das du den Konstruktor von TLoginForm zwar implementiert hast, aber vergessen hast den Owner-Konstruktor von TExForm aufzurufen?
__fastcall TLoginForm::TLoginForm(TComponent* Owner) : TExForm(Owner, "") // Hier must du den Konstruktor von TExForm mit passenden Parametern aufzufen { }
bis bald
akari
-
Leider nein!
__fastcall TExForm::TExForm(TComponent* Owner) : TForm(Owner) { this->OnClose = OnCloseForm; FAppEvents = new TApplicationEvents(this); KeyPreview = true; }
ExForm ruft den Konstruktor von TForm auf und
__fastcall TLoginForm::TLoginForm(TComponent* Owner) : TExForm(Owner) { this->Caption = "Anmelden - " + THENAMEOFTHEGAMESHORT; this->Left = Screen->Width / 2 - this->Width / 2; this->Top = Screen->Height / 2 - this->Height / 2; }
LoginForm dann wiederum den Konstruktor der ExForm.
Kann es damit zuzsammenhängen, dass der Owner ein DataModule ist?
Oder vielleicht, dass es keine Ressource für die ExForm gibt?/* TCustomForm.Create */ inline __fastcall virtual TForm(Classes::TComponent* AOwner) : TCustomForm(AOwner) { }
Hier bleibt der Cursor übrigens stehen.
Die letzten Ops aus dem StackTrace:
:501eebb6 vcl120.@Forms@TScrollingWinControl@CreateWndqqr50System@%Setiuciuc3% + 0x28 :50128754 vcl120.@Graphics@TCanvas@TextHeightqqrx20System@UnicodeString + 0x14
-
Hmmm.... so kann man seine Zeit auch verdaddeln
void __fastcall TExForm::CreateParams(TCreateParams &Params) { inherited::CreateParams(Params); Params.WndParent = GetDesktopWindow; }
Hinter GetDesktopWindow gehören natürlich ()!