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@CreateWndqqrv+0xa:501289f4vcl120.@Graphics@TCanvas@RequiredStateqqrv + 0xa :501289f4 vcl120.@Graphics@TCanvas@RequiredStateqqr50System@%Sett22Graphics@TCanvasStatest22Graphics@TCanvasStatesiuc00iuc3% + 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 ()!


Anmelden zum Antworten