Fehler, Irrtümer, Fragen - Seite 2794

 
Mihail Matkovskij:

Mein Indikator hat aus irgendeinem Grund begonnen, grafische Objekte zu verlieren und löscht sie nicht. Ich verwende die automatische Löschung im Destruktor der Klasse. Ich nenne es:

Infolgedessen erhalte ich ein falsches Positiv. Ich rufe GetLastError() auf und erhalte den Fehler 4101 ("Errory chart identifier"). Angenommen. Ich vergleiche die ChartID des zu löschenden grafischen Objekts mit dem Ergebnis der Funktion ChartID(), und sie stimmen genau überein. Was kann der Grund dafür sein, dass ein Objekt nicht aus dem Diagramm entfernt wird, und wie kann ich das Problem umgehen?

Ich habe beschlossen, einen anderen Weg zu versuchen. Beim Erstellen eines Diagramms füge ich alle Objekte zur Liste hinzu und verwende die Schleife, um alle Objekte zu löschen, wenn ich den Indikator lösche. Jetztgibt die FunktionGetLastError() nach dem Aufruf der Funktion ObjectDelete denFehler 4001 aus und einige Diagrammobjekte bleiben im Diagramm.

 
Mihail Matkovskij:

Mein Indikator hat aus irgendeinem Grund angefangen, grafische Objekte zu verlieren und will sie nicht mehr löschen. Ich verwende die automatische Löschung im Destruktor der Klasse. Ich nenne es:

Infolgedessen erhalte ich ein falsches Positiv. Ich rufe GetLastError() auf und erhalte den Fehler 4101 ("Errory chart identifier"). Angenommen. Ich vergleiche die ChartID des zu löschenden grafischen Objekts mit dem Ergebnis der Funktion ChartID(), und sie stimmen genau überein. Was kann der Grund dafür sein, dass ein Objekt nicht aus dem Diagramm entfernt wird und wie kann dies vermieden werden?

Ich habe einen Quellcode erstellt, in dem dieser Fehler auftritt:
//+------------------------------------------------------------------+
//|                                           DeleteChartObjects.mq5 |
//|                                      Copyright 2020, © Cyberdev. |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, © Cyberdev."
#property version   "1.00"
#property indicator_chart_window

#property indicator_plots 0

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

#include <ChartObjects\ChartObjectsLines.mqh>
#include <Arrays\ArrayObj.mqh>

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//--- input parameters
input int      nBars = 100000;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int customN_Bars = 0;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CArrayObj listOfTrendLines;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {
//--- indicator buffers mapping
  int totalBars = iBars(NULL, PERIOD_CURRENT);
  customN_Bars = (nBars < totalBars) ? nBars : totalBars;
//---
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[]
) {
  CChartObjectTrend * trend;
  int delta = rates_total - customN_Bars;
  int shift;
  int i;
  for(i = 0; i < customN_Bars; i++) {
    shift = delta + customN_Bars - i - 1;
    trend = new CChartObjectTrend();
    if(trend.Create(0, "trend"+(string)i, 0, time[shift], low[shift], time[shift], high[shift]))
      listOfTrendLines.Add(trend);
  }
  return(rates_total);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
  
  CChartObjectTrend * trend;
  
  int i = listOfTrendLines.Total() - 1;
  for(; i >= 0; i--) {
    trend = dynamic_cast <CChartObjectTrend *> (listOfTrendLines.At(i));
    
    if(CheckPointer(trend) == POINTER_INVALID)
      continue;
    
    delete trend;
  }
}
//+------------------------------------------------------------------+

Aktionen zur Demonstration des Fehlers.

1. Platzieren Sie den Indikator auf dem Chart.

2. Entfernen Sie den Indikator aus dem Diagramm.

3 Drücken Sie die Tastenkombination Strg+B und dann die Schaltfläche "Alles auflisten" im Fenster, um die nicht entfernten Objekte anzuzeigen.

Objekte

Ich habe nur 294 von 100000.

Wenn Sie den Wert des Eingabeparameters nBars verringern, tritt der Fehler nicht auf.

Dateien:
 

Guten Tag.

Ich habe lange mit dem Upgrade von Windows 7 auf 10 gezögert, aber diese Woche habe ich neu installiert.

Jetzt habe ich ein Problem, ich kann keine Expert Advisor Demoversionen meiner Indikatoren und anderer EAs herunterladen,

Ich drücke den Download-Button und nichts passiert, ich habe es mit geöffnetem und geschlossenem Terminal versucht!

Ich versuche, es für das MT4-Terminal herunterzuladen, ich war noch nicht auf MT5.

Was zum Teufel ist hier los?

 
Mihail Matkovskij:
Ich habe einen Quellcode erstellt, in dem dieser Fehler auftritt:

Was passiert, wenn ein Zeiger gelöscht wird?

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
  
  CChartObjectTrend * trend;
  
  int i = listOfTrendLines.Total() - 1;
  for(; i >= 0; i--) {
    trend = dynamic_cast <CChartObjectTrend *> (listOfTrendLines.At(i));
    
    if(CheckPointer(trend) == POINTER_INVALID)
      continue;
    
    delete trend;
  }
}

Gibt es einen Befehl für das Diagramm, um das grafische Objekt zu löschen? Siehe Hinweis zu ObjectDelete

