English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
Özel Grafik Kontrolleri. Kısım 3. Formlar

Özel Grafik Kontrolleri. Kısım 3. Formlar

MetaTrader 5Örnekler | 9 Aralık 2021, 12:40
56 0
Dmitry Fedoseev
Dmitry Fedoseev

 

Giriş

İlk makale "Basit Kontrol Oluşturma", grafik kontrol oluşturma ilkelerini ele almış ve basit bir kontrolün oluşturulmasını gösteren adım adım bir örnek sağlamıştır. Sonraki makale "Kontrol Kitaplığı", bir dizi hazır kontrol ortaya koymuştur. Çok önemli bir grafik arayüz bileşeni daha vardır - form.

Form, kontrollerin görüntülendiği ekranın özel olarak belirlenmiş dikdörtgen bir kısmını temsil eder. Ayrıca form, içerdiği tüm kontrolleri aynı anda yönetmeyi sağlayan bir taşıyıcıdır: tümünü bir arada gizlemek, görüntülemek ve taşımak için.

Son makale, formların oluşturulmasını ve bunların kontrollerle birlikte kullanımını açıklayacaktır.

Önceki makalelerde kullanılan IncGUI.mqh dosyasına formlarla çalışma sınıfları eklendi (yeni dosya adı IncGUI_v3.mqh). Formlarla çalışma sınıflarına ek olarak dosyaya bazı sınıflar daha eklendi, CHMenu (Yatay Menü) ve CVMenu (Dikey Menü) sınıfları güncellendi ve birkaç hata düzeltildi.

Eklenen sınıflar:

  • CFrame Sınıfı - Çerçeve. Sınıf, CWorkPiece sınıfının Frame yöntemiyle oluşturulan çerçeveyle aynıdır.
  • CButton Sınıfı - Düğme. Normal bir düğme (OBJ_BUTTON).
  • CLabel Class - Etiket. "Etiket" (OBJ_LABEL) grafik nesnesi ile yapıldığı gibi etiketi görüntülemenin yanı sıra, bu sınıf, bir metnin satırların "\n" sembolü ile ayrıldığı birkaç satırda görüntülenmesini sağlar.

Yeni sınıfların eklenmesi sonucunda CColorSchemes sınıfı şu şekilde değiştirildi: yeni kontroller için renkler eklendi.

CHMenu ve CVMenu sınıflarındaki değişiklikler: Uygulanan değişiklikler, açılır sekmelerle iki seviyeli menüler oluşturmayı sağlar. Bu, aşağıdaki "Ana Menünün Oluşturulması" bölümünde daha ayrıntılı olarak ele alınacaktır.

Hatalar: CWorkPiece sınıfının Frame() yönteminde bir düzeltme - bir dikdörtgen etiket için bir alt pencere numarası ayarlanamadı. CListMS Sınıfı - Selected() ve SetSelected() yöntemleri - dizi boyutu şimdi kontrol edildi, aksi takdirde boş bir liste kullanmak imkansızdı.

 

1. Formlar

Form, birkaç düğme OBJ_BUTTON kullanımı ile "Dikdörtgen Etiket" OBJ_RECTANGLE_LABEL grafik nesnelerine dayanmaktadır. Görsel olarak form, form adının ve kontrol düğmelerinin görüntülendiği formun üst kısmında bir çubuk bulunan bir dikdörtgeni (Şekil 1) temsil eder.

Solda formu hareket ettiren (el görselli) bir düğme, sağda küçültme düğmesi (dikdörtgen görselli) ve kapat düğmesi (çarpı görselli) yer alır.

Şekil 1. Form

Şekil 1. Form

Formu taşımak için, taşı düğmesine basın (düğme basılan konuma gelir) ve grafikte formun taşınması gereken herhangi bir yeri tıklayın. Sonuç olarak, taşı düğmesi serbest bırakılacak ve form belirtilen yere taşınacaktır (sol üst köşesi tıklanan noktada olacaktır).

Belirtilen yerin grafiğin kenarında olduğunda ve formun grafik sınırının dışına yerleştirilmesi gerektiğinde, form konumu, grafikte tamamen görünecek şekilde ayarlanacaktır.

Birkaç tür form oluşturmak mümkündür:

  • Tür 0 (Şekil 1);
  • Tür 1 - ek "İptal" ve "Uygula" düğmeleriyle (Şekil 2);
  • Tür 2 - ek "Kapat" düğmesi ile (Şekil 3);

Şekil 2. Tür 1 Formu ("İptal" ve "Uygula" düğmeleriyle)

Şekil 2. Şekil 2. Tür 1 Formu ("İptal" ve "Uygula" düğmeleriyle)

Şekil 3. Tür 2 Formu ("Kapat" düğmesiyle)

Şekil 3. Şekil 3. Tür 2 Formu ("Kapat" düğmesiyle)

Formlarla çalışmak için programatik araçlar iki sınıfla temsil edilir: CFormBase ve CFormTemplate.

