
CChartObject sınıfına dayalı yeni GUI pencere öğelerinin tasarlanması ve uygulanması
Giriş
GUI arayüzlü yarı otomatik Uzman Danışman (EA) üzerine önceki makaleyi yazdıktan sonra arayüzün daha karmaşık göstergeler ve Uzman Danışman (EA) için bazı yeni işlevlerle geliştirilmesinin istendiği ortaya çıktı. MQL5 Standart Kitaplık sınıfları ile tanıştıktan sonra yeni pencere öğelerini uyguladım.
Bu makalede, GUI nesneleri için MQL5 Standart Kitaplık sınıflarını kullanmaya yönelik bir işlemi ve CChartObjectEdit sınıfından türetilen yeni sınıfların nasıl uygulanacağını açıklayacağım: CChartObjectProgressBar, CChartObjectSpinner ve CChartEditTable. CChartEditTable sınıfı, dinamik, iki boyutlu bir nesne dizisi kullanır, bu MQL5’te dinamik 2D bir nesne dizisinin nasıl uygulanacağına dair bir çalışma örneğidir.
1. CChartObject ve bunun soyundan gelenler
Standart MQL5 kitaplık sınıfı kullanmıyorsak grafikte herhangi bir nesne oluşturmak ve korumak için Nesne Fonksiyonlarını kullanmalıyız.
Nesneler ObjectCreate() fonksiyonu ile oluşturulur ve nesnenin türü bir ENUM_OBJECT değeri olarak ObjectCreate() fonksiyonuna geçirilir. Grafikteki tüm nesneler kendi özelliklerine sahiptir, bu Tamsayı, Çift veya Dizgi tipi olabilir. Tüm özellikler özel fonksiyonlar yoluyla ayarlanır ve alınır: ObjectGetInteger(), ObjectSetInteger(), ObjectGetDouble(), ObjectSetDouble(), ObjectGetString(), ObjectSetString(). Ayrıca belirli herhangi bir grafikte nesneleri silmek, taşımak ve silmek için fonksiyon vardır.
MQL5’teki OOP paradigması nedeniyle, çeşitli grafik nesnelerinin işlenmesi CChartObject sınıfı ve bunun soyundan gelenler kullanılarak yapılabilir.
CChartObject sınıfı, bir grafik üzerine koyulabilen herhangi bir grafik nesnesi için temel bir sınıftır. Lütfen aşağıdaki CChartObject nesnesi için temel kalıtım diyagramını gözlemleyin:
Şekil 1. CChartObject sınıfı için kalıtım diyagramı
Gördüğümüz gibi sağ alt köşede küçük bir üçgenle işaretlenmiş birkaç sınıf vardır.
Bunlar, diğer sınıfların üstleri olan sınıflardır. Temel olarak, aynı soydan gelen sınıflar nesne üzerinde çalışan yeni değişkenler ve yöntemler ekleyerek bir temel sınıf olanaklarını artırır. Bunlar ayrıca, türetilen bir nesneyi oluşturmak ve türünü geri döndürmek için Create() ve Type() yöntemlerinde farklılık gösterebilir.
Bunu örnekle göstereyim: CChartObjectTrend sınıfı, CChartObjectTrendByAngle, CChartObjectChannel, CChartObjectStdDevChannel, CChartObjectRegression ve CChartObjectPitchfork sınıflarının bir üstüdür.
CChartObjectTrend, OBJPROP_RAY_RIGHT ve OBJPROP_RAY_LEFT özelliklerine sahip nesneler için bir temel sınıftır ve aşağıdaki gibi tanımlanır:
class CChartObjectTrend : public CChartObject { public: //--- methods of access to properties of the object bool RayLeft() const; bool RayLeft(bool new_sel); bool RayRight() const; bool RayRight(bool new_sel); //--- method of creating the object bool Create(long chart_id,string name,int window, datetime time1,double price1,datetime time2,double price2); //--- method of identifying the object virtual int Type() const { return(OBJ_TREND); } //--- methods for working with files virtual bool Save(int file_handle); virtual bool Load(int file_handle); };
Bunlar, tanımda farklı yöntem türlerini ayırt etmeyi sağlayan yorumlardır.
Nesnenin özelliklerine erişim yöntemleri RayLeft() ve RayRight()’tır. Bunların uygulamaları, CChartObjectTrend nesnesi üzerinde çalışan ObjectGetInteger() ve ObjectSetInteger() yöntemlerini çağırmaktır.
bool CChartObjectTrend::RayLeft(bool new_ray) { //--- checking if(m_chart_id==-1) return(false); //--- return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_RAY_LEFT,new_ray)); }
Create() yöntemi, grafik üzerinde nesneyi oluşturma ve eklemeden sorumludur.
Bu, parametrelerden biri olarak OBJ_TREND ile ObjectCreate() yöntemini çağırır:
bool CChartObjectTrend::Create(long chart_id,string name,int window, datetime time1,double price1,datetime time2,double price2) { bool result=ObjectCreate(chart_id,name,OBJ_TREND,window,time1,price1,time2,price2); if(result) result&=Attach(chart_id,name,window,2); //--- return(result); }
Save() ve Load() yöntemleri, FileWriteInteger() ve FileLoadInteger() fonksiyonlarını kullanarak nesne verilerini bir sabit sürücüye depolar ve yükler:
bool CChartObjectTrend::Save(int file_handle) { bool result; //--- checking if(file_handle<=0) return(false); if(m_chart_id==-1) return(false); //--- writing result=CChartObject::Save(file_handle); if(result) { //--- writing value of the "Ray left" property if(FileWriteInteger(file_handle,(int) ObjectGetInteger(m_chart_id,m_name, OBJPROP_RAY_LEFT),CHAR_VALUE)!=sizeof(char)) return(false); //--- writing value of the "Ray right" property if(FileWriteInteger(file_handle,(int) ObjectGetInteger(m_chart_id,m_name, OBJPROP_RAY_RIGHT),CHAR_VALUE)!=sizeof(char)) return(false); } //--- return(result); } bool CChartObjectTrend::Load(int file_handle) { bool result; //--- checking if(file_handle<=0) return(false); if(m_chart_id==-1) return(false); //--- reading result=CChartObject::Load(file_handle); if(result) { //--- reading value of the "Ray left" property if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_RAY_LEFT, FileReadInteger(file_handle,CHAR_VALUE)))return(false); //--- reading value of the "Ray right" property if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_RAY_RIGHT, FileReadInteger(file_handle,CHAR_VALUE))) return(false); } //--- return(result); }
Hızlıca CChartObjectTrend’den gelen aynı soydan sınıfların tanımları üzerinden geçelim.
CChartObjectTrendByAngle sınıfı Angle() özellik değiştiriciyi ekler ve OBJ_TRENDBYANGLE nesne tipini geri döndürür:
class CChartObjectTrendByAngle : public CChartObjectTrend { public: //--- methods of access to properties of the object double Angle() const; bool Angle(double angle); //--- method of creating the object bool Create(long chart_id,string name,int window,datetime time1,double price1, datetime time2,double price2); //--- method of identifying the object virtual int Type() { return(OBJ_TRENDBYANGLE); } };
CChartObjectChannel sınıfı OBJ_CHANNEL nesne tipini geri döndürür ve kanalları işlediği için üç çift fiyat/tarih parametresi Create() yöntemine geçirilir:
class CChartObjectChannel : public CChartObjectTrend { public: //--- method of creating the object bool Create(long chart_id,string name,int window,datetime time1,double price1, datetime time2,double price2,datetime time3,double price3); //--- method of identifying the object virtual int Type() const { return(OBJ_CHANNEL); } };
CChartObjectStdDevChannel sınıfı Deviations() özellik değiştiricisini ve ek sapma parametresini Create() yöntemine ekler:
class CChartObjectStdDevChannel : public CChartObjectTrend { public: //--- methods of access to properties of the object double Deviations() const; bool Deviations(double deviation); //--- method of creating the object bool Create(long chart_id,string name,int window, datetime time1,datetime time2,double deviation); //--- method of identifying the object virtual int Type() const { return(OBJ_STDDEVCHANNEL); } //--- methods for working with files virtual bool Save(int file_handle); virtual bool Load(int file_handle); };
CChartObjectRegression sınıfı regresyon trend çizgisini oluşturur, sadece Create() ve Type() yöntemleri CChartObjectTrend sınıfındakilerden geçersiz kılınır:
class CChartObjectRegression : public CChartObjectTrend { public: //--- method of creating the object bool Create(long chart_id,string name,int window,datetime time1,datetime time2); //--- method of identifying the object virtual int Type() const { return(OBJ_REGRESSION); } };
CChartObjectPitchfork sınıfı dirgen tipini işler, ayrıca sadece Create() ve Type() yöntemleri değiştirilir:
class CChartObjectPitchfork : public CChartObjectTrend { public: //--- method of creating the object bool Create(long chart_id,string name,int window,datetime time1,double price1, datetime time2,double price2,datetime time3,double price3); //--- method of identifying the object virtual int Type() const { return(OBJ_CHANNEL); } };
Bu hızlı tarama, bazı başka sınıflara dayalı yeni grafik nesnesi sınıfını yazarken uygulanan temel kuralları göstermiştir:
- nesne oluşturma için Create() yöntemini değiştirme
- nesne tipini geri döndürmek için Type() yöntemini değiştirme
- özellik erişim değiştiricileri ekleme
Tüm kuralların uygulanması gerekmez, sadece yeni erişim değiştiriciler eklenebilir veya sınıfa yeni değişkenler ve/veya nesneler eklenebilir.
Daha fazla ayrıntıya girmeden önce, CChartObject yöntemlerinin grafik nesneleri üzerinde nasıl kullanılacağını açıklayayım.
ObjectSet ve ObjectGet yöntemleri grubunu kullanmak ve nesne özelliklerini kullanmak yerine, CChartObject veya aynı soydan gelen bir nesneyi belirlemek ve istenen özelliklerini değiştiren yöntemleri uygulamak yeterlidir. Bunu daha kolay hale getirmek için sıradan bir etiket örneği veriyorum.
Yazmak yerine:
void OnStart() { //--- string label_name="my_OBJ_LABEL_object"; if(ObjectFind(0,label_name)<0) { Print("Object ",label_name," not found. Error code = ",GetLastError()); ObjectCreate(0,label_name,OBJ_LABEL,0,0,0); ObjectSetInteger(0,label_name,OBJPROP_XDISTANCE,200); ObjectSetInteger(0,label_name,OBJPROP_YDISTANCE,300); ObjectSetInteger(0,label_name,OBJPROP_COLOR,White); ObjectSetString(0,label_name,OBJPROP_TEXT,UP); ObjectSetString(0,label_name,OBJPROP_FONT,"Wingdings"); ObjectSetInteger(0,label_name,OBJPROP_FONTSIZE,10); ObjectSetDouble(0,label_name,OBJPROP_ANGLE,-45); ObjectSetInteger(0,label_name,OBJPROP_SELECTABLE,false); ChartRedraw(0); } }
Bunu OOP paradigmasını kullanarak uygulayabiliriz:
1. CChartObjectLabel nesnesini belirleyin:
CChartObjectLabel label;
2. Nesne üzerinde çalışın:
int OnInit() { //--- label.Create(0, label_name, 0, 0); label.X_Distance(200); label.Y_Distance(300); label.Color(White); label.Description(UP); label.Font("Wingdings"); label.FontSize(10); label.Angle(-45); label.Selectable(false); //--- return(0); }
Görebileceğiniz gibi, temel fark artık bir label_name dizgisi üzerinde çalışmadığımız:
string label_name="my_OBJ_LABEL_object";
ve parametrelerden biri olarak label_name ile ObjectSetInteger(), ObjectGetInteger(), ObjectSetDouble(), ObjectGetDouble() fonksiyonlarını çağırmamızdır, fakat CChartObjectLabel nesnesini belirliyor ve bunun yöntemlerini kullanıyoruz. Bu sadece hatırlaması daha kolay ve uygulaması mantıklı olmakla kalmaz, aynı zamanda daha hızlı yazılır.
MQL5 kod düzenleyici bize nesne örneğinden sonra nokta (.) koyarken kod tamamlama işlevini sağlar. Belirli bir özelliği ayarlamak veya almak için hangi OBJPROP özelliğinin düzene koyulacağını görmek için MQL5 belgelerini taramaya gerek yoktur.
Önceden açıklanan CChartObjectTrend sınıfına benzer şekilde, bir sol veya sağ ışın almak veya ayarlamak için CChartObjectTrend nesnesini belirlemek ve RayRight() veya RayLeft() yöntemini uygulamak yeterlidir:
CChartObjectTrend trendline; trendline.RayRight(true);
2. ProgressBar
Uygulayacağımız ilk pencere öğesi ProgressBar’dır. İlerleme çubukları, 0’dan x yüzdeye kadar çalışma ilerlemesini gösterir.
Daha güçlü hale getirmek için, maksimum değeri 100 ile değil, fakat herhangi bir pozitif tamsayı değeri ile sınırlayalım. İlerleme çubuğuna göre boyutunu değiştirecek bir renkli şeride ihtiyacımız var. Akla ilk gelen şey iki dikdörtgen kullanmaktır, fakat ben başka bir yol seçtim: biri diğerinin içinde olan, farklı arka plan renklerine sahip iki CChartObjectEdit nesnesi kullanmak.
Kodlamayı basitleştirir ve değerini göstermek için ilerleme çubuğunun içerisine koyulabilen metin ekler. Gereksinime bağlı olarak İlerleme çubuğumuzun yatay veya dikey olması güzel olurdu.
2.1. ProgressBar uygulaması
CChartObjectProgress sınıfı CChartObjectEdit sınıfından türetilir.
Değeri tutmak için dahili özel değişkenler ve değer üzerinde kısıtlamalar ekledim: m_value, m_min, m_max.
İlerleme çubuğunun yönü, tamsayı değeri olarak ayarlanır ve m_direction değişkeni ile tutulur. Renk, m_color değişkeni ile tutulur. Herhangi bir şekilde amacımız için tanınan hiçbir değer olmadığından Type() yöntemi OBJ_EDIT değerini geri döndürür. Sınıf tanımı içinde CChartObjectEdit m_bar fark edilebilir - bu, m_value değişkenine bağlı olarak boyutunu değiştiren iç çubuktur. Ek değişkenler m_name ve m_chart dahili olarak m_bar değişkeni için değerleri tutar.
class CChartObjectProgressBar : public CChartObjectEdit { private: int m_value; int m_min; int m_max; int m_direction; color m_color; CChartObjectEdit m_bar; string m_name; long m_chart_id; public: int GetValue(); int GetMin(); int GetMax(); void SetValue(int val); void SetMin(int val); void SetMax(int val); void SetColor(color bgcol,color fgcol); bool Create(long chart_id,string name,int window,int X,int Y, int sizeX,int sizeY,int direction); //--- method of identifying the object virtual int Type() const { return(OBJ_EDIT); } };
Create() yöntemi ProgressBar nesnesini oluşturur ve bunu grafiğe ekler.
Y değişkeninin dikey çubuğun çekilmesi durumunda sizeY değişkeninden çıkarıldığını fark edebilirsiniz, bunun nedeni normalde CChartObjectEdit’in üstten aşağıya doğru çizilmesidir ve ben alttan yukarıya doğru iç dikdörtgeni çizmek istedim:
bool CChartObjectProgressBar::Create(long chart_id,string name,int window,int X,int Y, int sizeX,int sizeY,int direction=0) { bool result=ObjectCreate(chart_id,name,(ENUM_OBJECT)Type(),window,0,0,0); m_name=name; m_chart_id=chart_id; m_direction=direction; if(direction!=0) { Y=Y-sizeY; } ObjectSetInteger(chart_id,name,OBJPROP_BGCOLOR,White); ObjectSetInteger(chart_id,name,OBJPROP_COLOR,White); ObjectSetInteger(chart_id,name,OBJPROP_SELECTABLE,false); ObjectSetInteger(chart_id,name,OBJPROP_READONLY,true); result&=m_bar.Create(chart_id,name+"m_bar",window,X,Y,sizeX,sizeY); m_bar.Color(White); m_bar.ReadOnly(true); m_bar.Selectable(false); //--- if(result) result&=Attach(chart_id,name,window,1); result&=X_Distance(X); result&=Y_Distance(Y); result&=X_Size(sizeX); result&=Y_Size(sizeY); //--- return(result); }
SetColor() yöntemi, her iki dikdörtgende arka plan ve ön plan renklerini ayarlar:
void CChartObjectProgressBar::SetColor(color bgCol,color fgCol=White) { m_color=bgCol; m_bar.BackColor(m_color); m_bar.Color(fgCol); }
SetValue() yöntemi, hem m_val değerini ayarlamaktan hem de iç dikdörtgen nesne boyutunu yeniden hesaplamaktan sorumludur.
Boyut yatay ve dikey çubuklar için farklı şekilde hesaplanır:
void CChartObjectProgressBar::SetValue(int val) { if(m_direction==0) // horizontal ProgressBar { double sizex=(double)ObjectGetInteger(m_chart_id,m_name,OBJPROP_XSIZE,0); double stepSize=sizex/(m_max-m_min); m_value=val; m_bar.Create(m_bar.ChartId(),m_bar.Name(),m_bar.Window(), m_bar.X_Distance(),m_bar.Y_Distance(),(int)MathFloor(stepSize*m_value),m_bar.Y_Size()); } else { double sizey=(double)ObjectGetInteger(m_chart_id,m_name,OBJPROP_YSIZE,0); double stepSize=sizey/(m_max-m_min); m_value=val; m_bar.Create(m_bar.ChartId(),m_bar.Name(),m_bar.Window(), m_bar.X_Distance(),(int)(this.Y_Distance()+sizey-MathFloor(stepSize*m_value)), m_bar.X_Size(),(int)MathFloor(stepSize*m_value)); } m_bar.Description(IntegerToString(m_value)); }
2.2. ProgressBar Demo
Halihazırda CChartObjectProgressBar sınıfını uyguladığımız için bunu eylem halinde görme zamanı.
Grafik üzerine yeni bir ilerleme çubuğu yerleştirmek için CChartObjectProgressBar nesnesini belirlemek ve Create() ve uygun özellik yöntemlerini kullanmak yeterlidir:
progressBar.Create(0, "progressBar1", 0, 10, 10, 200, 40); progressBar.SetColor(YellowGreen); progressBar.SetMin(0); progressBar.SetMax(100); progressBar.SetValue(0);
Grafik üzerine altı farklı ilerleme çubuğu koyan ve ekranda herhangi bir nesneye tıklandıktan sonra bunların değerini değiştiren demo bir Uzman Danışman (EA) yazdım.
Bu ve diğer demolar için tam kaynak kodu eklerdedir, lütfen aşağıdaki sunuma bakın:
3. Değer Değiştirici
Değer değiştirici pencere öğesi, bir alan ve iki düğme içeren bir pencere öğesidir. Düğmelerden birine tıklayarak düzenleme alanında bir değeri artırmak veya azaltmak için kullanılır.
Nesneyi tasarlarken sadece tamsayı değerler üzerinde çalışmak istemedim, bu nedenle Değer değiştirici çift tipte çalışmak üzere tasarlandı. Değer değiştirici ayrıca mevcut değeri artırma veya azaltma değeri olan adım boyutunu tanımlayabilir. Ayrıca, aşılamayan minimum ve maksimum değere sahip olmalıdır.
3.1. Değer değiştiriciyi uygulama
MQL5’te CChartObjectSpinner sınıfı olarak birleştirilebilen CChartObjectEdit ve CChartObjectButton sınıflarına sahibiz. CChartObjectSpinner, CChartObjectEdit mirasçısıdır ve iki özel eleman CChartObjectButton nesnesi içerir.
m_min ve m_max eleman değişkenlerinde depolanan minimum ve maksimum m_value için kısıtlamalar vardır ve m_precision değişkeni n. hane değerine kadar hesaplama hassasiyetini depolar. Gerekli yöntemler değere erişim, artırma ve azaltma adım boyutunu ayarlamaya ve değeri ayarlamaya yöneliktir.
class CChartObjectSpinner: public CChartObjectEdit { private: double m_value; double m_stepSize; double m_min; double m_max; int m_precision; string m_name; long m_chart_id; CChartObjectButton m_up,m_down; public: double GetValue(); double GetMin(); double GetMax(); void SetValue(double val); void SetMin(double val); void SetMax(double val); double Inc(); double Dec(); bool Create(long chart_id,string name,int window,int X,int Y, int sizeX,int sizeY,double val,double stepSize,int precision); //--- method of identifying the object virtual int Type() const { return(OBJ_EDIT); } };
Create() yöntemi yeni CChartObjectSpinner oluşturur ve bunu grafiğe ekler.
CChartObjectEdit’in sağ tarafında oluşturulan, her biri CChartObjectEdit yüksekliğinin yarım yüksekliğine sahip iki CChartObjectButtons vardır.
Artırma düğmesi ‘+’ işaretine ve azaltma düğmesi ‘-’ işaretine sahiptir.
bool CChartObjectSpinner::Create(long chart_id,string name,int window,int X,int Y, int sizeX,int sizeY,double val=0.0,double stepSize=1.0,int precision=8) { bool result=ObjectCreate(chart_id,name,(ENUM_OBJECT)Type(),window,0,0,0); m_name=name; m_chart_id=chart_id; m_value=val; m_stepSize=stepSize; m_precision=precision; ObjectSetInteger(chart_id,name,OBJPROP_BGCOLOR,White); ObjectSetInteger(chart_id,name,OBJPROP_COLOR,Black); ObjectSetInteger(chart_id,name,OBJPROP_SELECTABLE,false); ObjectSetInteger(chart_id,name,OBJPROP_READONLY,true); result&=m_up.Create(chart_id, name+"_up", window, X+sizeX, Y, 15, sizeY/2); result&=m_down.Create(chart_id, name+"_down", window, X+sizeX, Y+sizeY/2, 15, sizeY/2); m_up.Description("+"); m_down.Description("-"); ObjectSetString(chart_id,name,OBJPROP_TEXT,0,(DoubleToString(m_value,precision))); //--- if(result) result&=Attach(chart_id,name,window,1); result&=X_Distance(X); result&=Y_Distance(Y); result&=X_Size(sizeX); result&=Y_Size(sizeY); //--- return(result); }
SetValue() yöntemi, <m_min, m_max> aralığında olması koşuluyla özel m_value değişkenini çift değere ayarlar.
void CChartObjectSpinner::SetValue(double val) { if(val>=m_min && val<=m_max) m_value=val; this.Description(DoubleToString(m_value)); }
Inc() yöntemi değeri m_max değerinden fazla olmamak kaydıyla belirli adım boyutunda artırır.
Çift değerleri verilen hassasiyetle karşılaştırmak için NormalizeDouble() fonksiyonunu kullanmak zorunda kaldığıma lütfen dikkat edin.
double CChartObjectSpinner::Inc(void) { if(NormalizeDouble(m_max-m_value-m_stepSize,m_precision)>0.0) m_value+=m_stepSize; else m_value=m_max; this.Description(DoubleToString(m_value, m_precision)); m_up.State(false); return m_value; }
Dec() yöntemi değeri m_min değerinden az olmamak kaydıyla belirli adım boyutunda azaltır.
double CChartObjectSpinner::Dec(void) { if(NormalizeDouble(m_value-m_stepSize-m_min,m_precision)>0.0) m_value-=m_stepSize; else m_value=m_min; this.Description(DoubleToString(m_value,m_precision)); m_down.State(false); return m_value; }
3.2. Değer Değiştirici Demo
Değer değiştirici nesnelerini test etme zamanı. Bunları kullanmak için, CChartObjectSpinner nesnesini belirlemek ve Create(), SetMin() ve SetMax() yöntemlerini kullanmak yeterlidir.
spinner.Create(0, "spinner1", 0, 10, 10, 200, 40, 0.0, 0.4); spinner.SetMin(0); spinner.SetMax(100);
Üç Değer değiştirici pencere öğesi kullanan ve herhangi bir Değer değiştirici düğmesine tıklandıktan sonra tüm değerleri ekleyen bir demo hazırladım.
Bu, OnChartEvent() fonksiyonunun içinde yapılır;
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- Check the event by pressing a mouse button if(id==CHARTEVENT_OBJECT_CLICK) { if (sparam=="spinner1_up") spinner.Inc(); if (sparam=="spinner1_down") spinner.Dec(); if (sparam=="spinner2_up") spinner2.Inc(); if (sparam=="spinner2_down") spinner2.Dec(); if (sparam=="spinner3_up") spinner3.Inc(); if (sparam=="spinner3_down") spinner3.Dec(); label.Description(DoubleToString(NormalizeDouble(spinner.GetValue()+spinner2.GetValue()+spinner3.GetValue(),10),10)); ChartRedraw(); } }
Lütfen ekteki demoya bakın:
4. CChartObjectEditTable
Çok sayıda çoklu zaman dilimi (MTF) Uzman Danışmanında (EA), her bir zaman dilimi için ayrı şekilde görüntülenen gösterge değerleri vardır.
Bazen her bir zaman dilimi farklı renklerdeki dikdörtgenlerden veya karelerden oluşan 2D tablo formunda görüntülenen farklı gösterge ayarlarına sahiptir. CChartObjectEditTable sınıfını oluşturarak bu tür nesnelerden oluşan evrensel bir 2D tablo tasarladım. Bu sınıf, 2D dinamik nesne dizisi kullandığım için rastgele miktarda satır ve sütunu tutabilir.
Tasarım sırasında her bir hücre için ayrı bir renk tanımlamaya ve ayrıca herhangi bir hücreye farklı metin dizgileri koyma olanağını eklemeye karar verdim. Hücreler eşit boyuta sahiptir, fakat ağırlıklarını ve genişliklerini ve hücreler arasındaki boşluğu tanımlamak istedim.
CChartObjectEditTable sınıfı CArrayObj işaretçisini iki boyutlu bir nesne dizisinde tutar ve m_rows ve m_columns eleman değişkenleri tablodaki satırlar ve sütunların sayısını tutar.
Tüm hücre CChartObjectEdit nesnelerinin önekini tablo içinde tutan m_baseName eleman değişkeni vardır. GetColor(), SetColor(), GetText(), SetText() yöntemleri renk ve metin değerlerini istenen herhangi bir hücreye ayarlamaya ve almaya yöneliktir. Delete() yöntemi, Create() yöntemi ile oluşturulan tüm nesneleri siler.
class CChartObjectEditTable { private: CArrayObj *array2D; int m_rows; int m_cols; string m_baseName; public: bool Create(long chart_id,string name,int window,int rows,int cols,int startX,int startY, int sizeX,int sizeY,color Bg,int deltaX,int deltaY); bool Delete(); bool SetColor(int row,int col,color newColor); color GetColor(int row,int col); bool SetText(int row,int col,string newText); string GetText(int row,int col); };
Create() yöntemi, CChartObjectEdit nesnelerinin iki boyutlu dinamik tablosunu oluşturur.
Lütfen MQL5’te 2D nesne dizisinin nasıl oluşturulduğunu gözlemleyin: öncelikle 2D dizisine bir işaretçi belirliyoruz ve ardından diziyi belirli sayıda CArrayObj() nesnesi ile dolduruyoruz, yani dizi içinde diziler oluşturuyoruz. Tüm diziler tablonun sütunları için tutucular olarak görülebilir.
Her bir sütun, her biri görüntülenecek tek bir hücre olan CChartObjectEdit nesnelerini tutan satırlar içerir.
bool CChartObjectEditTable::Create(long chart_id,string name,int window,int rows=1,int cols=1, int startX=0,int startY=0,int sizeX=15,int sizeY=15, color Bg=White,int deltaX=5,int deltaY=5) { m_rows=rows; m_cols=cols; m_baseName=name; int i=0,j=0; array2D=new CArrayObj(); if (array2D==NULL) return false; for(j=0; j<m_cols; j++) { CArrayObj *new_array=new CArrayObj(); if (array2D==NULL) return false; array2D.Add(new_array); for(i=0; i<m_rows; i++) { CChartObjectEdit *new_edit=new CChartObjectEdit(); new_edit.Create(chart_id, name+IntegerToString(i)+":"+IntegerToString(j), window, startX+j*(sizeX+deltaX), startY+i*(sizeY+deltaY), sizeX, sizeY); new_edit.BackColor(Bg); new_edit.Color(White); new_edit.Selectable(false); new_edit.ReadOnly(true); new_edit.Description(""); new_array.Add(new_edit); } } return true; }
SetColor() yöntemi, herhangi bir tek hücrenin rengini ayarlar. Başlangıçta, sütun dizisini ve ardından sütun dizisindeki n. elemanı bulur.
Ardından, elemanın renk değeri BackColor() yöntemi uygulanarak değiştirilir.
bool CChartObjectEditTable::SetColor(int row,int col,color newColor) { CArrayObj *sub_array; CChartObjectEdit *element; if((row>=0 && row<m_rows) && (col>=0 && col<m_cols)) { if(array2D!=NULL) { sub_array=array2D.At(col); element=(CChartObjectEdit*)sub_array.At(row); element.BackColor(newColor); return true; } } return false; }
GetColor() yöntemi, hücreyi bulmak için SetColor() yöntemi ile aynı algoritmaya sahiptir, fakat belirli herhangi bir hücrenin renk değerini geri döndürür.
color CChartObjectEditTable::GetColor(int row,int col) { CArrayObj *sub_array; CChartObjectEdit *element; if((row>=0 && row<m_rows) && (col>=0 && col<m_cols)) { if(array2D!=NULL) { sub_array=array2D.At(col); element=(CChartObjectEdit*)sub_array.At(row); return element.BackColor(); } } return NULL; }
SetText() yöntemi elemanı bulur ve Description() yöntemini uygulayarak metin değerini ayarlar.
bool CChartObjectEditTable::SetText(int row,int col,string newText) { CArrayObj *sub_array; CChartObjectEdit *element; if((row>=0 && row<m_rows) && (col>=0 && col<m_cols)) { if(array2D!=NULL) { sub_array=array2D.At(col); element=(CChartObjectEdit*)sub_array.At(row); element.Description(newText); return true; } } return false; }
Delete() yöntemi, Create() yöntemi ile oluşturulan tüm nesneleri siler.
Başlangıçta, tüm sütun dizilerini siler ve ardından bellekten array2D nesnesini siler.
bool CChartObjectEditTable::Delete(void) { for(int j=0; j<m_cols; j++) { CArrayObj *column_array=array2D.At(j); column_array.Clear(); delete column_array; } delete array2D; return true; }
4.2. CChartObjectEditTable Demo
CChartObjectEditTable pencere öğesini kullanmak için, CChartEditTable nesnesini belirlemek ve tablonun kaç tane satır ve sütun içermesi gerektiğini gösteren parametreler ile Create() yöntemini kullanmak gerekir.
Ardından, özellik değiştiriciler kullanılarak herhangi bir hücre üzerinde renk ve metin basitçe değiştirilebilir.
table.Create(0,"t",0,1,10,10,10,15,15,Yellow); table.SetColor(2,2,Red); table.SetText(2,2,"2");
Lütfen CChartObjectEditTable nesnesini kullanma olasılıklarını gösteren, tarafımca hazırlanan komut dosyasına bakın.
Komut dosyasının kaynak kodu ektedir.
Sonuç
Makalede CChartObject sınıfı üzerinde türetilen yeni grafik pencere öğelerini oluşturmaya yönelik bir işlemi açıkladım ve tanıttım.
Uygulanan pencere öğelerini kullanmaya yönelik işlem çok basittir ve sadece birkaç kod satırı sürmektedir.
Pencere öğelerini kullanmak için lütfen Uzman Danışmana (EA) veya gösterge koduna ChartObjectsExtControls.mqh dosyasını dahil edin.
MetaQuotes Ltd tarafından İngilizceden çevrilmiştir.
Orijinal makale: https://www.mql5.com/en/articles/196





- Ücretsiz alım-satım uygulamaları
- İşlem kopyalama için 8.000'den fazla sinyal
- Finansal piyasaları keşfetmek için ekonomik haberler
Gizlilik ve Veri Koruma Politikasını ve MQL5.com Kullanım Şartlarını kabul edersiniz