Zugriff auf TCustomGrid::Options benötigt



  • Hallo,
    ich benötige den Zugriff auf die protected __property TGridOptions Options; Diese __property stammt aus TCustomGrid oder einem Abkömmling in Richtung TStringGrid.

    In meiner Ableitung der Klasse TDBGrid möchte ich auf diese __property mit folgender Funktion zugreifen:

    //cpp
    void __fastcall TmyDBGrid::f(void) {
    TmyCustomGrid* tGr = dynamic_cast<TmyCustomGrid*>(this);  //geht leider nicht
      tGr->Options = tGr->Options >> goFixedVertLine >> goFixedHorzLine;
    }
    

    Zur Erklärung: Es dürfte Euch das folgende Ableitungsschema bekannt sein:

    TCustomGrid ->TCustomDrawGrid ->TDrawGrid ->TStringGrid
    TCustomGrid ->TCustomDBGrid ->TDBGrid ->TmyDBGrid

    enum TGridOption { goFixedVertLine,...goThumbTracking }; -> TGridOption TGridOptions; -> __property TGridOptions Options;

    Ich habe versucht über die Ableitung von TCustomGrid an die protected __property Options heranzukommen, indem ich diese dort
    public deklariere:

    //h
    class TmyCustomGrid : public TCustomGrid { //gemeinsamer Vorfahr von TStringGrid und TDBGrid
    public:
      __fastcall TmyCustomGrid(TComponent* AOwner);
      __property Options;
    }
    

    Leider nützt mir das nichts. Scheinbar kann ich TCustomGrid bzw. TmyCustomGrid nicht erzeugen? Weiß jemand warum, bzw. hat jemand einen Tipp, wie ich das lösen kann?



  • Du kannst doch einfach innerhalb deiner TDBGrid-Ableitung 'TmyDBGrid' direkt auf Options zugreifen:

    void __fastcall TmyDBGrid::f() // <- do not use (void) - ugly! we are in C++, not in C!!!
    {
      Options = Options >> goFixedVertLine >> goFixedHorzLine;
    }
    

    What's the problem?



  • Hi @Th69, thank you for your reply.
    Sorry, your proposal doesn't work.
    As you can see the TDBGridOption doesn't have a goFixedVertLine and a goFixedHorzLine. That's the problem.

    enum TDBGridOption {
      dgEditing,
      dgAlwaysShowEditor,
      dgTitles,
      dgIndicator,
      dgColumnResize,
      dgColLines,
      dgRowLines,
      dgTabs,
      dgRowSelect,
      dgAlwaysShowSelection,
      dgConfirmDelete,
      dgCancelOnExit,
      dgMultiSelect
    };
    

    Therefore you must have access to the ancestor TCustomGrid in which the Options are jointly defined like this. Also see my description above.

    enum TGridOption {
      goFixedVertLine,
      goFixedHorzLine,
      goVertLine,
      goHorzLine,
      goRangeSelect,
      goDrawFocusSelected,
      goRowSizing,
      goColSizing,
      goRowMoving,
      goColMoving,
      goEditing,
      goTabs,
      goRowSelect,
      goAlwaysShowEditor,
      goThumbTracking
    };
    

    I don't have any opinion why the developers made a difference between TDBGrid and Grid, because they are so similar. If you have any idea further, how to solve
    the problem, I am grateful for your support.



  • Aha, jetzt erst verstehe ich das Problem.
    Da scheint TDBGrid das Property Option von TCustomGrid verdeckt zu haben...

    Probier mal:

    TCustomGrid* grid = dynamic_cast<TCustomGrid*>(this);
    grid->Options = grid->Options >> goFixedVertLine >> goFixedHorzLine;
    

    P.S. Dein dynamic_cast hat nicht funktioniert, weil dein TmyDBGrid halt kein TmyCustomGrid ist (sondern beide eben nur von TCustomGrid abgeleitet sind).
    Du könntest stattdessen auch einfach static_cast benutzen (auf eigene Gefahr hin -)

    Und wenn es immer noch nicht funktioniert, dann beschwer dich bei den VCL-Programmierern -) Oder geh zum Bundesverfassungsgericht - einfach so die Options zu behandeln - das ist ja menschen- äh objekt-unwürdig...



  • Hallo @Th69,
    Danke für Deine Mühe, leider geht Dein neuer Vorschlag auch nicht.

    Ich denke es liegt daran, dass die Eigenschaft Options in TCustomGrid auch protected ist. Ich kann deshalb nicht auf diese Eigenschaft zugreifen, eben weil sie protected ist.
    Ich hatte deshalb ja auch versucht das zu umgehen, indem ich TCustomGrid auf TMyCustomGrid ableite und dabei diese Options public setze.

    public: __property Options;
    

    Theoretisch müßte das gehen. Nur in der Praxis scheinbar nicht.

    Mittlerweile habe ich den reinterpret_cast im Einsatz. Das geht zwar, gefällt mir aber gar nicht. Ich bin noch nicht durch mit Quelltext. Es wird sich erst noch herausstellen, ob's damit später funktioniert.



  • Habe mir jetzt auch mal die Mühe gemacht und es klappt (aber wirklich nur mit einem reinterpret_cast bzw. mit einem C-Cast):

    class TMyCustomGrid : public TCustomGrid
    {
    public:
      __property Options;
    };
    
    class TMyDBGrid : public TDBGrid
    {
    public:
    	__fastcall TMyDBGrid(TComponent *Owner)
    	  : TDBGrid(Owner)
    	{
    	}
    
    	void Test()
    	{
    		TMyCustomGrid *grid = reinterpret_cast<TMyCustomGrid*>(this);
    		grid->Options = grid->Options >> goFixedVertLine >> goFixedHorzLine;
    	}
    };
    

    Die hervorgehobenen Linien sind dann auch zur Laufzeit verschwunden...

    Alternativ kann man auch einfach auf TStringGrid bzw. TDrawGrid casten (darf dann aber wirklich nur auf Member von TCustomGrid zugreifen).

    Edit: Kaum hat man gepostet, fällt einem die einfachste und beste Lösung ein:

    class TMyDBGrid : TDBGrid
    {
      void Test()
      {
         TCustomGrid::Options = TCustomGrid::Options << goFixedVertLine << goFixedHorzLine;
      }
    }
    

    Sieht zwar aus, wie der Aufruf eines statischen Members, ist aber nur ein gezielter Aufruf eines Basisklassen-Members!

    🙂



  • Hallo @Th69, 🙂
    ganz große Klasse. Ich sag dazu nur, es ist wie bei einem guten Essen, das Beste, wie z.B. Dessert, kommt immer zuletzt.

    Die Lösung ist sowas von verblüffend einfach - und gerade das macht die Klasse aus! 👍

    Vielen Dank für Deine Mühe. 🙂


Anmelden zum Antworten