"MQL5 Tarif Defteri Gösterge Alt Pencere Kontrolleri - Düğmeler" makalesi için tartışma - sayfa 7

 
TheXpert:
Makalenizin mükemmel olduğundan bu kadar emin misiniz?

Okuduğunuz için çok memnun oldum.

Tüm soruları uygun başlıkta yanıtlamaktan mutluluk duyacağım.

===

Gereksiz yanlış anlamalar olmasın diye söylüyorum, Anatoly'ye karşı hiçbir şeyim yok! Makale için kendisine tebrikler! Ancak sorulara cevap vermek gerekiyor...

 
DC2008:

Affedersiniz, sizi başka bir eğitim veya tarif yazmaktan alıkoyuyor olabilir miyim?

Değilse, gösterge alt penceresindeki kontrol hakkındaki makalenizi tartışmaya devam edelim. Yani, bir göstergede nasıl kullanışlı bir menü yapılacağına dair toplu bir çözüm (veya bir fikir) sunuyorsunuz. Güzel, makalenin amacı çok değerli! Ancak "yeni başlayan" bir programcı tüm bu cephaneliği nasıl kullanabilir? Özel fonksiyonlar nereye yerleştirilir? Örnekle gösterin. Ve aynı zamanda, örneğin 5 düğme kullanmak için kodda neleri düzeltmeniz gerektiğini açıklayın? Bunu bir acemi sorusu olarak düşünün.

Hayır, değilsin. Henüz bir şey yazmıyorum. Yılda en az bir gün dinlenmem gerekiyor. Sadece dinlenmek ilginç değildir, özellikle de uzun bir süre için. )

Bu kitlesel bir karar değil ve ben de bu konuda yazmadım. Olmamış bir şeyi olmuş gibi göstermeyelim. Bunun evrensel bir çözüm değil, özel bir durum olduğu zaten tartışmanın başında dile getirildi. Bence yeni başlayan birinin pratik yapması için iyi bir örnek. Ve hazır bir çözümü bedavaya alıp, ağzı açık, geniş bir gülümsemeyle güneşi karşılamak için koşmak değil. ) Anlıyor musunuz? Programlama öğrenmenin en başında böyle basit ve net bir örnek isterdim. Özellikle de bu hayatınızdaki ilk programlama diliyse ve ondan önce tüm hayatınızın faaliyeti tamamen farklı bir alandaysa, hiçbir şekilde onunla bağlantılı değilse.

Bu durumda, 5 düğme yapmak için, dizilerin boyutunu değiştirmemiz ve nesne düğmelerinin adları, düğmelerde görüntülenen metin ve düğme durumları için dizileri bildirirken gereksiz öğeleri hariç tutmamız gerekir.

Bir dizi düğme durumu vardır, bu nedenle hangi düğmeye basıldığını kontrol etmek ve yalnızca düğmenin rengini değiştirmek yerine başka (kullanıcı tarafından istenen) bir eylem gerçekleştirmek için aynı ilke kullanılabilir. Bu, örneğin, alım satım işlevleri olabilir (ve sadece değil): bekleyen tüm emirleri silme, tüm pozisyonları kapatma vb. Fikirler sonsuzdur. Ve eğer hiç fikir yoksa, o zaman yanlış türde bir faaliyet seçmişsiniz demektir. )

Bunu uygulamak için, örneğin ENUM_SCRIPT adıyla özel bir numaralandırmanın (bunun da oluşturulması gerekir) tanımlayıcılarıyla başlatılacak başka bir dizi oluşturmanız gerekir. Ve tanımlayıcılar daha sonra çağrılacaktır, örneğin: SCRIPT_01 =0, SCRIPT_02 =2, vb. Ayrıca döngüde, paneldeki düğmenin basılı olup olmadığını kontrol ederken, hangi tanımlayıcının basılı düğmeye bağlı olduğunu ve düğmenin mevcut durumunu belirlemeniz ve ardından ilgili işlevi yürütülmesi için programa aktarmanız gerekecektir.

Bilerek örnek bir kod göstermeyeceğim. Yeni başlayanlar için bir ev ödevi olsun. )

Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства ордеров
Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства ордеров
  • www.mql5.com
Стандартные константы, перечисления и структуры / Торговые константы / Свойства ордеров - Документация по MQL5
 

Dediğiniz gibi değişiklikleri yaptım:

//--- Düğmelerde görüntülenen metin
string button_texts[BUTTON_ROWS][BUTTON_COLUMNS]=
  {
     {"Button 01","Button 02","Button 03","Button 04"},
     {"Button 05"}
  };
//--- Nesne adları
string button_object_names[BUTTON_ROWS][BUTTON_COLUMNS]=
  {
     {"button_01","button_02","button_03","button_04"},
     {"button_05"}
  };