Документация по MQL5: Графические объекты / ObjectDelete
Документация по MQL5: Графические объекты / ObjectDelete
  • www.mql5.com
При вызове ObjectDelete() всегда используется асинхронный вызов, поэтому функция возвращает только результат постановки команды в очередь графика. В этом случае true означает только то, что команда успешно поставлена в очередь, сам результат её выполнения неизвестен. Для проверки результата выполнения можно использовать функцию ObjectFind() или...
 
Mihail Matkovskij:

Bei mir sind es 294 von 100000.

Wenn wir den Wert des Eingabeparameters nBars verringern, tritt der Fehler nicht auf.

Kann es passieren, dass die Schleife länger dauert, als die Ausführung von OnDeinit dauert?

In Ihrem Beispiel haben alle Objekte das Präfix "trend", warum verwenden Sie es nicht und verweigern es in der Schleife?

int  ObjectsDeleteAll(
   long           chart_id,   // идентификатор графика
   const string     prefix,   // префикс имени объекта
   int       sub_window=-1,   // индекс окна
   int      object_type=-1    // тип объекта для удаления
   );
 
Rashid Umarov:

Was passiert, wenn ein Zeiger gelöscht wird?

Gibt es einen Befehl für das Diagramm, um das grafische Objekt zu löschen? Siehe den Hinweis zu ObjectDelete

Ich habe sicherlich schon einmal über diese Notiz nachgedacht. Aber dann habe ich aus irgendeinem Grund beschlossen, dass es ein Fehler des Terminals war. Dafür entschuldige ich mich. Es muss also meine Schuld sein.

Aber ich weiß nicht, was ich in diesem Fall tun soll. Rufe ich ObjectDelete und dann ObjectFind und warten, bis es fehlschlägt, um herauszufinden, ob das Objekt tatsächlich entfernt wurde? Nach der gleichen Notiz zu urteilen, ist es zu zeitaufwendig. Ich weiß nicht, ob ein zweites Löschen funktionieren wird (in meinem Indikator habe ich versucht, ObjectDelete zweimal hintereinander aufzurufen, aber es hat nicht funktioniert). Und die Sleep-Funktion in Indikatoren funktioniert nicht, um dem Diagramm etwas Zeit zu geben, jedes Objekt zu löschen. Vielleicht gibt es irgendwo Beispiele dafür, wie man dies umgehen kann?

 
Alexey Viktorov:

Kann es nicht passieren, dass die Schleife länger dauert als die Zeit für die Ausführung von OnDeinit?

Schließlich haben alle Objekte in Ihrem Beispiel das Präfix "trend", warum also nicht verwenden und aus der Schleife verwerfen?

Dies gilt nur für das Beispiel. Der Indikator, mit dem ich arbeite, hat komplexe Namen. Und ich habe nur zur Veranschaulichung ein Beispiel genannt.

 
Mihail Matkovskij:

Ich habe sicherlich schon einmal über diese Notiz nachgedacht. Aber dann dachte ich aus irgendeinem Grund, es sei ein Terminalfehler. Dafür entschuldige ich mich. Es stellt sich heraus, dass es meine Schuld ist.

Aber ich weiß nicht, was ich in diesem Fall tun soll. Rufe ich ObjectDelete und dann ObjectFind und warten, bis es fehlschlägt, um herauszufinden, ob das Objekt tatsächlich entfernt wurde? Nach der gleichen Notiz zu urteilen, ist es zu zeitaufwendig. Ich weiß nicht, ob eine zweite Löschung funktionieren würde (in meinem Indikator habe ich versucht, ObjectDelete zweimal hintereinander aufzurufen, aber es hat nicht funktioniert). Und die Sleep-Funktion in Indikatoren funktioniert nicht, um dem Diagramm etwas Zeit zu geben, jedes Objekt zu löschen. Vielleicht gibt es irgendwo Beispiele dafür, wie man dies umgehen kann?

Ich glaube, Sie fügen der Liste alle Zeiger hinzu. Das Terminal-Subsystem selbst löscht solche Objekte, deren Zeiger in der Liste CArrayObj stehen

trend = new CChartObjectTrend();
    if(trend.Create(0, "trend"+(string)i, 0, time[shift], low[shift], time[shift], high[shift]))
      listOfTrendLines.Add(trend);
Hier gibt es ein potenzielles Speicherleck. Und ein möglicher Aufruf eines ungültigen Objekts.
 
Artyom Trishkin:
Ich denke, Sie sollten alle Hinweise in die Liste aufnehmen. Das Terminal-Subsystem selbst löscht solche Objekte, deren Zeiger in der Liste CArrayObj stehen

Nach dem Ausschalten des Terminals bleiben die Objekte nach dem Indikator auf der Karte. Und wenn ich das Terminal wieder starte, sind diese Objekte sichtbar und stören die gesamte Ansicht.

 
Mihail Matkovskij:

Nach dem Ausschalten des Terminals bleiben die Objekte nach dem Indikator auf der Karte. Und wenn ich das Terminal wieder starte, sind diese Objekte sichtbar und stören die gesamte Ansicht.

Ich bin nicht an meinem PC, um Ihr Beispiel zu überprüfen. Ich habe meinem Beitrag oben hinzugefügt, was ich an Fehlern sehe.