CFormBase sınıfı bir temel sınıftır, CFormTemplate ise CFormBase sınıfının bir alt sınıfıdır. Gerçekte ve prensipte (uygulama ilkesi dahil), CFormBase sınıfı, daha önce açıklanan diğer kontrollerle tamamen aynı kontroldür.

CFormBase sınıfı, kontrol hazırlığı için Init() yöntemine, bir formun görüntülenmesi için SetPos() ve Show() yöntemlerine (bir formu temsil eden grafik nesnelerin oluşturulması), gizlemek için Hide() yöntemine, ekranı yenilemek için Refresh() yöntemine, etkinlik işlemek için Event() yöntemine ve diğer tüm kontrollerde olan diğer yöntemlere sahiptir.

Bir formun uygulanması ve kontrollerin kullanımı, Init() yönteminin çağrılmasıyla başlar, ardından SetPos() yöntemi kullanılarak bir konum belirlenir ve Show() yöntemiyle görüntüleme etkinleştirilir veya aksi takdirde görüntüleme, parametrelerle yalnızca Show() yöntemi kullanılarak etkinleştirilebilir ve bir form Hide() yöntemi kullanılarak gizlenebilir.

Form kontrolü kapasitesini (taşıma, küçültme, kapatma vb.) sağlanması için OnChartEvent() fonksiyonuna bir Event() yöntem çağrısı eklenir. Formun bir alt pencerede çalışmasını sağlamak gerektiğinde, CHARTEVENT_CHART_CHANGE etkinliği sırasında OnChartEvent() fonksiyonunun yanı sıra Init() yöntemi çağrıldıktan hemen sonra çağrılan SetSubWindow() yöntemi kullanılır. Her şey diğer kontrollerdekiyle aynıdır.

Standart kontroller bağımsız olsa da (diğer kontrollerle ilişkilendirilmeleri gerekmez), form, formda yer alan kontrollerin gizlenmesi/görüntülenmesini formun gizlenmesi/görüntülenmesi ile eş zamanlı olarak sağlamak için form diğer kontrollerle zorunlu bir ilişkilendirmenin varlığını ima eder. Böylece formun Init(), Show() ve Hide() yöntemlerinin ve ilgili kontrollerin senkronize çalışması sağlanmalıdır.

Formla ilgili tüm kontrollerin Show() yöntemleri (örneğin formun Show() yöntemini çağırırken) kesinlikle çağrılabilir, ancak programda birkaç form kullanıldığında bu tür bir yaklaşım yapılandırılmamış ve anlamak, hata ayıklamak ve güncellemek için elverişsiz bir kodla sonuçlanır.

Her form için form sınıfının bir kopyası alınabilir ve içine kontrollerle birlikte çalışma kodu eklenebilir; ancak bu yine yapılandırılmamış kodla (burada formun kodu kontrol işlemiyle ilgili koddan ayrılmaz), yalnızca formun tasarımından ve fonksiyonundan sorumlu kod bölümünün kopyalanacağı yerde kodun aşırı kopyalanmasıyla sonuçlanacaktır; tüm bunlar, her sınıf kopyasında değişiklik yapılmasını gerektireceğinden, herhangi bir form fonksiyonunda değişikliklerin uygulanmasını zorlaştıracaktır.

Temel sınıfa ve alt sınıfa bölünme, çeşitli formlar oluşturma, formun ve ilgili kontrollerin görüntülenmesinin senkronizasyonu ve farklı formlarla ilgili kodun açık şekilde ayrılması sorununu çözmeye yardımcı olur. Temel sorunları çözmenin yanı sıra, sınıf ve alt sınıfın kullanımı, halihazırda tamamlanmış işlerde herhangi bir değişiklik yapmak zorunda kalmadan temel sınıfın gelecekte yükseltilmesini sağlayacaktır.

Kontrollerin ve formun Init(), Show() ve Hide() yöntemlerinin çağrısını senkronize etmek için, CFormBase sınıfının standart kontrol sınıfından bazı farklılıkları vardır: korumalı bir bölümde birkaç sanal yöntem:

virtual void MainProperties() {}
virtual void OnInitEvent() {}
virtual void OnShowEvent() {}
virtual void OnHideEvent() {}
virtual void EventsHandler(const int id, const long& lparam, const double& dparam, const string& sparam){}
virtual void OnWindowChangeEvent(int aSubWindow) {}
virtual bool OnCancelEvent() {return(true);}
virtual bool OnApplyEvent()  {return(true);} 

Bu yöntemler sanaldır; bu, CFormTemplate alt sınıfının karşılık gelen gerçek yöntemlerine yeniden yönlendirmenin bunlar aracılığıyla gerçekleştirildiği anlamına gelir.

CFormTemplate alt sınıfı tek başına kullanılmaz, bu bir şablondur. Yeni bir form oluşturmak için, benzersiz bir adla CFormTemplate sınıfının bir kopyasını oluşturun (sadece CFormTemplate sınıfının kodunu kopyalayın, yeniden adlandırın ve her form için aynısını tekrarlayın). Alt sınıfların kopyalanması, farklı formlarla ilgili kodun ayrılmasını sağlar.