....
bool button_states[BUTTON_ROWS][BUTTON_COLUMNS]=
  {
     {true,false,false,false},
     {false}
  };

Ve ekranda gördüğüm şey bu:

Bunu nasıl düzeltebilirim? (Ben acemiyim)

 
DC2008:

Dediğiniz gibi değişiklikleri yaptım:

Ve ekranda gördüğüm şey bu:

Bunu nasıl düzeltebilirim? (Ben acemiyim)

Bunun gibi:

#define  BUTTON_COLUMNS 5 // Genişliğe göre düğme sayısı
#define  BUTTON_ROWS    1 // Yüksekliğe göre düğme sayısı
...
//--- Düğmelerde görüntülenen metin
string button_texts[BUTTON_ROWS][BUTTON_COLUMNS]=
  {
     {"Button 01","Button 02","Button 03","Button 04","Button 05"}
  };
//--- Nesne adları
string button_object_names[BUTTON_ROWS][BUTTON_COLUMNS]=
  {
     {"button_01","button_02","button_03","button_04","button_05"}
  };
...
//--- Düğme durumları
bool button_states[BUTTON_ROWS][BUTTON_COLUMNS]=
  {
     {true,false,false,false,false}
  };
 

Oh, harika! Çalışıyor.

Ama fonksiyonlarımı düğmelere nasıl bağlayacağımı anlamıyorum. Bana bir örnek gösterin.

 
DC2008:

Oh, harika! Çalışıyor.

Ama fonksiyonlarımı düğmelere nasıl bağlayacağımı anlamıyorum. Bana bir örnek gösterin.

Pekala, sizin başlattığınız "acemi" oyununa devam edelim. )

Hangi noktada takılıp kaldınız? Mevcut noktada nasıl anlaşıldığına dair bir girişim gösterin. Beş tanımlayıcıya sahip bir numaralandırma ve elemanlarına bu tanımlayıcıların atanması gereken bir dizi oluşturun.

 
bool fun_states[BUTTON_ROWS][BUTTON_COLUMNS]=
  {
     {true,false,false,false,false}
  };
enum ENUM_SCRIPT
  {
   SCRIPT_01 =0,
   SCRIPT_02 =1,
   SCRIPT_03 =2,
   SCRIPT_04 =3,
   SCRIPT_05 =4,
  };
void F1()
  {Print("F1");}
bool F2()
  {Print("F2");return(false);}
int F3()
  {Print("F3");return(0);}
double F4()
  {Print("F4");return(0.1);}
color F5()
  {Print("F5");return(clrAliceBlue);}

Peki şimdi ne yapacağız?

 
DC2008:

Peki şimdi ne yapacağız?

İhtiyacınız olan dizi türü budur:

//--- Komut Dosyaları
ENUM_SCRIPT buttons_scripts[NUMBER_BUTTONS_HEIGHT][NUMBER_BUTTONS_WIDTH]=
  {
     {SCRIPT_01,SCRIPT_02,SCRIPT_03,SCRIPT_04,SCRIPT_05}
  };

O zaman bunun gibi bir fonksiyon yazmanız gerekir:

//+------------------------------------------------------------------+
//|| Komut dosyaları çalıştırılıyor |
//+------------------------------------------------------------------+
void ScriptOn()
  {
   for(int i=0; i<NUMBER_BUTTONS_WIDTH; i++)
     {
      for(int j=0; j<NUMBER_BUTTONS_HEIGHT; j++)
        {
         //--- Bu düğmeye basılırsa, ilgili komut dosyasını çalıştıracağız
         if(buttons_state[j][i])
           {
            if(buttons_scripts[j][i]==SCRIPT_01)
              {
               F1();
               return;
              }
            //---
            if(buttons_scripts[j][i]==SCRIPT_02)
              {
               F2();
               return;
              }
            //---
            if(buttons_scripts[j][i]==SCRIPT_03)
              {
               F3();
               return;
              }
            //---
            if(buttons_scripts[j][i]==SCRIPT_04)
              {
               F4();
               return;
              }
            //---
            if(buttons_scripts[j][i]==SCRIPT_05)
              {
               F5();
               return;
              }
           }
        }
     }
  }

...ve bu fonksiyonu kodun bu kısmına yerleştirin:

//--- Bir grafik nesne üzerinde sol fare düğmesi tıklamalarını izleme
   if(id==CHARTEVENT_OBJECT_CLICK)
     {
      //--- Eğer butona tıklarsanız
      if(InitializeButtonStates(sparam))
        {
         //--- Düğmeler için renkleri ayarlayın
         ChangeButtonColorOnClick();
         //--- Komut dosyasını çalıştırın
         ScriptOn();
        }
      //--- Grafiği güncelleyin
      ChartRedraw();
      return;
     }

Ve sonra gerekirse kodu nasıl optimize edeceğinizi düşünebilirsiniz. :)

 
tol64:

