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 ()!