Sanal yöntemler korumalı bölümde bulunur ve bu nedenle yöntemler farklı form etkinliklerinde temel sınıftan zaten çağrıldığından gerekli bile olmayan bir çağrı için erişilemez olacaktır - yalnızca bu etkinliklere karşılık gelen kontrollerin çalışması için bir kod eklemelisiniz.

Aşağıdaki grafik, Uzman Danışman (EA) fonksiyonları ile standart kontrol sınıfı yöntemleri arasındaki etkileşimi gösterir. (Şekil 4) ve bir karşılaştırma olarak form sınıfı yöntemlerle etkileşim (Şekil 5).

Şekil 4. Uzman Danışman (EA) fonksiyonları ve kontrol yöntemleri arasındaki etkileşim
Şekil 4. Uzman Danışman (EA) fonksiyonları ve kontrol yöntemleri arasındaki etkileşim

Şekil 5. Uzman Danışman (EA) fonksiyonları ile form sınıfı yöntemleri arasındaki etkileşim
Şekil 5. Uzman Danışman (EA) fonksiyonları ile form sınıfı yöntemleri arasındaki etkileşim

Her yöntemin amacını ayrıntılı olarak gözden geçirelim:

  • MainProperties() ve OnInitEvent() yöntemleri, formun Init() yönteminden çağrılır. MainProperties() yöntemi, formun görünümünü (form türü, taşıma, küçültme ve kapatma düğmelerinin varlığı) ayarlar. OnInitEvent() yöntemi, tüm kontrollerin Init() yöntemlerini çağırır ve kontrollere varsayılan değerleri ayarlar.

  • OnShowEvent() yöntemi, Show() yönteminden çağrılır; tüm kontrollerin Show() yöntemlerinin çağrı kodu buna eklenir.

  • OnHideEvent() yöntemi, Hide() yönteminden çağrılır; tüm kontrollerin Hide() yöntemlerinin çağrı kodu buna eklenir.

  • EventsHandler() yöntemi, Uzman Danışmanın (EA) OnChartEvent() fonksiyonuna eşdeğerdir. Formun Event() yöntemi, Uzman Danışmanın (EA) OnChartEvent() fonksiyonundan çağrılır ve tüm grafik etkinlikleri basitçe bu yönteme yönlendirilir. Tüm kontrollerin Event() yöntemlerinin çağrı kodu ve ilgili etkinliği işleme, EventsHandler() öğesine eklenir.

  • OnWindowChangeEvent() yöntemi, bir alt pencere değiştirilirken SetSubWindow() yönteminden çağrılır. Tüm kontrollerin SetSubWindow() yöntemlerinin çağrı kodu buna eklenir. Yöntem, tüm kontrollerde ayarlanacak yeni bir alt pencere numarasını ileten bir parametreye sahiptir.

  • OnCancelEvent() yöntemi, form kapatıldıktan sonra yürütülür (çarpı görselli düğme, "İptal" veya "Kapat" düğmeleri tıklandığında). Örneğin, formun gerçekten kapatılması gerektiğinden emin olmak için bir onay penceresinin çağrılması gibi, formun kapanışında bazı kontrol kodları eklenebilir. Yöntem doğru çıkarsa, formu kapatan kod tamamlanacak ve form kapanacaktır; yöntem yanlış çıkarsa, formu kapatan kodun çalışması kesintiye uğrayacak ve form açık kalacaktır.

  • Formun "Uygula" düğmesine tıklandığında OnApplyEvent() yöntemi yürütülür. Burada (OnCancelEvent() yönteminde olduğu gibi) bazı kontroller yapılabilir ve yöntemin doğru mu yoksa yanlış mı çıktığına bakılabilir, böylece formun kapanmasına izin verilir veya verilmez. Bu yöntem ayrıca, Uzman Danışmanın (EA) bir sonraki başlatılışında kontrol değerlerinin program kapatılmadan öncekiyle aynı olması için kontrol değerlerini kaydetmek için bir kod içerebilir. Ve bu amaçla, kaydedilen değerler OnInitEvent() yönteminde yüklenmeli ve kontrollere ayarlanmalıdır.

 

2. Yeni Bir Form Oluşturmak için Adım Adım Prosedür

Dolayısıyla, yeni bir form oluşturmak için adım adım prosedür aşağıdaki gibidir:

1. IncGUI_v3.mqh dosyasını dahil edin.

#include <IncGUI_v3.mqh>
2. CFormTemplate sınıfının kodunu IncGUI_v3.mqh dosyasından Uzman Danışmanınızın (EA) bir dosyasına kopyalayın (alt sınıf dosyanın sonundadır) ve yeniden adlandırın (kitaplık örneğinde alt sınıf CForm olarak adlandırılır). 

 