Ben böyle yapıyorum.

Başlangıçta izleme özelliği etkin olan program, boşaltma sırasında bunu kapatıyor. Ve grafikte kalan ve izlemeye ihtiyaç duyan program, etkin olup olmadığını kontrol eder ve devre dışı bırakılmışsa etkinleştirir.

İfadelerin belirsizliğini ortadan kaldırmak için önceki sayfadaki yazımdaki Uzman Danışman ve gösterge kodu örnekleri üzerinde varyantınızı vermeniz istenir.

Birinin fare olaylarının izlenmesini devre dışı bırakıp bırakmadığını sürekli kontrol etmeye gerek yoktur. Daha doğrusu, kendinizi herhangi bir durumdan korumak istiyorsanız, kontrol edebilirsiniz, ancak bunun çok fazla olduğunu düşünüyorum.

Belki de geliştiricilere CHART_EVENT_MOUSE_MOVE değiştiğinde CHARTEVENT_CHART_CHANGE oluşturmalarını önermeliyiz? Ardından, Uzman Danışman çalışırken gerekli ayarı zarif bir şekilde geri yüklemek mümkün olacaktır.

Şimdiye kadar bu varyantı aldım:

#property copyright "Copyright 2013, komposter"
#property link      "http://www.komposter.me/"
#property version   "1.00"
#property indicator_chart_window

input   bool    EnableMouseDetect = false; // true - fare izleme ile çalışır, false - izleme olmadan

bool PrevState = false;

//+------------------------------------------------------------------+
//| Özel gösterge başlatma işlevi |
//+------------------------------------------------------------------+
int OnInit()
{
        if ( EnableMouseDetect )
        {
                //--- Geçerli durumu alın
                PrevState = (bool)ChartGetInteger(0,CHART_EVENT_MOUSE_MOVE);
                //--- Fare olayı izlemeyi etkinleştir
                if ( PrevState == false ) ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
        }

        return(0);
}

//+------------------------------------------------------------------+
//| Uzmanın başlangıçtan çıkarma işlevi |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
        if ( EnableMouseDetect )
        {
                //--- Fare olayı izlemeyi devre dışı bırak
                if ( PrevState == false )
                {
                        ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,false);
                        ChartRedraw(); // Bu satır olmadan, izleme yalnızca bir tik geldiğinde devre dışı bırakılır. Bu şekilde mi tasarlandı?
                }
        }
}

//+------------------------------------------------------------------+
//| OnTick|
//+------------------------------------------------------------------+
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[])
       {
        
        return(rates_total);
       }
//+------------------------------------------------------------------+
//| ChartEvent fonksiyonu|
//+------------------------------------------------------------------+
void OnChartEvent(const int    id,
                  const long   &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--- Fare hareketini ve sol fare düğmesine basmayı izleme
   if(id==CHARTEVENT_MOUSE_MOVE)
     {
      static int count=1;
      Print("CHARTEVENT_MOUSE_MOVE; EXPERT; ",count);
      count++;
     }
  }
//+------------------------------------------------------------------+

Bir gösterge yaptım, ancak bir parametre ile: EnableMouseDetect = true ile çalıştır - izlemeyi kontrol eder, false - izleme etkinse sadece olay sayısını yazdırır.


------------------
Şimdi biraz daha düşündüm ve kabul etmek zorundayım - bu seçenek işe yaramayacak. Fareyi izleyen ilk programı çalıştırırsanız (izlemeyi etkinleştirecektir), sonra ikincisini (zaten neyin etkin olduğunu görecektir) ve sonra ilkini silerseniz, izlemeyi devre dışı bırakacak ve ikincisine hiçbir şey kalmayacaktır. Yani, izlemenin gerekli olduğunu bildirmek için bir tür semafor bulmamız gerekiyor.

Ve burada yapılan araştırma ışığında (işlemci üzerindeki yük hakkında) bu tür koltuk değnekleri gerekli değildir.

Bu yüzden önerimi geliştiricilere oylatmayı öneriyorum ve konu kapatılabilir.

 
ChartRedraw(); // Bu satır olmadan, izleme yalnızca bir tik geldiğinde devre dışı bırakılır. Bu şekilde mi tasarlandı?
MT5, grafik özelliklerinin asenkron güncellenmesine sahiptir. Yani, bir özelliği ayarlamış olmamız, terminalin onu hemen aldığı anlamına gelmez. ChartRedraw() fonksiyonu, tüm özelliklerin terminal tarafından yeniden okunması için kullanılır. Ayrıca ChartGet... ObjectGet kullanabilirsiniz, bu durumda özellikler de yeniden okunacaktır.
Документация по MQL5: Операции с графиками / ChartRedraw
Документация по MQL5: Операции с графиками / ChartRedraw
  • www.mql5.com
Операции с графиками / ChartRedraw - Документация по MQL5