Bibliotheken: Die Bibliothek EasyAndFastGUI zum Erstellen von grafischen Interfaces - Seite 8

 

Das Kompilieren von ExampleEAF.mq5 hat den Zweck erfüllt.

Ich hatte angenommen, dass ich eine Bibliothek kompilieren muss, wenn ich eigene Dinge damit erstellen will.

Wie auch immer, vielen Dank!

Oh, und ich bin über diese Codezeile am Anfang der meisten Bibliotheksdateien gestolpert:

class CWindow;

Ist die Erstellung einer "Fake-Klasse" ein Trick, um einen #include-Albtraum zu vermeiden? Wie kann der Compiler später tatsächlich die richtige Klasse linken, die wirklich verwendet wird?

 

Zuerst möchte ich das, was wir haben, abschließen... Immerhin gibt es noch eine Menge Unzulänglichkeiten.

Ich habe einige Anmerkungen zur Architektur. Die angegebenen Objekteigenschaften und das angezeigte Bild führen ein Eigenleben, unabhängig voneinander. Und ein obligatorischer Aufruf von Update() ist erforderlich, sonst bleiben sie in parallelen Realitäten. Das halte ich für falsch, wenn man bedenkt, dass wir ein ereignisbasiertes Modell haben.Manuelles Aktualisieren (Neuzeichnen) sollte keine Voraussetzung sein, es erlaubt nur, Änderungen sofort anzuzeigen, aber alle Änderungen sollten trotzdem angezeigt werden. Zu diesem Zweck sollte eine Nachricht (Ereignis) gesendet werden, um dieses Objekt neu zu zeichnen, die später verarbeitet wird.

D.h. etwa so:

class CSomeControl
{
  int  m_property;
  bool m_changed;
  bool m_event_sent;
 public:
  void Property(int value)  { m_property= value;  m_changed=true;  if (!m_event_sent) m_event_sent= EventChartCustom(m_chart_id, ON_CHANGE, m_id, 0, 0); }  

  void Update()             { /*...Neuzeichnen...*/.  m_changed=false; }

  void OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {  
    if (id==CHARTEVENT_CUSTOM+ON_CHANGE) { m_event_sent=false;  if (m_changed) Update(); }
  }                       
};
 

Mit ChangeWindowWidth ändere ich die Breite des Fensters so, dass es über das aktuelle Diagramm hinausgeht. Wenn ich danach versuche, das Fenster zu verschieben, klebt es automatisch am linken Rand des Diagramms. Wie kann ich dies deaktivieren? Ich kann keine Stelle im Code finden.

 
Alexey Navoykov:

Mit ChangeWindowWidth ändere ich die Breite des Fensters so, dass es über das aktuelle Diagramm hinausgeht. Wenn ich danach versuche, das Fenster zu verschieben, bleibt es automatisch am linken Rand des Diagramms hängen. Wie kann ich dies deaktivieren? Ich kann keine Stelle im Code finden.

Sie müssen die Methode CWindow::UpdateWindowXY() neu schreiben. Sie ist derzeit so implementiert, dass die Ränder des Fensters nicht über das Diagramm hinausgehen können, wenn das Fenster verschoben wird.

 

Übrigens, zur Änderung der Fensterbreite

   m_window1.ChangeWindowWidth(NEW_WIDTH);
   m_window1.Update(true);

In MT5 ist alles in Ordnung, aber in MT4 ist es so

Nach einem Klick auf die Kopfzeile verschieben sich die Schaltflächen an ihren richtigen Platz. Können Sie mir sagen, in welche Richtung ich schauen soll? Wo ist die Bewegung dieser Schaltflächen implementiert?

 
Oleksii Chepurnyi:

Übrigens, wenn Sie die Breite des Fensters ändern

In MT5 ist alles in Ordnung, aber in MT4 ist es so

Nach einem Klick auf die Kopfzeile bewegen sich die Schaltflächen an die richtige Stelle. Können Sie mir sagen, in welche Richtung ich schauen soll? Wo ist die Bewegung dieser Schaltflächen implementiert?