class CFormTemplate: public CFormBase{
   public:
   protected      void MainProperties()
     {
        m_Name        = "Form";       // Form name. The names of all the controls of this form should start with it.
        m_Width       = 200;           // Form width
        m_Height      = 150;           // Form height
        m_Type        = 1;             // Form type: 0 - without buttons, 1 - with "Apply" and "Cancel" buttons, 2 - with the "Close" button
        m_Caption     = "FormCaption"; // Form caption
        m_Movable     = true;          // Movable form (the button with a hand image is displayed in the top left corner)
        m_Resizable   =  true;         // Form minimizing/maximizing allowed (the button with a rectangle image 
                                           // is displayed in the top right corner)
        m_CloseButton = true;          // Form closing allowed (the button with a cross image is displayed in the top right corner)
     }
      void OnInitEvent() {} 
      void OnShowEvent(int aLeft, int aTop) {}
      void OnHideEvent() {}
      void OnWindowChangeEvent(int aSubWindow) {}
      void EventsHandler(const int id,const long& lparam,const double& dparam,const string& sparam){}
      bool OnApplyEvent()  {return(true);}
      bool OnCancelEvent() {return(true);}
};

Form kodu için ayrı bir içerme dosyası oluşturulabilir, bu içerme dosyasına dahil edilebilir, CFormTemplate alt sınıfının kodu buna kopyalanabilir ve form işlemiyle ilgili kalan kodlama bu dosyada yapılabilir.

Bir görsel düzenleyicinin kullanımıyla bir benzetme yaparsak, bu adım, projede çeşitli form etkinliklerinin fonksiyonlarına sahip yeni bir form dosyasının görüneceği yeni bir form oluşturmak için düğmeye tıklamaya oldukça benzer olacaktır.

