CMExit aus Basisklasse kann nicht aufgerufen werden



  • Guten Morgen,
    bei der Übersetzung eines Delphi-Programms stoße ich auf folgendes Problem:
    Ich muß die Funktion CMExit aus der Basisklasse (=TWinControl) aufrufen.

    Der Compiler meldet folgenden Fehler
    [BCC32 Fehler] Unit2.cpp(5239): E2247 Zugriff auf '_fastcall TWinControl::CMExit(TWMNoParams &)' nicht möglich

    Mir ist klar, dass CMExit im private-Bereich von TWinControl definiert ist und deshalb der direkte Zugriff nicht möglich ist.
    Wie muß ich das folgende Programm umbauen um hier weiterzukommen?

    class TmyDBGrid : public TCustomGrid {
    typedef TCustomGrid inherited;
    private: //...
      MESSAGE void __fastcall CMExit(Messages::TWMNoParams &Message);
    public: //...
      BEGIN_MESSAGE_MAP 
        MESSAGE_HANDLER(CM_EXIT, Messages::TWMNoParams, CMExit)
        //...
      END_MESSAGE_MAP(TCustomGrid)
    };
    
    void __fastcall TmyDBGrid::CMExit(Messages::TWMNoParams &Message){
      try
      {
       //...	
      } 
      catch(...)
      {
      //...		
      };
      inherited::CMExit(Message);
    }
    


  • thunderbol4 schrieb:

    bei der Übersetzung eines Delphi-Programms

    Warum übersetzen alle immer Delphi-Code, anstatt ihn einfach einzubinden 😕

    thunderbol4 schrieb:

    Ich muß die Funktion CMExit aus der Basisklasse (=TWinControl) aufrufen.

    Der Compiler meldet folgenden Fehler
    [BCC32 Fehler] Unit2.cpp(5239): E2247 Zugriff auf '_fastcall TWinControl::CMExit(TWMNoParams &)' nicht möglich

    Mir ist klar, dass CMExit im private-Bereich von TWinControl definiert ist und deshalb der direkte Zugriff nicht möglich ist.

    Das ist richtig. Es gibt auch eine Lösung für dein Problem, und ich habe auch irgendwo den Quelltext dafür herumliegen. Aber zunächst wüßte ich gerne, wie das denn deine Delphi-Vorlage macht - die sollte doch dasselbe Problem haben?



  • Hallo @audacia,
    anbei die entsprechende Delphi-CMExit-Prozedur

    procedure TmyDBGrid.CMExit(var Message: TMessage);
    begin
      try
        if FDatalink.Active then
          with FDatalink.Dataset do
    	  if (dgCancelOnExit in Options) and (State=dsinsert) and
    	      not Modified and not FDatalink.FModified then
    	    Cancel else
    	    FDataLink.UpdateData;
    	except
    	  SetFocus;
    	  raise;
    	end;
    	inherited;
    end;
    

    Zur Lösung meines Problems habe ich unterdessen im Netz und hier im Forum gekramt. Vieles deutet daraufhin, dass es
    inherited::Dispatch(&Message) heißen muß, bin mir aber nicht sicher und lasse mich hier gerne von Dir beraten, verbessern.

    Warum Delphi-Code?
    Ganz einfach:

    1. Es gibt im Netz hiervon eine Unmenge von Quellcode für jeden nur erdenklichen Fall. Im Vergleich dazu ist der Anteil an C++ Builder-Code
      leider deutlich geringer.
    2. Bei der Umsetzung von Delphi auf C++Builder-Code habe ich bisher auf diese Art eine Menge dazugelernt, das kriegt man nur wenn man Stück für Stück übersetzt. Voraussetzung ist natürlich man hat die Zeit.
    3. Wenn es mir nur auf den Code ankäme, würde ich einfach eine Komponente mit Quellcode kaufen.


  • Tut mir leid, daß ich jetzt erst darauf zurückkomme - ich hatte das hier völlig vergessen.

    thunderbol4 schrieb:

    Zur Lösung meines Problems habe ich unterdessen im Netz und hier im Forum gekramt. Vieles deutet daraufhin, dass es
    inherited::Dispatch(&Message) heißen muß

    So ist es.

    Der "Quelltext, den ich herumliegen habe", war ein Workaround zur Lösung des Problems, weil ich mir bis vor kurzem gar nicht bewußt war, daß man in Delphi auch in Message-Handlern einfach "inherited" aufrufen kann (ich kannte es nur von virtuellen Funktionen). Damit ist mein "Workaround" natürlich hinfällig.

    thunderbol4 schrieb:

    Warum Delphi-Code?

    Neinnein. Die Frage war nicht "warum Delphi-Code", sondern "warum nimmt man den Delphi-Code nicht so, wie er ist, sondern meint, ihn erst nach C++ übersetzen zu müssen". Aber das hier

    thunderbol4 schrieb:

    1. Bei der Umsetzung von Delphi auf C++Builder-Code habe ich bisher auf diese Art eine Menge dazugelernt, das kriegt man nur wenn man Stück für Stück übersetzt.

    ist in der Tat ein gutes Argument dafür - wenngleich ich den Lernzweck doch eher vom Produktiveinsatz trennen würde.


Anmelden zum Antworten