Sehen Sie sich die Methode Moving() an.

Versuchen Sie, über Zeiger auf die Fensterschaltflächen zuzugreifen und diese Methode aufzurufen.

 
Alexey Navoykov:

Ja, Sie müssen entweder die Breite aller Spalten proportional erhöhen oder nur die der letzten Spalte, wobei letzteres vorzuziehen ist.

Aber in der aktuellen Version ist es problematisch, dies selbst zu implementieren, da ich in Ihrer Klasse keine Methode gefunden habe, um die aktuelle Spaltenbreite zu ermitteln, und alle Felder sind privat. Im Allgemeinen sollte zumindest diese Methode hinzugefügt werden.

So können Sie versuchen, das zu implementieren, was Sie jetzt brauchen:

//--- Ereignisse zur Größenänderung des Fensters
   if(id==CHARTEVENT_CUSTOM+ON_WINDOW_CHANGE_YSIZE)
     {
      //--- Anpassen der Breite der Spalte der Übersichtstabelle
      if(m_table_symbols.RowsTotal()>(uint)m_table_symbols.VisibleRowsTotal())
        {
         int width[]={79};
         m_table_symbols.ColumnsWidth(width);
        }
      else
        {
         int width[]={95};
         m_table_symbols.ColumnsWidth(width);
        }
      //---
      m_table_symbols.Update(true);
      m_table_symbols.GetScrollVPointer().CurrentPos(0);
      m_table_symbols.GetScrollVPointer().Update(true);
      return;
     }
 
Anatoli Kazharski:

Sehen Sie sich die Methode Moving() an.

Versuchen Sie, über Zeiger auf Fensterschaltflächen zuzugreifen und diese Methode aufzurufen.

Ja, das war's :) Danke!

Ich dachte, ich hätte schon alles durchgesehen und das Offensichtlichste übersehen :)

 
Anatoli Kazharski:

So können Sie versuchen, das zu realisieren, was Sie jetzt brauchen:

Es handelt sich nur um eine feste Spaltenbreite, aber wir sprachen davon, die Breite der Spalten dynamisch auf der Grundlage ihrer vorherigen Breite zu ändern. Allerdings habe ich die Klasse bereits vervollständigt, indem ich dort die Methode int ColumnWidth(int i) hinzugefügt habe

 

Guten Tag!

Das Problem ist größer :)

Wir erstellen ein dynamisches Objekt, zum Beispiel ein Etikett.

   labels[i] = new CTextLabel;
   labels[i].MainPointer(m_window1);
   labels[i].XSize(SYMBOLS_COL_WIDTH);
   labels[i].YSize(HEAD_HIGHT);
   labels[i].Alpha(SYMBOLS_HEAD_BACK_ALPHA);
   labels[i].FontSize(SYMBOLS_HEAD_FONT_SIZE);
   labels[i].TextAlign(SYMBOLS_HEAD_TEXT_ALIGN,HORIZONTAL_SPACE,0);
   labels[i].FontStyle(SYMBOLS_HEAD_FONT_STYLE);
   labels[i].BackColor(SYMBOLS_HEAD_BACK_COLOR);
   labels[i].CreateTextLabel("0",x_gap,ProfitHeadGap);
   CWndContainer::AddToElementsArray(0,labels[i]);
   labels[i].Update(true);

Aber wie löscht man es?

Ich lösche es auf diese Weise.

      labels[i].Delete();
      delete labels[i];

Aber nachdem ich es gelöscht habe, stürzt es ab und sagt, dass der Zugriff auf den Zeiger nicht korrekt ist.

Soweit ich verstanden habe, fügt CWndContainer::AddToElementsArray das Objekt zu den allgemeinen Arrays hinzu, aber Delete() löscht es nicht von dort, und das Fenster versucht, auf das Objekt zuzugreifen. Ich kann keine andere ähnliche Funktion wie Delete() finden.

Wie löscht man ein Objekt richtig?