Referenz als Klassenelement!



  • Ich setze den Zeiger des aktuell geöffneten Fensters auf OpenedFrame und möchte beim nächsten Aufruf von ÖffneFrame überprüfen ob das übergebene Frame schon geöffnet ist.

    1. Frame1 erzeugen und in OpenedFrame "merken"
    2. Frame2 erzeugen und in OpenedFrame "merken"

    -> Problem Zeiger von Frame1 zeigt jetzt auf Frame2 und wird beim nächsten Aufruf schon als geöffnet betrachtet und das Erstellen von Frames ist nicht mehr möglich.

    Ich brauchte etwas in dem ich nur die Adresse speichern... int?



  • Kannst Du mir bitte mal mehr Code zeigen ?

    wie erzeigst du die Frames ??

    TFrame Frame1 = new TFrame();

    ??

    Funktioniert dein Code ansonsten ???

    Frame1 = (TFrame1*) FrameManager->OpenFrame(__classid(TFrame1),Frame1);
    (TFrame1*) ??

    in der Klasse:
    TFrame* OpenFrame(TMetaClass* InstanceClass, TCustomFrame *Reference);

    in der cpp

    TFrame* TFrameManager::OpenFrame(System::TMetaClass* InstanceClass, TFrame *Reference)

    🙄

    Ich würde Dir gern helfen aber da stimmt doch was Hinten und Vorne nicht.



  • Kommt das in Deine Richtung ??

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    	: TForm(Owner)
    {
    
    	Frame1=new TFrame(Form1);
    	Frame2=new TFrame(Form1);
    	FrameM= new TFrameManager(Form1);
    
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button3Click(TObject *Sender)
    {
    Close();	
    }
    //---------------------------------------------------------------------------
    void TFrameManager::CloseCurrentFrame()
    {
       if (_OpenedFrame) {
                _OpenedFrame->Parent = NULL ;
                try {
                  delete _OpenedFrame;       //call destructor
                }
                __finally {
                  _OpenedFrame = NULL;
                }
        }
    }
    //---------------------------------------------------------------------------
    
    TFrame* TFrameManager::OpenFrame(TFrame *Reference)
    {
    
    	if ( (_OpenedFrame != Reference) || (_OpenedFrame == NULL) )
    	{
    
    	 CloseCurrentFrame();
    	 //Application->CreateForm(InstanceClass , &Reference);
    
        this->_OpenedFrame = Reference;
        this->_OpenedFrame->Parent = _Parent;
    
      }
      return _OpenedFrame;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
      TFrameManager *FrameM= new TFrameManager(Form1);
    
      Frame1->Color=clYellow;
      Frame1->Left=10;
      Frame1->Top=10;
      TFrame *tempFrame = FrameM->OpenFrame(Frame1);
      Application->ProcessMessages();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
    
      Frame1->Color=clRed;
      Frame1->Left=10;
      Frame1->Top=10;
      TFrame *tempFrame = FrameM->OpenFrame(Frame1);
    
      Application->ProcessMessages();
    
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
    {
    	delete Frame1;
    	Frame1=NULL;
    
    	delete Frame2;
    	Frame2=NULL;
    
    	delete FrameM;
    	FrameM=NULL;
    }
    //---------------------------------------------------------------------------
    
    //---------------------------------------------------------------------------
    
    #ifndef Unit1H
    #define Unit1H
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    //---------------------------------------------------------------------------
    
    class TFrameManager
    {
    private:
         TFrame * _OpenedFrame; 
         TWinControl *_Parent; 
    
    public:
    
    	  TFrameManager (TWinControl *AParent)
    	  {
            _OpenedFrame   = NULL; 
            _Parent        = AParent; 
         }; 
    
    	 ~TFrameManager ()
    	 {
    		 CloseCurrentFrame();
    	 };
    
    	  TFrame* TFrameManager::OpenFrame(TFrame *Reference);
    
         void CloseCurrentFrame(); 
    
         TFrame* GetOpenedFrame() { return _OpenedFrame; }; 
    
    }; 
    
    class TForm1 : public TForm
    {
    __published:	// Von der IDE verwaltete Komponenten
    	TButton *Button1;
    	TButton *Button2;
    	TButton *Button3;
    	void __fastcall Button3Click(TObject *Sender);
    	void __fastcall Button1Click(TObject *Sender);
    	void __fastcall Button2Click(TObject *Sender);
    	void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
    private:	// Anwender-Deklarationen
    	TFrame *Frame1;
    	TFrame *Frame2;
    	TFrameManager *FrameM;
    public:		// Anwender-Deklarationen
    	__fastcall TForm1(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif
    [code]
    
    Du brauchst ne Form mit 3 Button  :open_mouth: 
    
    Button1 ruft Frame1 auf.
    Button2 ruft Frame2 auf.
    Button3 .. naja ;-)
    
    wenn Du die Frames nicht wie ich fest anlegst sondern dynamisch wird es ein kleineres Problem die selbe Adresse nochmal zu bekommen.
    
    Der Code ist nicht vollstaendig optimiert, ich möchte erst einmal wissen, was Du ueberhaupt vor hast .
    

    tempFrame sollte den aktuellen Frame haben (damit moechtest du bestimmt noch etwas machen ....)



  • Sinn meiner Klasse soll sein, das Frames erst zum Zeitpunkt des Bedarfs erstellt werden und auf Knopfdruck wieder zerstört werden. Ein Hauptaspekt soll darin liegen das die Frames nicht mehr so abhängig voneinander sind und leichter ausgetauscht werden können.

    Ich habe eine Klasse die Zeiger auf Routinen des Hauptfensters enthält so wird automatisch beim Öffnen irgendeines Frames durch den "FrameManager" z.B. die Routine "SETZE ÜBERSCHRIFT" gerufen und das Hauptfenster angepasst. Problem ist das ich in der Klasse FrameManager bisher nicht überprüfen kann ob der Zeiger auf ein übergebenes Frame gleich dem geöffneten Frame ist um zu verhindern das ein bereits offnenes Frame wieder zerstört und nochmal geöffnet wird.

    //----------------------------- HPP -----------------------------------------
    
    class TFrameManager{
    
         TFrame *_OpenedFrame;
         TWinControl *_Parent;
    
        void (*_OpenFunction)();  // pointer to function that will be called after creating a new Frame
        void (*_CloseFunction)();
    
    public:
    
          TFrameManager (TWinControl *AParent, void (*OpenFunction)(), void (*CloseFunction)() )
          {
            _OpenedFrame   = NULL;
            _Parent        = AParent;
            _OpenFunction  = OpenFunction;
            _CloseFunction = CloseFunction;
         };
    
        ~TFrameManager () { CloseCurrentFrame(); };
    
         TFrame* OpenFrame(TMetaClass* InstanceClass, TFrame *Reference);
    
         void CloseCurrentFrame();
    
         TFrame* GetOpenedFrame() { return _OpenedFrame; };
    
    };
    
    //------------------------- CPP ----------------------------------------------
    
    void TFrameManager::CloseCurrentFrame()
    {
       if (_OpenedFrame) {
                _OpenedFrame->Parent = NULL ;
                try {
                  delete _OpenedFrame;       //call destructor
                }
                __finally {
                  _OpenedFrame = NULL;
                  if (_CloseFunction) _CloseFunction();
                }
        }
    }
    
    TFrame* TFrameManager::OpenFrame(System::TMetaClass* InstanceClass, TFrame *Reference)
    {
    
     //  if ( (_OpenedFrame != Reference) || (_OpenedFrame == NULL) ) {
    
        CloseCurrentFrame();
    
        Application->CreateForm(InstanceClass , &Reference);
    
        this->_OpenedFrame = Reference;
        this->_OpenedFrame->Parent = _Parent;
        if (_OpenFunction) _OpenFunction();
    
    //  }
        return _OpenedFrame;
    }
    


  • FrankHof schrieb:

    Sinn meiner Klasse soll sein, das Frames erst zum Zeitpunkt des Bedarfs erstellt werden und auf Knopfdruck wieder zerstört werden. Ein Hauptaspekt soll darin liegen das die Frames nicht mehr so abhängig voneinander sind und leichter ausgetauscht werden können.

    Frame2=new TFrame(Form1);
    tempFrame = FrameM->OpenFrame(Frame1);

    tempFrame merken ......
    CloseFrame(tempFrame);

    FrankHof schrieb:

    Ich habe eine Klasse die Zeiger auf Routinen des Hauptfensters enthält

    Da kannst Du Dir tempFrame merken.

    FrankHof schrieb:

    so wird automatisch beim Öffnen irgendeines Frames durch den "FrameManager" z.B. die Routine "SETZE ÜBERSCHRIFT" gerufen und das Hauptfenster angepasst. Problem ist das ich in der Klasse FrameManager bisher nicht überprüfen kann ob der Zeiger auf ein übergebenes Frame gleich dem geöffneten Frame ist um zu verhindern das ein bereits offnenes Frame wieder zerstört und nochmal geöffnet wird.

    wenn Du die Frames nicht mit "new" erzeugst, hast Du auch keinen "neuen" Frame !
    Also immer die gleiche Adresse.

    sonst würde

    if ( (_OpenedFrame != Reference) || (_OpenedFrame == NULL) )

    funktionieren.

    Solltest Du mehrere FRAMES haben solltest Du eine Liste mit Frames uebergeben die geoeffnet sind und im FrameManager diese Liste durchsuchen ob der Frame den Du uebergibst Dabei ist.

    TList *slLISTE = new TList;
    TList->Add(tempFrame);



  • tempFrame = FrameM->OpenFrame(Frame1);
    //wie kann ich denn dann in OpenFrame das Frame1 abhängig von seinen Typ erstellen? brauch ich da nicht ein Template?

    &TFrame OpenFrame(MyFrame TFrame)
    {
       MyFrame = new TFrame(this->_Parent); //funktioniert nicht da kein TFrame()
                                            //sondern T<irgendwasFrame>()
    };
    


  • *TFrame OpenFrame(TFrame MyFrame) // MyFrame ist vom Typ TFrame nicht umgekehr
    {

    MyFrame = new TFrame(this->_Parent); //funktioniert nicht da kein TFrame()
    //sondern T<irgendwasFrame>()
    };



  • Wenn DU es mit verschiedenen Klassen machen moechtest muss es in etwa so aussehen:

    template <class T>
    T* OpenFrame(T MyFrame) 
    { 
    ..........
    
    MyFrame = new T(this->_Parent); 
    return MyFrame
    };
    


  • also das template schaut nun so aus:

    template <class T> T* TFrameManager::OpenFrame(T* Frame){
    
       Frame = new T(this);
       Frame->Parent = this->_Parent;
       this->_OpenedFrame = Frame;
    
       return (Frame);
    };
    

    aber es tritt leider folgender Linkerfehler auf:

    [Linker Fehler] Unresolved external 'TFrameBestandsErfassung * TFrameManager::OpenFrame<TFrameBestandsErfassung>(TFrameBestandsErfassung *)' referenced from C:\PROGRAMME\BORLAND\CBUILDER6\PROJECTS\KOENITZ\OBJ\MAINFORM.OBJ



  • okay habs... lag am an der auslagerung in die cpp das geht ja bei Templates nicht wirklich....


Anmelden zum Antworten