Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools

Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools (http://www.expert-advisor.com/forum/index.php)
-   Programmierung MQL4 (http://www.expert-advisor.com/forum/forumdisplay.php?f=220)
-   -   DeInit mit reason funktioniert nicht (http://www.expert-advisor.com/forum/showthread.php?t=7062)

AVT 06.08.21 16:01

DeInit mit reason funktioniert nicht
 
Ich versuche in DeInit mit Hilfe der reason die erforderlichen Aktionen einzuteilen, leider klappt das nicht.
Die Situation: ich habe im EA 2 unterschiedliche Objektarten, das eine ist die Steuereinheit (besteht aus Button, RectangleLabel und Label) und das andere ist die Aktionseinheit (besteht aus Linien und Buffern, die hier aber unwichtig sind).
Code:

  // === delete all created objects
  // === ONLY if we failed to init or if we are deleted from chart
  if(  reason==REASON_PROGRAM
      || reason==REASON_REMOVE
      || reason==REASON_CHARTCLOSE
      || reason==REASON_INITFAILED
      || reason==REASON_CLOSE      )
  {
      for(int i=ObjectsTotal()-1; i>=0; i--)
      {
        string obj_name=ObjectName(i);
        if(StringSubstr(obj_name,0,StringLen(PFX))==PFX) //ExactPFXmatch
        {
            ObjectDelete(0,obj_name);
        }
      }
  }
  // === in other cases keep action objects, only delete the panel
  // === this will be recreated in OnInit
  else if(  reason==REASON_CHARTCHANGE  //ForTimeframeChange
          || reason==REASON_RECOMPILE    //ForWorkingInEditor
          || reason==REASON_TEMPLATE    //ForChangeOfIndicatorCombination
          || reason==REASON_PARAMETERS  //ForChangeOfValues
          || reason==REASON_ACCOUNT    ) //ForLoosingServerConnection
  {
      DriveRemoveAll();
  }

DriveRemove all sucht nach den Elementen der Steuereinheit und löscht sie:
Code:

void DriveRemoveAll()
{
  for(int i=ObjectsTotal()-1; i>=0; i--)
  {
      string obj_name=ObjectName(i);
      if(StringSubstr(obj_name,0,StringLen(PFX))==PFX) //ExactPFXmatch
      {
        if(ObjectGetInteger(0,obj_name,OBJPROP_TYPE)==OBJ_BUTTON )
            ObjectDelete(0,obj_name);
        else if(ObjectGetInteger(0,obj_name,OBJPROP_TYPE)==OBJ_RECTANGLE_LABEL )
            ObjectDelete(0,obj_name);
        else if(ObjectGetInteger(0,obj_name,OBJPROP_TYPE)==OBJ_LABEL )
            ObjectDelete(0,obj_name);
      }
  }
}

Aber anstatt bei einem Recompile nur die Steuereinheit zu löschen, werden komplett alle Elemente rigoros gelöscht. Dasselbe passiert, wenn ich einfach nur den Timeframe wechsele.
Ich bin momentan komplett ratlos, wieso das nicht funktioniert. Hat jemand eine Idee?
Danke. AVT

traderdoc 08.08.21 17:50

Bei mir funktioniert das immer.
Wo kommt denn die Variable reason her?
Sollte die, warum auch immer, auf Standard 0 stehen, was für REASON_PROGRAMM stehen würde, dann würde auch immer alles gelöscht werden.

traderdoc

AVT 09.08.21 13:15

Danke traderdoc.
Zitat:

Zitat von traderdoc (Beitrag 45595)
Bei mir funktioniert das immer.
Wo kommt denn die Variable reason her?
Sollte die, warum auch immer, auf Standard 0 stehen, was für REASON_PROGRAMM stehen würde, dann würde auch immer alles gelöscht werden.

Die kommt aus aus der Funktion void OnDeinit(const int reason) {...} und erscheint, auch ohne ein Print, immer wenn OnDeinit aufgerufen wird, unter Experten als "uninit reason Nummer".
Man kann sie aber auch noch extra printen lassen (wobei es völlig egal ist, ob das am Anfang oder am Ende von OnDeinit steht, das habe ich alles gestestet) mit
Print(__FUNCTION__," reason for deinit=",(int)reason);

Und die Zahlen, die dann kommen, sind auch der jeweiligen Situation angepaßt, es sind also die korrekten Zahlen für z.B. Timeframe change kommt =3. Sie stehen also nicht permanent auf Null. Das ist ja, was mich so komplett ratlos macht.
AVT

AVT 10.08.21 20:51

vorläufige Lösung
 
Die erste Lösung war, den EA auf einem leeren Chart laufen zu lassen und gar nichts löschen zu lassen, wird der EA entfernt bleiben halt alle Objekte da - aber da der Chart sonst keine anderen Sachen hat, kann man ihn einfach schließen.
Zweite Lösung ist nun eine Wiederherstellungsfunktion, die aus der sowieso schon vorhandenen Sicherungsdatei sämtliche Aktionslinien neu zeichnet.
Das erklärt zwar immer noch nicht, wieso der erste Weg nicht klappt, aber umschifft ihn wenigstens.
AVT

AVT 16.09.21 21:00

Nachtrag Lösung
 
Endlich dazu gekommen, mich mal daran zu setzen.
Wenn man den Grund für DeInit benutzen will, um unterschiedliche Aktionen zu starten, holt man den Wert über UninitializeReason().
Also so was wie:
Code:

  switch( UninitializeReason() )
  {
      //ExpertRemove() was called
      case 0: { CloseMode=0; _CloseOrder();
                EventKillTimer();
                ObjectsDeleteAll(0,PFX);
                break;
              }
      //Program Deleted From Chart
      case 1: { CloseMode=0; _CloseOrder();
                EventKillTimer();
                ObjectsDeleteAll(0,PFX);
                break;
              }
      //Program Recompiled
      case 2: { break; }
      // ... und so weiter
  }

Wieso meine erste Annahme nicht geht, ist mir immer noch nicht klar,
aber so geht es auf jeden Fall. Falls jemand mal danach sucht. AVT


Alle Zeitangaben in WEZ +2. Es ist jetzt 04:32 Uhr.

Powered by vBulletin® Version 3.8.5 (Deutsch)
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.6.1
Powered by vBCMS® 2.7.0 ©2002 - 2024 vbdesigns.de
Copyright ©2009 - 2023 by Expert-Advisor.com - Das Metatrader Forum