MQL5 Tarif Defteri Gösterge Alt Pencere Kontrolleri - Düğmeler
Giriş
Bu makalede, düğme kontrolleri ile bir kullanıcı arayüzünü geliştirme örneğini ele alacağız. Kullanıcı ile etkileşim fikrini iletmek için, imleç üzerlerine geldiğinde düğmelerin renkleri değişecektir. İmleç bir düğmenin üzerindeyken, düğme rengi hafifçe koyulaşacak ve düğmeye tıklandığında büyük ölçüde koyulaşacaktır. Ayrıca, her düğmeye araç ipuçları ekleyerek sezgisel bir arayüz oluşturacağız.
Makale aynı zamanda, fare hareketi olayı, sol fare düğmesinin durumu, nesneye sol tıklama ve grafik özelliklerini değiştirme olayı gibi bazı olayları da kapsayacaktır. Gösterge alt penceresinin tüm alanını kaplayacak bir düğme paneli oluşturacağız. Örnekleme amacıyla, düğmeler, her sırada dört düğme olacak şekilde üç sıra halinde düzenlenecektir.
Geliştirme
MQL5'te düğmeler, OBJ_BUTTON (Düğme), OBJ_BITMAP (Bitmap), OBJ_BITMAP_LABEL (Bitmap Etiketi) veya OBJ_EDIT (Düzenle) gibi çeşitli grafik nesneleri kullanılarak oluşturulabilir.
Bu makalede, düğmeleri OBJ_EDIT kullanarak oluşturacağız. Bu türde nesneler Salt Okunur hale getirilebilir. Bunlar aynı zamanda, belirttiğiniz metni görüntüleyebilmeleri açısından kullanışlıdır. Ayrıca, nesnenin köşelerini keskinleştirirken kenarlığını koruyabilirsiniz.
Öyleyse, MQL5 Sihirbazını kullanarak bir gösterge oluşturalım. Göstergenin kaynak kodu, biraz değiştirilmiş haliyle, aşağıdaki gibi olacaktır:
//+------------------------------------------------------------------+ //| TestButtons.mq5 | //| Copyright 2013, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2013, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property version "1.00" //--- #property indicator_separate_window // Indicator is in the subwindow #property indicator_plots 0 // No plotting series //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) { //--- //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| Timer function | //+------------------------------------------------------------------+ void OnTimer() { //--- } //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- } //+------------------------------------------------------------------+
Şu anda sıfır çizim serisine sahip boş bir penceremiz var. Bir zamanlayıcı ihtiyacı biraz sonra tartışılacaktır.
Şimdi fonksiyonları oluştururken kullanılacak sabitleri, değişkenleri ve dizileri ekleyelim. Tüm diziler iki boyutludur. İlk boyut, pencere yüksekliği boyunca düğme sayısını belirtir ve ikinci boyut, pencere genişliği boyunca düğme sayısını belirtir:
//--- #define BUTTON_COLUMNS 4 // Number of buttons across the width #define BUTTON_ROWS 3 // Number of buttons across the height //+------------------------------------------------------------------+ //| Global parameters | //+------------------------------------------------------------------+ //--- Font string font_name="Calibri"; //--- Indicator subwindow properties int subwindow_number =WRONG_VALUE; // Subwindow number int subwindow_height =0; // Subwindow height string subwindow_shortname ="TestButtons"; // Short name of the indicator string prefix =subwindow_shortname+"_"; // Prefix for object names int chart_width =0; // Chart width int chart_height =0; // Chart height int chart_y_offset =0; // Distance from the chart top to the subwindow //--- Colors of button elements color background_color =clrSteelBlue; // Button color color font_color =clrWhite; // Font color color hover_background_color =C'38,118,166'; // Button color when the cursor goes over color clicked_background_color =C'2,72,136'; // Clicked button color //--- Text displayed on buttons string button_texts[BUTTON_ROWS][BUTTON_COLUMNS]= { {"Button 01","Button 02","Button 03","Button 04"}, {"Button 05","Button 06","Button 07","Button 08"}, {"Button 09","Button 10","Button 11","Button 12"} }; //--- Object names string button_object_names[BUTTON_ROWS][BUTTON_COLUMNS]= { {"button_01","button_02","button_03","button_04"}, {"button_05","button_06","button_07","button_08"}, {"button_09","button_10","button_11","button_12"} }; //--- Button widths int button_widths[BUTTON_ROWS][BUTTON_COLUMNS]; //--- Button heights int button_heights[BUTTON_ROWS][BUTTON_COLUMNS]; //--- X-coordinates int button_x_distances[BUTTON_ROWS][BUTTON_COLUMNS]; //--- Y-coordinates int button_y_distances[BUTTON_ROWS][BUTTON_COLUMNS]; //--- Button states bool button_states[BUTTON_ROWS][BUTTON_COLUMNS]= { {true,false,false,false}, {false,false,false,false}, {false,false,false,false} }; //--- Button colors color button_colors[BUTTON_ROWS][BUTTON_COLUMNS];
Göstergeyi grafiğe eklerken, diziler, koordinatların ve boyutlarının hesaplanmasının ardından OnInit() fonksiyonu içindeki nesne özelliklerine başlatılacaktır. İmleç izlemeyi de etkinleştirmemiz gerekiyor. Son olarak, gösterge alt penceresine düğmeler eklememiz gerekiyor. Bu eylemler, kolaylık sağlamak adına, aşağıda tek tek inceleyeceğimiz ayrı fonksiyonlarda gerçekleştirilecektir. Bunun sonucunda, OnInit() fonksiyonu kodu aşağıdaki şekilde görünecektir:
//+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Set the timer at 1-second intervals EventSetTimer(1); //--- Add prefix to object names AddPrefix(); //--- Enable tracking of mouse events ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true); //--- Set the short name IndicatorSetString(INDICATOR_SHORTNAME,subwindow_shortname); //--- Set subwindow properties SetSubwindowProperties(); //--- Set button properties SetButtonColors(); // Colors SetButtonCoordinates(); // Coordinates SetButtonSizes(); // Sizes //--- Add the button panel AddButtonsPanel(); //--- Refresh the chart ChartRedraw(); //--- Everything completed successfully return(INIT_SUCCEEDED); }
AddPrefix() fonksiyonundaki ön ek, yani göstergenin kısa adı, her bir grafik nesnesinin adına eklenir. Bu, çizelgede birden fazla programın çalıştığında nesne adlarının eşleşmesi durumunda nesnelerin değiştirilmesini/silinmesini/kaydurulmasını hariç tutmak için gereklidir.
//+------------------------------------------------------------------+ //| Adding prefix to all object names | //+------------------------------------------------------------------+ void AddPrefix() { //--- Add prefix to object names for(int i=0; i<BUTTON_COLUMNS; i++) for(int j=0; j<BUTTON_ROWS; j++) button_object_names[j][i]=prefix+button_object_names[j][i]; }
Hesaplamalar için gereken grafik özellikleri SetSubwindowProperties() fonksiyonunda başlatılacaktır:
//+------------------------------------------------------------------+ //| Setting subwindow properties | //+------------------------------------------------------------------+ void SetSubwindowProperties() { //--- Indicator subwindow number subwindow_number=ChartWindowFind(0,subwindow_shortname); //--- Subwindow width and height chart_width=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS); subwindow_height=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,subwindow_number); }
Grafik özelliklerini elde etmenin ardından, düğme renklerini, koordinat değerlerini ve boyutlarını belirlemek için hesaplamalar yapabiliriz. Tüm bu eylemler aşağıda sağlanan üç ayrı fonksiyonda gerçekleştirilir:
//+------------------------------------------------------------------+ //| Setting button color | //+------------------------------------------------------------------+ void SetButtonColors() { for(int i=0; i<BUTTON_COLUMNS; i++) { for(int j=0; j<BUTTON_ROWS; j++) { //--- If the button is clicked if(button_states[j][i]) button_colors[j][i]=clicked_background_color; //--- If the button is unclicked else button_colors[j][i]=background_color; } } } //+------------------------------------------------------------------+ //| Setting X and Y coordinates for buttons | //+------------------------------------------------------------------+ void SetButtonCoordinates() { int button_width=chart_width/BUTTON_COLUMNS; int button_height=subwindow_height/BUTTON_ROWS; //--- for(int i=0; i<BUTTON_COLUMNS; i++) { for(int j=0; j<BUTTON_ROWS; j++) { if(i==0) button_x_distances[j][i]=0; else button_x_distances[j][i]=(button_width*i)-i; //--- if(j==0) button_y_distances[j][i]=0; else button_y_distances[j][i]=(button_height*j)-j; } } } //+------------------------------------------------------------------+ //| Setting button width and height | //+------------------------------------------------------------------+ void SetButtonSizes() { int button_width=chart_width/BUTTON_COLUMNS; int button_height=subwindow_height/BUTTON_ROWS; //--- for(int i=0; i<BUTTON_COLUMNS; i++) { for(int j=0; j<BUTTON_ROWS; j++) { if(i==BUTTON_COLUMNS-1) button_widths[j][i]=chart_width-(button_width*(BUTTON_COLUMNS-1)-i); else button_widths[j][i]=button_width; //--- if(j==BUTTON_ROWS-1) button_heights[j][i]=subwindow_height-(button_height*(BUTTON_ROWS-1)-j)-1; else button_heights[j][i]=button_height; } } }
Son olarak, AddButtonsPanel() fonksiyonu, düğmeleri gösterge alt penceresine ekler:
//+------------------------------------------------------------------+ //| Adding buttons to the indicator subwindow | //+------------------------------------------------------------------+ void AddButtonsPanel() { //--- Create buttons for(int i=0; i<BUTTON_COLUMNS; i++) { for(int j=0; j<BUTTON_ROWS; j++) { CreateButton(0,subwindow_number,button_object_names[j][i],button_texts[j][i], CORNER_LEFT_UPPER,font_name,8,font_color,button_colors[j][i],clrNONE, button_widths[j][i],button_heights[j][i], button_x_distances[j][i],button_y_distances[j][i],2,true,button_texts[j][i]); } } }
CreateButton() yardımcı fonksiyonunun kaynak kodu aşağıdaki gibidir:
//+------------------------------------------------------------------+ //| Creating a button (graphical object of the Edit type) | //+------------------------------------------------------------------+ void CreateButton(long chart_id, // chart id int sub_window, // (sub)window number string object_name, // object name string text, // displayed text long corner, // chart corner string font, // font int font_size, // font size color c_font, // font color color c_background, // background color color c_border, // border color int x_size, // width int y_size, // height int x_dist, // X-coordinate int y_dist, // Y-coordinate long zorder, // Z-order bool read_only, // Read Only flag string tooltip) // tooltip { //--- If the object has been created successfully, set the remaining properties if(ObjectCreate(chart_id,object_name,OBJ_EDIT,subwindow_number,0,0)) { ObjectSetString(chart_id,object_name,OBJPROP_TEXT,text); // name ObjectSetInteger(chart_id,object_name,OBJPROP_CORNER,corner); // chart corner ObjectSetString(chart_id,object_name,OBJPROP_FONT,font); // font ObjectSetInteger(chart_id,object_name,OBJPROP_FONTSIZE,font_size); // font size ObjectSetInteger(chart_id,object_name,OBJPROP_COLOR,c_font); // font color ObjectSetInteger(chart_id,object_name,OBJPROP_BGCOLOR,c_background); // background color ObjectSetInteger(chart_id,object_name,OBJPROP_BORDER_COLOR,c_border); // border color ObjectSetInteger(chart_id,object_name,OBJPROP_XSIZE,x_size); // width ObjectSetInteger(chart_id,object_name,OBJPROP_YSIZE,y_size); // height ObjectSetInteger(chart_id,object_name,OBJPROP_XDISTANCE,x_dist); // X-coordinate ObjectSetInteger(chart_id,object_name,OBJPROP_YDISTANCE,y_dist); // Y-coordinate ObjectSetInteger(chart_id,object_name,OBJPROP_SELECTABLE,false); // object is not available for selection ObjectSetInteger(chart_id,object_name,OBJPROP_ZORDER,zorder); // Z-order ObjectSetInteger(chart_id,object_name,OBJPROP_READONLY,read_only); // Read Only text ObjectSetInteger(chart_id,object_name,OBJPROP_ALIGN,ALIGN_CENTER); // align center ObjectSetString(chart_id,object_name,OBJPROP_TOOLTIP,tooltip); // no tooltip if "\n" } }
CreateButton() fonksiyonunun son parametresine dikkat edin: bu, fare imleci bir grafik nesnesinin üzerinden geçtiğinde araç ipucundan sorumludur. Örneğin, bu parametre AddButtonsPanel() fonksiyonunda button_texts dizisinden (düğmeler üzerinde görüntülenen metin) aktarılan değerler ile temsil edilir. İsterseniz daha detaylı açıklamalara sahip ayrı bir dizi oluşturabilirsiniz.
Şimdi, göstergeyi grafiğe eklerseniz, sonuç aşağıdaki gibi olacaktır:
Şekil 1. Gösterge alt penceresine eklenen düğmeler
Şu anda, bunlar yalnızca gösterge alt penceresinde düzenlenmiş nesnelerdir. Kullanıcı ile etkileşim henüz uygulanmamıştır. Şimdi bu nesnelere "hayat verelim".
İlk olarak, alt pencere yeniden boyutlandırıldığında, düğme boyutlarını bunun boyutuna göre ayarlama imkanını uygulayacağız. Bunun için iki fonksiyon daha yazacağız: UpdateButtonCoordinates() ve ResizeButtons(). Bunlar, düğme koordinatlarını ve boyutlarını ayarlayacaktır:
//+------------------------------------------------------------------+ //| Updating button coordinates | //+------------------------------------------------------------------+ void UpdateButtonCoordinates() { //--- Set coordinates for(int i=0; i<BUTTON_COLUMNS; i++) { for(int j=0; j<BUTTON_ROWS; j++) { ObjectSetInteger(0,button_object_names[j][i],OBJPROP_XDISTANCE,button_x_distances[j][i]); ObjectSetInteger(0,button_object_names[j][i],OBJPROP_YDISTANCE,button_y_distances[j][i]); } } } //+------------------------------------------------------------------+ //| Updating button sizes | //+------------------------------------------------------------------+ void ResizeButtons() { //--- Set sizes for(int i=0; i<BUTTON_COLUMNS; i++) { for(int j=0; j<BUTTON_ROWS; j++) { ObjectSetInteger(0,button_object_names[j][i],OBJPROP_XSIZE,button_widths[j][i]); ObjectSetInteger(0,button_object_names[j][i],OBJPROP_YSIZE,button_heights[j][i]); } } }
Grafik özelliklerinin değiştirilmesi ve grafiğin yeniden boyutlandırılması olayını ele almak için, CHARTEVENT_CHART_CHANGE tanımlayıcısını kullanmamız gerekiyor.. Aşağıda, OnChartEvent() fonksiyonu gövdesine eklemeniz gereken kodu göreceksiniz:
//+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, // event identifier const long &lparam, // parameter of the event of type long const double &dparam, // parameter of the event of type double const string &sparam) // parameter of the event of type string { //--- Tracking the event of modifying the chart properties and resizing the chart if(id==CHARTEVENT_CHART_CHANGE) { //--- Set subwindow properties SetSubwindowProperties(); //--- Set button coordinates SetButtonCoordinates(); //--- Set button sizes SetButtonSizes(); //--- Set new button coordinates UpdateButtonCoordinates(); //--- Set new button sizes ResizeButtons(); //--- Refresh the chart ChartRedraw(); return; } }
Göstergeyi grafiğe şimdi eklersek (veya gösterge halihazırda grafik üzerindeyse kodu yeniden derlersek), grafik penceresi veya gösterge alt penceresi yeniden boyutlandırılır boyutlandırılmaz, düğmeler otomatik olarak yeniden boyutlandırılacak ve yeniden konumlandırılacaktır.
Ayrıca, imleç bir düğmenin üzerine geldiğinde düğme renginin değişimini uyguluyoruz. Fakat fonksiyon kodunu yazmadan önce, CHARTEVENT_MOUSE_MOVE tanımlayıcısı ile olayın ele alınma sürecine bir göz atalım.
OnInit() fonksiyonu içinde, halihazırda, programa fare imleci hareketini ve sol fare düğmesinin durumunu izlemesi talimatı veren bir dizemiz var:
//--- Enable tracking of mouse events ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
Bu dize olmadan (veya aktarılan son parametre değeri false ise), CHARTEVENT_MOUSE_MOVE tanımlayıcı ile olaylar, OnChartEvent() fonksiyonu içinde izlenmeyecektir. Bu tür olayları her programda izlemeye gerek olmayabileceğinden, bu oldukça faydalı gibi görünüyor.
Fare olayı izlemenin nasıl çalıştığını anlamak için, OnChartEvent() fonksiyon koduna, geçici olarak ilgili yorumu grafikte görüntüleme imkanını ekleyebiliriz:
//--- Mouse movement and left-click tracking if(id==CHARTEVENT_MOUSE_MOVE) { Comment("id: ",CHARTEVENT_MOUSE_MOVE,"\n", "lparam (x): ",lparam,"\n", "dparam (y): ",dparam,"\n", "sparam (state of the mouse buttons): ",sparam );
Şimdi fare imlecini grafikte hareket ettirmeye başlarsanız, sol üst köşedeki imlecin mevcut koordinatlarını görebileceksiniz. Sol tıklandığında, değişiklikler yorum satırı sparam (fare düğmelerinin durumu) içinde görüntülenecektir, burada bir (1) fare düğmesine tıklandığı anlamına gelir ve sıfır (0) düğmenin bırakıldığı anlamına gelir.
Fare imlecinin mevcut olarak bulunduğu alt pencereyi bilmek isterseniz, ChartXYToTimePrice() fonksiyonunu kullanabilirsiniz. Koordinatları alır ve pencere/alt pencere sayısını, zamanı ve fiyatı (referans olarak kendisine aktarılan değişkenlere) döndürür. Bunu, aşağıdaki kodu test ederek çalışma halinde görebilirsiniz:
//--- Mouse movement and left-click tracking if(id==CHARTEVENT_MOUSE_MOVE) { int x =(int)lparam; // X-coordinate int y =(int)dparam; // Y-coordinate int window =WRONG_VALUE; // Number of the window where the cursor is located datetime time =NULL; // Time corresponding to the X-coordinate double price =0.0; // Price corresponding to the Y-coordinate //--- Get the position of the cursor if(ChartXYToTimePrice(0,x,y,window,time,price)) { Comment("id: ",CHARTEVENT_MOUSE_MOVE,"\n", "x: ",x,"\n", "y: ",y,"\n", "sparam (state of the mouse buttons): ",sparam,"\n", "window: ",window,"\n", "time: ",time,"\n", "price: ",DoubleToString(price,_Digits) ); } //--- return; }
Gösterge alt penceresindeki hesaplamalar, göreceli koordinatların kullanılması durumunda daha kolaydır. Bu durumda, Y koordinatı (fiyat ölçeği) ile ilgilidir. Göreceli değeri elde etmek için, yalnızca grafiğin tepesinden gösterge alt penceresine olan mesafeyi mevcut değerden çıkarmanız gerekiyor. Bu işlem şu şekilde yapılabilir:
//--- Get the position of the cursor if(ChartXYToTimePrice(0,x,y,window,time,price)) { //--- Get the distance from the chart top to the indicator subwindow chart_y_offset=(int)ChartGetInteger(0,CHART_WINDOW_YDISTANCE,subwindow_number); //--- Convert the Y-coordinate to the relative value y-=chart_y_offset; Comment("id: ",CHARTEVENT_MOUSE_MOVE,"\n", "x: ",x,"\n", "y: ",y,"\n", "sparam (state of the mouse buttons): ",sparam,"\n", "window: ",window,"\n", "time: ",time,"\n", "price: ",DoubleToString(price,_Digits) ); }
Şimdi, y değişkenindeki değer, fare imleci gösterge alt penceresinin üzerindeyse negatif ve imleç alt pencere alanının üzerine geldiğinde pozitif olacaktır.
Varsayılan olarak, grafiği imlecin grafik üzerindeki konumundan bağımsız olarak zaman ölçeği boyunca kaydırma imkanı vardır. Ancak, gerekirse ve gerektiğinde grafik kaydırma devre dışı bırakılabilir. Bu çoğunlukla, imleç panelin veya özel kontrollerin üzerinde bulunduğunda gerekli olacaktır. İmleç gösterge alt penceresindeyken grafik kaydırmayı devre dışı bırakma ve imleç alt pencereden dışarı hareket ettirildiğinde bunu etkinleştirme kodu, örneğin, aşağıdaki gibi olabilir:
//--- If the cursor is in the subwindow area, disable chart scrolling if(window==subwindow_number) ChartSetInteger(0,CHART_MOUSE_SCROLL,false); //--- Enable chart scrolling if the cursor moves out of the indicator subwindow area else ChartSetInteger(0,CHART_MOUSE_SCROLL,true);
Ayrıca, imleç ilgili düğme üzerine geldiğinde düğme rengini değiştiren bir fonksiyon yazalım: ChangeButtonColorOnHover():
//+------------------------------------------------------------------+ //| Changing the button color when the cursor hovers over the button | //+------------------------------------------------------------------+ void ChangeButtonColorOnHover(int x,int y) { int x1,y1,x2,y2; //--- Initialize the array of XY coordinates for buttons SetButtonCoordinates(); //--- Determine if the cursor is over any of the buttons for(int i=0; i<BUTTON_COLUMNS; i++) { for(int j=0; j<BUTTON_ROWS; j++) { //--- If this button is clicked, go to the next one if(button_states[j][i]) continue; //--- Get the button boundaries x1=button_x_distances[j][i]; y1=button_y_distances[j][i]; x2=button_x_distances[j][i]+button_widths[j][i]; y2=button_y_distances[j][i]+button_heights[j][i]; //--- If the cursor is within the button area, set the new button color if(x>x1 && x<x2 && y>y1 && y<y2) ObjectSetInteger(0,button_object_names[j][i],OBJPROP_BGCOLOR,hover_background_color); //--- Otherwise set the standard color else ObjectSetInteger(0,button_object_names[j][i],OBJPROP_BGCOLOR,background_color); } } }
Bunun sonucunda, CHARTEVENT_MOUSE_MOVE tanımlayıcı dalında aşağıdaki kaynak kodumuz olur:
//--- Mouse movement and left-click tracking if(id==CHARTEVENT_MOUSE_MOVE) { int x =(int)lparam; // X-coordinate int y =(int)dparam; // Y-coordinate int window =WRONG_VALUE; // Number of the window where the cursor is located datetime time =NULL; // Time corresponding to the X-coordinate double price =0.0; // Price corresponding to the Y-coordinate //--- Get the position of the cursor if(ChartXYToTimePrice(0,x,y,window,time,price)) { //--- Get the distance from the chart top to the indicator subwindow chart_y_offset=(int)ChartGetInteger(0,CHART_WINDOW_YDISTANCE,subwindow_number); //--- Convert the Y-coordinate to the relative value y-=chart_y_offset; //--- If the cursor is in the subwindow area, disable chart scrolling if(window==subwindow_number) ChartSetInteger(0,CHART_MOUSE_SCROLL,false); //--- Enable chart scrolling if the cursor moves out of the indicator subwindow area else ChartSetInteger(0,CHART_MOUSE_SCROLL,true); //--- Change the button color when the cursor is hovered over ChangeButtonColorOnHover(x,y); } //--- Refresh the chart ChartRedraw(); return; }
Şimdi, imleci düğmelerin üzerinde hareket ettirirseniz, düğme renginin değiştiğini/normale döndüğünü görebileceksiniz.
Şu anda yalnızca Düğme 01, tıklanan düğme rengindedir. Diğer düğmelere tıklamaya çalışırsanız, yanıt ve dolayısıyla renk değişikliği olmayacaktır. Bu durumda renk değişikliğini uygulamak için, CHARTEVENT_OBJECT_CLICK tanımlayıcısına sahip bir olayı kullanmamız gerekir.
İki fonksiyon yazalım: InitializeButtonStates() ve ChangeButtonColorOnClick(). InitializeButtonStates() fonksiyonu, adındaki ön ek dikkate alındığında, belirli bir düğmeye tıklanıp tıklanmadığını kontrol eder. Tıklama olayı tanımlanmışsa, bu durumda düğme durumları (button_states) dizisi bir döngüde başlatılır ve fonksiyon true değerini döndürür.
//+------------------------------------------------------------------+ //| Initializing button states in case of click | //+------------------------------------------------------------------+ bool InitializeButtonStates(string clicked_object) { //--- Get the indicator subwindow number subwindow_number=ChartWindowFind(0,subwindow_shortname); //--- If a button in the indicator subwindow has been clicked if(ObjectFind(0,clicked_object)==subwindow_number && StringFind(clicked_object,prefix+"button_",0)>=0) { //--- Determine the clicked button for(int i=0; i<BUTTON_COLUMNS; i++) { for(int j=0; j<BUTTON_ROWS; j++) { //--- Determine the state of all buttons if(clicked_object==button_object_names[j][i]) button_states[j][i]=true; else button_states[j][i]=false; } } //--- return(true); } //--- return(false); }
Bunun ardından, ChangeButtonColorOnClick() fonksiyonu, düğme renklerini button_states dizisinin değerlerine göre ayarlar.
//+------------------------------------------------------------------+ //| Changing the button color in case of click | //+------------------------------------------------------------------+ void ChangeButtonColorOnClick() { for(int i=0; i<BUTTON_COLUMNS; i++) { for(int j=0; j<BUTTON_ROWS; j++) { //--- If the button has been clicked, it is set a distinctive color if(button_states[j][i]) ObjectSetInteger(0,button_object_names[j][i],OBJPROP_BGCOLOR,clicked_background_color); //--- Set the standard color to the unclicked button else ObjectSetInteger(0,button_object_names[j][i],OBJPROP_BGCOLOR,background_color); } } }
Bunların hepsinin çalışması için, düğme tıklamalarının işlenmesini OnChartEvent() olay izleme fonksiyonuna eklediğinizden emin olmalısınız:
//--- Tracking left mouse button clicks on a graphical object if(id==CHARTEVENT_OBJECT_CLICK) { //--- If the button has been clicked if(InitializeButtonStates(sparam)) { //--- Set button colors ChangeButtonColorOnClick(); } //--- Refresh the chart ChartRedraw(); return; }
Şimdi tıklandığında, düğmenin rengini değişecektir.
Hala dikkat etmemiz gereken birkaç nokta var. OnDeinit() fonksiyonu içinde, alt pencere alanında grafik kaymasını etkinleştirmemiz ve göstergeyi grafikten silerken fare olaylarının izlenmesini devre dışı bırakmamız gerekir. Bu, olay izlemeyi kullanan birkaç program grafik üzerinde aynı anda çalışıyorsa önemli olabilir.
//+------------------------------------------------------------------+ //| Deinitialization | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if(reason==REASON_REMOVE || // If the indicator has been deleted from the chart or reason==REASON_RECOMPILE) // the program has been recompiled { //--- Deactivate the timer EventKillTimer(); //--- Delete the objects DeleteButtons(); //--- Enable chart scrolling ChartSetInteger(0,CHART_MOUSE_SCROLL,true); //--- Disable tracking of mouse events ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,false); //--- Refresh the chart ChartRedraw(); } }
Programın grafik nesnelerini silme fonksiyonları:
//+------------------------------------------------------------------+ //| Deleting all buttons | //+------------------------------------------------------------------+ void DeleteButtons() { for(int i=0; i<BUTTON_COLUMNS; i++) for(int j=0; j<BUTTON_ROWS; j++) DeleteObjectByName(button_object_names[j][i]); } //+------------------------------------------------------------------+ //| Deleting the object by name | //+------------------------------------------------------------------+ void DeleteObjectByName(string object_name) { //--- If such object exists if(ObjectFind(0,object_name)>=0) { //--- If an error occurred when deleting, print the relevant message if(!ObjectDelete(0,object_name)) Print("Error ("+IntegerToString(GetLastError())+") when deleting the object!"); } }
Ve son olarak, bu programda bir zamanlayıcıya ihtiyacımız olmasının nedeni şudur. Örneğin, grafik üzerinde birkaç program çalışıyorsa ve programların her birinin fare olaylarını izlemesi gerekiyorsa, bunlardan biri grafikten silindiğinde, izleme tüm programlar için OnDeinit() fonksiyonunda devre dışı bırakılacaktır. Bu yüzden, alternatif olarak, fare olaylarının izlenmesinin etkinleştirilip etkinleştirilmediğini görmek için her saniye kontrol gerçekleştirebilirsiniz:
//+------------------------------------------------------------------+ //| Timer function | //+------------------------------------------------------------------+ void OnTimer() { //--- Check whether tracking of mouse events is enabled CheckChartEventMouseMove(); }
CheckChartEventMouseMove() fonksiyon kodu aşağıda verilmiştir.
Bazen, bu kontrolü CHARTEVENT_CHART_CHANGE tanımlayıcı ile bir olay için yapmak gayet yeterli olabilir.
Aşağıda, elde ettiğimiz sonucu gösteren videoyu görebilirsiniz:
Sonuç
Konu genel itibarıyla bu şekilde. TestButtons.mq5 göstergesi makaleye eklenmiştir ve buradan indirilebilir. Daha fazla geliştirme ile bu örnek ilginç bir ana menüye dönüşebilir. Örneğin, kullanıcı belirli bir düğmeye tıklayarak ilgili bilgi parçasına atlayabilir. Düğme sayısı, gerekirse, artırılabilir.
MetaQuotes Ltd tarafından Rusçadan çevrilmiştir.
Orijinal makale: https://www.mql5.com/ru/articles/750
- Ü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