3. Formun ana özelliklerini ayarlayın. Bu adım, temel sınıfta bildirilen değişkenlere değerler atanarak MainProperties() yönteminde yürütülür. Tüm değişkenlerin amaçlarına ilişkin ayrıntılı yorumlar şablonda verilmiştir. Bu adımın bir görsel düzenleyicide form özellikleri penceresinin kullanımıyla benzerliğini fark edebilirsiniz (örneğin Excel'de VBA).

void MainProperties()
{
   m_Name         =  "Form";        // Form name. The names of all the controls of this form should start with this one.
   m_Width        =  200;           // Form width
   m_Height       =  150;           // Form height
   m_Type         =  1;             // Form type: 0 - without buttons, 1 - with "Apply" and "Cancel" buttons, 2 - with the "Close" button
   m_Caption      =  "FormCaption";   // Form caption
   m_Movable      =  true;          // Movable form (the button with a hand image is displayed in the top left corner)
   m_Resizable    =  true;          // Form minimizing/maximizing allowed (the button with a rectangle image 
                                    // is displayed in the top right corner)
   m_CloseButton = true;            // Form closing allowed (the button with a cross image is displayed in the top right corner)
}

Formun diğer kontrollerden başka bir farkı görülebilir - form adı, Init() yöntem parametresi olarak iletilmek yerine MainProperties() yönteminde ayarlanır.

Form üzerindeki ana çalışma bir alt sınıfta yapılır; formun her alt sınıfı yalnızca bir kez belirtilir, bu nedenle formun bir alt sınıfının Init() yöntemini çağırırken farklı adlar belirtmeye gerek yoktur.

Init() yöntemine iletilebilecek tek parametre State parametresidir, ancak bu bile zorunlu değildir. State parametresinin değeri, görüntülendiğinde formun başlangıç durumunu belirler: büyütülmüş veya küçültülmüş. Değer 1 ise form büyütülür (Şekil 1, 2, 3), değer 2 ise form küçültülür (Şekil 6).

Şekil 6. Küçültülmüş form

Şekil 6. Küçültülmüş form

4. Bir sınıf belirtin.

CForm frm;

5. Kontrolü kullanmak için standart adımlar atın: Uzman Danışmanın (EA) OnInit() fonksiyonundan formun Init() yöntemini çağırın, OnDeinit() fonksiyonundan Deinit() yöntemini çağırın, OnChartEvent() fonksiyonundan Event() yöntemini çağırın ve gerektiğinde CHARTEVENT_CHART_CHANGE etkinliğinde SetSubWindows() yöntemini çağırın.

Form daha sonra grafikte görünür olmalı ve taşı, küçült, kapat düğmelerine vb. tıklamaya yanıt vermelidir.

Daha sonra kontrolleri forma eklemeye devam ediyoruz.

 

3. Kontrolleri Forma Eklemek İçin Adım Adım Prosedür

  1. Kontrollerin belirtilmesi. Form dışında kontrol yöntemlerine erişim sağlamanız gerekiyorsa, kontrol sınıfları herkese açık bölümde bildirilmelidir; tüm işler form sınıfı içinde yapılabiliyorsa, kontrol sınıfları korumalı bölümde bildirilmelidir.

  2. Kontrol değerlerini geri yüklemek için değişkenlerin belirtilmesi. İsteğe bağlı bir adım. Formu "İptal" ve "Uygula" düğmeleri ile kullanacaksanız, bir kullanıcı kontrol değerini değiştirirse, fakat “İptal” düğmesine basarsa değeri geri yüklemek için form açıldığında kontrolün sahip olduğu değeri depolamak için her kontrole bir değişken eklenmelidir.

  3. Tüm kontrollerin Int() yöntemlerini çağırma. Bu, OnInitEvent() yönteminde yürütülür.

  4. Kaydedilen verileri yükleme. İsteğe bağlı bir adım. Bu, OnInitEvent() yönteminde yürütülür. Bu adım, Uzman Danışman (EA), Terminal veya bilgisayar yeniden başlatıldıktan sonra kontrollerin değerlerini koruması gerektiğinde kullanılır. Veri kaydetme, 12. adımda gerçekleştirilir.

  5. Varsayılan değerlerin ayarlanması. Bu adımda tüm kontroller Uzman Danışman (EA) başlatıldıktan sonra (kullanıcı tarafından değerleri değiştirilene kadar) formun ilk açılışında kontrollerde görülecek değerlere ayarlanır. Veriler 4. adımda yüklendiyse, yüklenen veriler kullanılır. Kontrollerin daha fazla hazırlanması da bu adımda gerçekleştirilir, örneğin liste ve menü öğeleri de buraya eklenir.

  6. Tüm kontroller için Show() yöntemlerinin (parametreli sürüm) çağrılması OnShowEvent() yönteminde yürütülür. OnShowEvent() yöntemi, formun çalışma alanının sol üst köşesinin koordinatlarını ileten iki parametreye (int aLeft, int aTop) sahiptir. Kontrol konumları bu değişkenlerin değerlerine göre ayarlanır (değerler eklenmelidir).

  7. OnHideEvent() yönteminde, formun tüm denetimleri için Hide() yönteminin bir çağrısı yürütülür.

  8. SetSubWindow() yöntemini çağırma. İsteğe bağlı bir adım. Formu bir alt pencerede görüntülemek gerekirse, tüm kontroller için SetSubWindow() yöntemi çağrılır. Bu, yeni bir alt pencere numarası taşıyan bir parametreye (int aSubWindow) sahip OnWindowChangeEvent() yönteminde yürütülür.

  9. Tüm kontrollerin Event() yöntemlerini çağırma. Bu, EventsHandler() yönteminde yürütülür.

  10. Kontrol etkinliklerini işleme. İsteğe bağlı bir adım. Etkinlikler sırasında kontroller arasında etkileşimin sağlanması gerekiyorsa, etkinliklerin işlenmesi ve uygun eylemlerin yürütülmesi bu adımda gerçekleşir. Bu, EventsHandler() yönteminde yürütülür.

  11. Yeni değerler uygulama. "Uygula" düğmesi kullanılarak yürütülen isteğe bağlı bir adım. Bu, OnApplyEvent() yönteminde yürütülür. Bu adımda, kontrol değerlerinin doğruluğu kontrol edilir; herhangi bir yanlış değer bulunursa, kullanıcı bilgilendirilmelidir, yöntem yanlış verecek ve form açık kalacaktır. Değerler doğruysa, formun kapanması için doğru verilecektir.

  12. Verileri kaydetme. İsteğe bağlı bir adım. Bu, "Uygula" düğmesi kullanılarak OnApplyEvent() yönteminde yürütülür. Veriler (hedeflere ve amaçlara bağlı olarak) bir dosyaya, global değişkenlere, grafikteki görünmez nesnelere vb. kaydedilebilir.

  13. OnCancelEvent() yöntemini kontrol edin. İsteğe bağlı bir adım. OnCancelEvent() yönteminden yanlış verilirse, form açık kalır, yani kapat düğmesi yanıt vermez. Formun kapanması için yöntemden doğru verilmelidir.

Formlarla çalışma örneği, ekteki eIncGUI_v3_Test_Form.mq5 dosyasında bulunabilir. Farklı kontrollere sahip ana form başlangıçta açılır (Şekil 7).

Formun kapat düğmesi olmadığını unutmayın; bu ana formdur ve grafikten kaybolmamalıdır, aksi takdirde formun yeniden görünmesi için Uzman Danışmanın (EA) yeniden başlatılması gerekecektir.

Şekil 7. Açık bir ana menü sekmesi ile eIncGUI_v3_Test_Form.mq5 örneğinden ana form

Şekil 7. Açık bir ana menü sekmesi ile eIncGUI_v3_Test_Form.mq5 örneğinden ana form

Ana menü komutlarını kullanarak formun diğer iki varyantını açabilirsiniz.

Ana menü - Form türleri - Tür 1, tür 1 formunu açar ("İptal" ve "Uygula" düğmeleriyle).
Ana menü - Form türleri - Tür 2, tür 2 formunu açar ("Kapat" düğmesiyle).

Her iki form da kapatıldıktan sonra onay gerektirir (MessageBox() fonksiyonu kullanılarak yapılır). Tür 1 formunun bir giriş kutusu vardır; bir giriş değeri "Uygula" düğmesine tıklanarak kontrol edilir. Tür 2 formda yeni bir kontrol "Etiket" (CLabel sınıfı) ve bunu test etmek için birkaç düğme (CButton sınıfı) bulunur.

Şimdi girişte bahsedildiği gibi ana menüyü oluşturarak CHMenu ve CVMenu sınıflarındaki değişiklikleri örneklendiği gibi inceleyelim.

 

Öncelikle, sadece iki seviyeli menüler oluşturulabileceğini söylemek isterim: yatay bir çubuk (CHMenu sınıfını temel alarak) ve sekmeler (CVMenu sınıfını temel alarak). Prensip olarak, daha fazla seviye oluşturmak mümkündür, ancak süreç çok karmaşık ve zahmetli olacaktır, bu yüzden tavsiye edilmez ve daha fazla üzerinde durulmayacaktır.

Aslında, form için ana menünün oluşturulması planlanmamıştı bile ve CHMenu ve CVMenu sınıflarının, çeşitli fonksiyonları ve araçları etkinleştirmek/devre dışı bırakmak için ayrı ve birbirinden bağımsız olarak kullanılması gerekiyordu. Bununla birlikte, CHMenu ve CVMenu sınıflarında yapılan hafif bir iyileştirme, çoğu durumda yeterince uygun olan ana menüyü elde etmeyi mümkün kılmıştır.

Tam teşekküllü çok seviyeli bir menü oluşturmak için, tamamen ayrı bir makale konusu olabilecek biraz farklı bir yaklaşım (ağaç benzeri bir veri yapısının oluşturulması) uygulanmalıdır, bu yüzden şimdi kendimizi mevcut araçlarla sınırlayacağız.

Önce CHMenu ve CVMenu sınıflarına uygulanan tüm değişiklik ve düzeltmeleri inceleyelim.

CVMenu sınıfında, tik sembolünü görüntülemek için kullanılan "Etiket" grafik nesnesine tıklamaya verilen yanıt düzeltilmiştir. Dolayısıyla, LastClickedX(), LastClickedY() ve LastClickedQuarter() yöntemlerinin çalışmasında değişiklikler olmuştur. Etiketlere tıklandığında, metin kutularında olduğu gibi değerler verilir. CHMenu sınıfına ve LastClickedX(), LastClickedY(), LastClickedQuarter() ve LastClickedW() yöntemlerine benzer düzeltmeler uygulanmıştır.

Her iki sınıf da menü komutunda görüntülenen bir grafik nesnenin koordinatlarını hesaplamaya yönelik SolvePosX() ve SolvePosY() yöntemleri eklenerek güncellenmiştir. Görüntülenen nesnenin genişliği SolvePosX() yöntemine iletilir ve görüntülenen nesnenin yüksekliği, görüntülenen nesnenin sırasıyla X veya Y koordinatını veren SolvePosY() yöntemine iletilir. Artık LastClickedX(), LastClickedY(), LastClickedQuarter() ve LastClickedW() yöntemlerini kullanmaya gerek yoktur.

Her iki sınıf da LastClickedName1() ve LastClickedName2() yöntemleri eklenerek güncellenmiştir. Bu yöntemler, son tıklanan menü öğesini oluşturan grafik nesnelerin adlarını verir. LastClickedName1() metin kutusunun adını verir, LastClickedName2() tik sembolü için etiketin adını verir.

CVMenu'ya ToggleNameAdd() ve ToggleNamesClear() yöntemleri eklenmiştir. ToggleNameAdd() yöntemi, "değiştirme" adlarının bir listesini oluşturmak için kullanılır, bu listeyi temizlemek için ToggleNamesClear() yöntemi kullanılır. ToggleNameAdd() yöntemini kullanırken (listeye bir ad eklerken), menüyü oluşturan grafik nesnelerinin etkinlikleri ve adları ToggleNameAdd() yöntemiyle eklenen grafik nesnelerin etkinlikleri dışında, menü herhangi bir grafik etkinliğinde otomatik olarak kapanır. . Liste ToggleNamesClear() yöntemiyle temizlendiğinde menü normal çalışma moduna döner.

İki seviyeli menünün çalışması şu şekildedir: Yatay menü öğesine tıklama etkinliği LastClickedName1() ve LastClickedName2() yöntemleriyle tanımlandığında, bu öğenin daha sonra dikey menünün ToggleNameAdd() yöntemine iletilen nesnelerinin adlarını alırız.

Bunun ardından, dikey menü ve bir yatay menü öğesi (dikey menünün açılmasını sağlayan) etkinlikleri dışında, dikey menü herhangi bir grafikte gizlenecektir.

Bir kullanıcı dikey menüden bir öğe seçtiyse, dikey menü kapatılmalı ve bu öğeye karşılık gelen işlemler gerçekleştirilmelidir. Bir kullanıcı aynı yatay menü öğesine (dikey menünün açılmasını sağlayan) art arda tıkladıysa, dikey menü gizlenmelidir.

Bir t/phe menü oluşturma örneğini inceleyelim.

Ana menüde üç öğe var, bu nedenle üç dikey menüye ihtiyacımız vardır. Form alt sınıfının herkese açık bölümünde bir yatay menü sınıfı ve üç dikey menü sınıfı belirtin (aşağıdaki örnek, bunu eIncGUI_v3_Test_Form.mq5 örneğindekiyle tamamen aynı şekilde gösterir):

class CForm: public CFormBase{
public:
   CHMenu m_hm;
   CVMenu m_vm1;
   CVMenu m_vm2;
   CVMenu m_vm3; 

OnInitEvent() yönteminde menü sınıflarını başlatın ve menü öğelerini ekleyin:

// Horizontal menu
m_hm.Init(m_Name+"_HM",m_Width,2);
// Adding horizontal menu items
m_hm.AddItem("Form types");
m_hm.AddItem("Item-2");
m_hm.AddItem("Item-3");
// Vertical menu 1
m_vm1.Init(m_Name+"_VM1",70,10); 
// Adding items to vertical menu 1
m_vm1.AddItem("Type-1");
m_vm1.AddItem("Type-2");
// Vertical menu 2
m_vm2.Init(m_Name+"_VM2",70,3);
// Adding items to vertical menu 2
m_vm2.AddItem("Item-2-1");
m_vm2.AddItem("Item-2-2");
m_vm2.AddItem("Item-2-3"); 
m_vm2.AddItem("Item-2-4");
m_vm2.AddItem("Item-2-5"); 
// Vertical menu 3
m_vm3.Init(m_Name+"_VM3",70,3);
// Adding items to vertical menu 3
m_vm3.AddItem("Item-3-1");
m_vm3.AddItem("Item-3-2");
m_vm3.AddItem("Item-3-3"); 
m_vm3.AddItem("Item-3-4");
m_vm3.AddItem("Item-3-5"); 

Menüyü OnHideEvent() yönteminde gizleyin:

void OnHideEvent()
{
   m_hm.Hide(); 
   m_vm1.Hide(); 
   m_vm2.Hide(); 
   m_vm3.Hide(); 
}

OnShowEvent() yönteminde yatay menüyü görüntüleyin:

void OnShowEvent(int aLeft,int aTop)
{
    m_hm.Show(aLeft,aTop); 
}

Son olarak, EventsHandler() yöntemindeki ana çalışma.

Tüm menülerin Event() yöntemlerini çağırın:

void EventsHandler(const int id,const long& lparam,const double& dparam,const string& sparam)
{
    int m_event0=m_hm.Event(id,lparam,dparam,sparam);
    int m_event1=m_vm1.Event(id,lparam,dparam,sparam);
    int m_event2=m_vm2.Event(id,lparam,dparam,sparam);
    int m_event3=m_vm3.Event(id,lparam,dparam,sparam); 

m_event0 değerine (yatay menü öğesi dizini) bağlı olarak, uygun dikey menü ile çalışın (ör. öğe 0 ve dikey menü 1 ile):

if(m_event0==0)
{ // Clicking item 0
   if(m_vm1.Visible())
   { 
      m_vm1.Hide(); // If the vertical menu is open, close it
   }
   else{ // If the vertical menu is closed
      m_vm1.ToggleNamesClear(); // Clear the list of "toggle" names
      // Add to the list the names of the graphical objects forming the item 
      // of the horizontal menu which led to the last event 
      // of the horizontal menu 
      m_vm1.ToggleNameAdd(m_hm.LastClickedName1()); 
      m_vm1.ToggleNameAdd(m_hm.LastClickedName2());
      // Display the vertical menu
      m_vm1.Show(m_hm.SolvePosLeft(m_vm1.Width()),m_hm.SolvePosTop(m_vm1.Height())); 
   }
}

Bu tür eylemler, dikey menüyü açan tüm yatay menü öğeleri için gerçekleştirilmelidir. Dikey menü etkinliği meydana geldiyse menüyü kapatın.

Tıklanan öğenin dizinine bağlı olarak aşağıdakileri yapın:

if(m_event1>=0)
{ // Vertical menu event 1
   m_vm1.Hide(); // Hide the menu
      if(m_event1==0)
      { // Clicking item 0
        //...
      }
      if(m_event1==1)
      { // Clicking item 1
        //...
      }
}

Bu tür eylemler, tüm dikey menüler ve bunların tüm öğeleri için gerçekleştirilmelidir.

Ana menünün oluşturulması artık tamamlanmıştır.

 

Sonuç

Bu makale, bir grafik arayüz oluşturmaya ayrılmış makale dizisini sonlandırmaktadır.

Çalışmamızın bir sonucu olarak, çok işlevli ve kullanımı kolay bir grafik arayüzün hızlı bir şekilde oluşturulması için oldukça önemli bir cephaneliğe sahibiz. Bu, bir grafik arayüzün mevcut gereksinimleriyle oldukça tutarlıdır:

  • Çerçeveyi bir başlık şeklinde ve küçültülebilen/büyütülebilen, taşınabilen bir formda kullanma;
  • Bir form veya diğeriyle ilgili açıkça belirlenmiş kod alanları;
  • Kontrollerin görüntülenmesi/gizlenmesi, formun görüntülenmesi/gizlenmesi ile senkronize edilir.

Tüm kontroller ve form, hızla değiştirilebilen ortak bir tasarıma ve renk şemasına sahiptir.

Form oluşturma prosedürünü tekrarlayalım.

Form oluşturmak için kısa bir prosedür:

  1. IncGUI_v3.mqh dosyasını dahil edin.

  2. Benzersiz bir adla CFormTemplate sınıfının bir kopyasını oluşturun ve bu sınıfı belirtin.

  3. Alt sınıf kopyasının MainProperties() yönteminde form özelliklerini ayarlayın.

  4. Uzman Danışmanın (EA) OnInit(), OnDeinit() ve OnChartEvent() fonksiyonlarından Init(), Hide() ve Event() yöntemlerini sırasıyla çağırın. Uzman Danışmanın (EA) OnInit() fonksiyonundan veya gerektiğinde Show() yöntemini çağırın.

  5. Kontrollerle çalışın. Alt sınıf kopyasındaki kontrol sınıflarını belirtin. Alt sınıf kopyasının OnInitEvent(), OnShowEvent(), OnHideEvent() ve EventHandler() yöntemlerinden kontrollerin Init(), Show(), Hide() ve Event() yöntemlerini çağırın.

 

Ek

Eklenen Dosyaların Listesi:

  • IncGUI_v3.mqh - bir grafik arayüz oluşturmak için tüm sınıfları içeren bir içerme dosyası. Dosya, Terminal Veri Dizininin MQL5/Include dizinine yerleştirilmelidir.
  • eIncGUI_v3_Test_Form.mq5 - formlarla çalışmaya bir örnek. Dosya, Terminal Veri Dizininin MQL5/Experts dizinine yerleştirilmelidir.
  • IncGUIv3mqh.chm - IncGUI_v3.mqh dosyasına ilişkin belgeler.

MetaQuotes Ltd tarafından Rusçadan çevrilmiştir.
Orijinal makale: https://www.mql5.com/ru/articles/322

Ekli dosyalar |
MQL5 Cloud Network ile Hesaplamaları Hızlandırın MQL5 Cloud Network ile Hesaplamaları Hızlandırın
Ana bilgisayarınızda kaç çekirdek var? Bir alım satım stratejisini optimize etmek için kaç bilgisayar kullanabilirsiniz? Burada, bir fare tıklamasıyla dünya çapında bilgi işlem gücünü alarak hesaplamaları hızlandırmak için MQL5 Cloud Network’ün nasıl kullanılacağını gösteriyoruz. "Vakit nakittir" ifadesi her geçen yıl daha da güncel hale geliyor ve önemli hesaplamalar için onlarca saat hatta günlerce beklemeyi göze alamayız.
Özel Grafik Kontrolleri. Kısım 2. Kontrol Kitaplığı Özel Grafik Kontrolleri. Kısım 2. Kontrol Kitaplığı
"Özel Grafik Kontrolleri" serisinin ikinci makalesi, bir program (Uzman Danışman (EA), komut dosyası, gösterge) ve bir kullanıcı arasındaki etkileşimde ortaya çıkan temel sorunları ele almak için bir kontrol kitaplığını tanıtmaktadır. Kitaplık çok sayıda sınıfı (CInputBox, CSpinInputBox, CCheckBox, CRadioGroup, CVSсrollBar, CHSсrollBar, CList, CListMS, CComBox, CHMenu, CVMenu, CHProgress, CDialer, CDialerInputBox, CTable) ve bunların kullanım örneklerini içerir.
MQL5'te Kendi Grafik Panellerinizi Oluşturun MQL5'te Kendi Grafik Panellerinizi Oluşturun
MQL5 programının kullanılabilirliği hem zengin fonksiyonu hem de ayrıntılı bir grafik kullanıcı arayüzü ile belirlenir. Görsel algı bazen hızlı ve istikrarlı çalışmadan daha önemlidir. Standart Kitaplık sınıfları temelinde kendi başınıza ekran panelleri oluşturmanız için adım adım bir kılavuzu aşağıda bulabilirsiniz.
Özel Grafik Kontrolleri. Kısım 1: Basit Kontrol Oluşturma Özel Grafik Kontrolleri. Kısım 1: Basit Kontrol Oluşturma
Bu makalede grafik kontrollerinin geliştirilmesine ilişkin genel ilkeler ele alınacaktır. Grafik nesnelerle hızlı ve kullanışlı bir çalışma için araçlar hazırlayacağız, metin veya nümerik verilerin girilmesi için basit bir kontrol oluşturma örneğini ve bunu kullanma yollarını analiz edeceğiz.