| //+------------------------------------------------------------------+
|
| //| WndContainer.mqh |
|
| //| Copyright 2000-2025, MetaQuotes Ltd. |
|
| //| https://www.mql5.com |
|
| //+------------------------------------------------------------------+
|
| #include "Wnd.mqh"
|
| #include <Arrays\ArrayObj.mqh>
|
| //+------------------------------------------------------------------+
|
| //| Class CWndContainer |
|
| //| Usage: base class of the combined control |
|
| //+------------------------------------------------------------------+
|
| class CWndContainer : public CWnd
|
| {
|
| private:
|
| CArrayObj m_controls; // container of the control
|
|
|
| public:
|
| CWndContainer(void);
|
| ~CWndContainer(void);
|
| //--- release memory
|
| virtual void Destroy(const int reason=0);
|
| //--- chart event handler
|
| virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
| virtual bool OnMouseEvent(const int x,const int y,const int flags);
|
| //--- access the contents of container
|
| int ControlsTotal(void) const { return(m_controls.Total()); }
|
| CWnd* Control(const int ind) const { return(dynamic_cast<CWnd *>(m_controls.At(ind))); }
|
| virtual CWnd* ControlFind(const long id);
|
| //--- for mouse cursor focus
|
| virtual bool MouseFocusKill(const long id=-1);
|
| //--- fill
|
| bool Add(CWnd *control);
|
| bool Add(CWnd &control);
|
| //--- underflowing
|
| bool Delete(CWnd *control);
|
| bool Delete(CWnd &control);
|
| //--- geometry
|
| virtual bool Move(const int x,const int y);
|
| virtual bool Move(const CPoint &point);
|
| virtual bool Shift(const int dx,const int dy);
|
| //--- ID
|
| virtual long Id(const long id);
|
| long Id(void) const { return(CWnd::Id()); }
|
| //--- state
|
| virtual bool Enable(void);
|
| virtual bool Disable(void);
|
| virtual bool Show(void);
|
| virtual bool Hide(void);
|
| //--- methods for working with files
|
| virtual bool Save(const int file_handle);
|
| virtual bool Load(const int file_handle);
|
|
|
| protected:
|
| //--- internal event handlers
|
| virtual bool OnResize(void);
|
| virtual bool OnActivate(void);
|
| virtual bool OnDeactivate(void);
|
| };
|
| //+------------------------------------------------------------------+
|
| //| Common handler of chart events |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
|
| {
|
| //--- if an object is being dragged, pass control to the special drag object
|
| if(m_drag_object!=NULL && m_drag_object.OnEvent(id,lparam,dparam,sparam))
|
| return(true);
|
| //--- loop by elements of group
|
| int total=m_controls.Total();
|
| for(int i=total-1;i>=0;i--)
|
| {
|
| CWnd *control=Control(i);
|
| //--- check of pointer
|
| if(control==NULL)
|
| continue;
|
| if(control.OnEvent(id,lparam,dparam,sparam))
|
| return(true);
|
| }
|
| //--- not handled
|
| return(false);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Common handler of mouse events |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::OnMouseEvent(const int x,const int y,const int flags)
|
| {
|
| if(!IS_VISIBLE)
|
| return(false);
|
| //--- if an object is being dragged, pass control to the special drag object
|
| if(m_drag_object!=NULL && m_drag_object.OnMouseEvent(x,y,flags))
|
| return(true);
|
| //--- loop by elements of group
|
| int total=m_controls.Total();
|
| for(int i=total-1;i>=0;i--)
|
| {
|
| CWnd *control=Control(i);
|
| //--- check of pointer
|
| if(control==NULL)
|
| continue;
|
| if(control.OnMouseEvent(x,y,flags))
|
| return(true);
|
| }
|
| //--- call of the method of the parent class
|
| return(CWnd::OnMouseEvent(x,y,flags));
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Constructor |
|
| //+------------------------------------------------------------------+
|
| CWndContainer::CWndContainer(void)
|
| {
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Destructor |
|
| //+------------------------------------------------------------------+
|
| CWndContainer::~CWndContainer(void)
|
| {
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Delete group of controls |
|
| //+------------------------------------------------------------------+
|
| void CWndContainer::Destroy(const int reason)
|
| {
|
| //--- loop by elements of group
|
| int total=m_controls.Total();
|
| for(int i=0;i<total;i++)
|
| {
|
| CWnd *control=Control(0);
|
| //--- check of pointer
|
| if(control==NULL)
|
| continue;
|
| control.Destroy();
|
| m_controls.Delete(0);
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Find control by specified ID |
|
| //+------------------------------------------------------------------+
|
| CWnd* CWndContainer::ControlFind(const long id)
|
| {
|
| CWnd *result=CWnd::ControlFind(id);
|
| //---
|
| if(result!=NULL)
|
| return(result);
|
| //--- loop by elements of group
|
| int total=m_controls.Total();
|
| for(int i=0;i<total;i++)
|
| {
|
| CWnd *control=Control(i);
|
| //--- check of pointer
|
| if(control==NULL)
|
| continue;
|
| result=control.ControlFind(id);
|
| if(result!=NULL)
|
| break;
|
| }
|
| //--- return the result
|
| return(result);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Remove the mouse focus from control |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::MouseFocusKill(const long id=-1)
|
| {
|
| if(!IS_ACTIVE)
|
| return(false);
|
| Deactivate();
|
| //--- loop by elements of group
|
| int total=m_controls.Total();
|
| for(int i=0;i<total;i++)
|
| {
|
| CWnd *control=Control(i);
|
| //--- check of pointer
|
| if(control==NULL)
|
| continue;
|
| control.MouseFocusKill();
|
| }
|
| //--- succeed
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Add control to the group (by pointer) |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::Add(CWnd *control)
|
| {
|
| //--- check of pointer
|
| if(control==NULL)
|
| return(false);
|
| //--- correct the coordinates of added control
|
| control.Shift(Left(),Top());
|
| //--- "projecting" the group flag "visibility" to the added element
|
| if(IS_VISIBLE && control.IsVisible())
|
| {
|
| //--- element will be "visible" only if the group is "visible" and the element is completely "within" this group
|
| control.Visible(Contains(control));
|
| }
|
| else
|
| control.Hide();
|
| //--- "projecting" the group flag "enabled" to the added element
|
| if(IS_ENABLED)
|
| control.Enable();
|
| else
|
| control.Disable();
|
| //--- adding
|
| return(m_controls.Add(control));
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Add control to the group (by reference) |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::Add(CWnd &control)
|
| {
|
| //--- add by pointer
|
| return(Add((CWnd*)GetPointer(control)));
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Delete control from the group (by pointer) |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::Delete(CWnd *control)
|
| {
|
| //--- check of pointer
|
| if(control==NULL)
|
| return(false);
|
| //--- loop by elements of group
|
| int total=m_controls.Total();
|
| for(int i=0;i<total;i++)
|
| {
|
| CWnd *pointer=Control(i);
|
| //--- check of pointer
|
| if(pointer==NULL)
|
| continue;
|
| //--- delete item from group
|
| if(pointer==control)
|
| return(m_controls.Delete(i));
|
| }
|
| //--- failure
|
| return(false);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Delete control from the group (by reference) |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::Delete(CWnd &control)
|
| {
|
| //--- delete by pointer
|
| return(Delete((CWnd*)GetPointer(control)));
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Absolute movement of the controls group |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::Move(const int x,const int y)
|
| {
|
| //--- relative movement
|
| return(Shift(x-Left(),y-Top()));
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Absolute movement of the controls group |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::Move(const CPoint &point)
|
| {
|
| //--- relative movement
|
| return(Shift(point.x-Left(),point.y-Top()));
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Relative movement of the controls group |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::Shift(const int dx,const int dy)
|
| {
|
| //--- call of the method of the parent class
|
| if(!CWnd::Shift(dx,dy)) return(false);
|
| //--- loop by elements of group
|
| int total=m_controls.Total();
|
| for(int i=0;i<total;i++)
|
| {
|
| CWnd *control=Control(i);
|
| //--- check of pointer
|
| if(control==NULL)
|
| continue;
|
| //--- move the group item
|
| control.Shift(dx,dy);
|
| }
|
| //--- succeed
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Set ID of control |
|
| //+------------------------------------------------------------------+
|
| long CWndContainer::Id(const long id)
|
| {
|
| //--- reserve ID for container
|
| long id_used=1;
|
| //--- loop by elements of group
|
| int total=m_controls.Total();
|
| for(int i=0;i<total;i++)
|
| {
|
| CWnd *control=Control(i);
|
| //--- check of pointer
|
| if(control==NULL)
|
| continue;
|
| id_used+=control.Id(id+id_used);
|
| }
|
| m_id=id;
|
| //--- return number of used IDs
|
| return(id_used);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Enables event handling by the group of controls |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::Enable(void)
|
| {
|
| //--- loop by elements of group
|
| int total=m_controls.Total();
|
| for(int i=0;i<total;i++)
|
| {
|
| CWnd *control=Control(i);
|
| //--- check of pointer
|
| if(control==NULL)
|
| continue;
|
| control.Enable();
|
| }
|
| //--- call of the method of the parent class
|
| return(CWnd::Enable());
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Disables event handling by the group of controls |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::Disable(void)
|
| {
|
| //--- loop by elements of group
|
| int total=m_controls.Total();
|
| for(int i=0;i<total;i++)
|
| {
|
| CWnd *control=Control(i);
|
| //--- check of pointer
|
| if(control==NULL)
|
| continue;
|
| control.Disable();
|
| }
|
| //--- call of the method of the parent class
|
| return(CWnd::Disable());
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Makes the group of controls visible |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::Show(void)
|
| {
|
| //--- loop by elements of group
|
| int total=m_controls.Total();
|
| for(int i=0;i<total;i++)
|
| {
|
| CWnd *control=Control(i);
|
| //--- check of pointer
|
| if(control==NULL)
|
| continue;
|
| control.Show();
|
| }
|
| //--- call of the method of the parent class
|
| return(CWnd::Show());
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Makes the group of controls hidden |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::Hide(void)
|
| {
|
| //--- loop by elements of group
|
| int total=m_controls.Total();
|
| for(int i=0;i<total;i++)
|
| {
|
| CWnd *control=Control(i);
|
| //--- check of pointer
|
| if(control==NULL)
|
| continue;
|
| control.Hide();
|
| }
|
| //--- call of the method of the parent class
|
| return(CWnd::Hide());
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Handler of resizing |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::OnResize()
|
| {
|
| //--- loop by elements of group
|
| int total=m_controls.Total();
|
| for(int i=0;i<total;i++)
|
| {
|
| CWnd *control=Control(i);
|
| //--- check of pointer
|
| if(control==NULL)
|
| continue;
|
| if(!control.Align(Rect()))
|
| return(false);
|
| }
|
| //--- handled
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Handler of activating the group of controls |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::OnActivate(void)
|
| {
|
| if(IS_ACTIVE)
|
| return(false);
|
| Activate();
|
| //--- loop by elements of group
|
| int total=m_controls.Total();
|
| for(int i=0;i<total;i++)
|
| {
|
| CWnd *control=Control(i);
|
| //--- check of pointer
|
| if(control==NULL)
|
| continue;
|
| control.Activate();
|
| }
|
| //--- handled
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Handler of deactivating the group of controls |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::OnDeactivate(void)
|
| {
|
| if(!IS_ACTIVE)
|
| return(false);
|
| Deactivate();
|
| //--- loop by elements of group
|
| int total=m_controls.Total();
|
| for(int i=0;i<total;i++)
|
| {
|
| CWnd *control=Control(i);
|
| //--- check of pointer
|
| if(control==NULL)
|
| continue;
|
| control.Deactivate();
|
| }
|
| //--- handled
|
| return(true);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Save |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::Save(const int file_handle)
|
| {
|
| bool result=true;
|
| //--- loop by elements of group
|
| int total=m_controls.Total();
|
| for(int i=0;i<total;i++)
|
| {
|
| CWnd *control=Control(i);
|
| //--- check of pointer
|
| if(control==NULL)
|
| continue;
|
| result&=control.Save(file_handle);
|
| }
|
| //--- result
|
| return(result);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Load |
|
| //+------------------------------------------------------------------+
|
| bool CWndContainer::Load(const int file_handle)
|
| {
|
| bool result=true;
|
| //--- loop by elements of group
|
| int total=m_controls.Total();
|
| for(int i=0;i<total;i++)
|
| {
|
| CWnd *control=Control(i);
|
| //--- check of pointer
|
| if(control==NULL)
|
| continue;
|
| result&=control.Load(file_handle);
|
| }
|
| //--- result
|
| return(result);
|
| }
|
| //+------------------------------------------------------------------+
|