Criar uma biblioteca gráfica a partir do zero - página 14

 
Tente fazer uma janela completa. Como um formulário Windows. Você pode fazê-lo sem dinamismo, mas como você o implementou parcialmente, acho que terá uma janela de "borracha" semelhante à de uma janela Windows.
 
Реter Konow:
Tente fazer uma janela completa. Como um formulário Windows. Você pode fazer isso sem dinamismo, mas como você o implementou parcialmente, acho que você terá uma janela de "borracha" semelhante à de uma Janela.
A parte mais difícil será desenhar os botões :))
 
Aliaksandr Hryshyn:
A parte mais difícil será desenhar os botões :))

Sim, imaginei que essa fosse a parte mais difícil, porque não há nenhuma. ))))

 

Os pergaminhos foram feitos separadamente, eles podem ser aplicados a uma configuração de janela específica, o resto (eventos, mudanças nas propriedades requeridas) será feito automaticamente. Conectá-los é muito simples:

   _scroll_v.Create(_main,_grid_cols,true,30);
   _scroll_h.Create(_main,_grid_cols,false,30);

Em relaçãoà dificuldade de criar uma mesa: o motor funcionou muito bem, portanto, criar uma mesa usando-a não é tão difícil assim.

//+------------------------------------------------------------------+
//|                                                       V_grid.mqh |
//|                                               Aliaksandr Hryshyn |
//|                          https://www.mql5.com/ru/users/greshnik1 |
//+------------------------------------------------------------------+
#property copyright "Aliaksandr Hryshyn"
#property link      "https://www.mql5.com/ru/users/greshnik1"

#include  <Greshnik\\\Windows_engine\\Windows_engine_base.mqh>
#include <Greshnik\\\Windows_engine\\V_objects\\V_scrollbar.mqh>

enum eG_property
  {
   gp_=0,
  };
//Таблица
class V_grid
  {
   int               _cols;//Количество столбцов
   int               _rows;//Количество строк
   int               _cell_width;//Ширина клетки
   int               _cell_height;//Высота клетки
   int               _scroll_width;//Ширина полосы прокрутки
   int               _size_caption;//Размер заголовков
   int               _size_fixing_col;//Размер фиксированного столбца
   bool              _is_captions;//Наличие заголовков
   bool              _is_cols_fixing;//Наличие первого фиксированного столбца
   bool              _is_scroll_bar_v;//Наличие вертикальной полосы прокрутки
   bool              _is_scroll_bar_h;//Наличие горизонтальной полосы прокрутки

   cV_object_base    *_main;//Основное окно
   cV_object_base    *_grid_view;//Окно отображения сетки
   V_scrollbar       _scroll_v;//Вертикалдьная прокрутка
   V_scrollbar       _scroll_h;//Горизонтальная прокрутка
   cV_object_base    *_caption_v;//Окно отображения заголовков
   cV_object_base    *_caption;//Окно с заголовками
   cV_object_base    *_col_fixing_v;//Окно отображения фиксированного столбца
   cV_object_base    *_col_fixing;//Фиксированный столбец
   cV_object_base    *_grid_cols;//Столбцы.Отсюда брать массивы столбцов

   //События, которые влияют на вертикальную прокрутку
   class Events_scroll_v_change: public iE_event_handler
     {
   public:
      V_grid         *_v_grid;
      void           On_event(sEvent &event);
     };
   Events_scroll_v_change scroll_v_change;

   //События, которые влияют на горизонтальную прокрутку
   class Events_scroll_h_change: public iE_event_handler
     {
   public:
      V_grid         *_v_grid;
      void           On_event(sEvent &event);
     };
   Events_scroll_h_change scroll_h_change;

   //События перемещения сетки
   class Events_grid: public iE_event_handler
     {
   public:
      V_grid         *_v_grid;
      void           On_event(sEvent &event);
     };
   Events_grid       events_grid;
public:
   //Создание таблицы
   bool              Create(
      cV_object_base &parent_object,
      string name=NULL
   );
   //Возвращает указатель на основной объект
   cV_object_base*   Get_main_v_object();

   //Изменение основных свойств таблицы
   void              Set_property(
      eG_property grid_property,
      long property_value
   );
   //Получение значения свойства
   long              Get_property(
      eG_property grid_property
   );//При ошибке возвращает LONG_MAX

   //Поучение объекта ячейки таблицы
   cV_object_base*   Get_cell_object(
      int pos_x,//Индекс столбца
      int pos_y//Индекс строки
   );//Возвращает объект ячейки или NULL при ошибке

   //Получение объекта столбца таблицы
   cV_object_base*   Get_col_object(
      int pos_x//Индекс столбца
   );//Возвращает объект ячейки или NULL при ошибке
  };

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
cV_object_base* V_grid::Get_col_object(int pos_x)
  {
   if((pos_x>=_grid_cols.Get_property(vop_s_childs_count).data_long)||(pos_x<0))
     {
      cLng_add_user(cV_object_base::lng_id,21,string(pos_x),"");
      return NULL;
     }
   return _grid_cols.Get_child(pos_x);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
cV_object_base* V_grid::Get_cell_object(int pos_x,int pos_y)
  {
   if((pos_x>=_grid_cols.Get_property(vop_s_childs_count).data_long)||(pos_x<0))
     {
      cLng_add_user(cV_object_base::lng_id,21,string(pos_x),"");
      return NULL;
     }
   cV_object_base *obj=_grid_cols.Get_child(pos_x);
   if((pos_y>=obj.Get_property(vop_s_childs_count).data_long)||(pos_y<0))
     {
      cLng_add_user(cV_object_base::lng_id,21,string(pos_x),"");
      return NULL;
     }
   return obj.Get_child(pos_y);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
long V_grid::Get_property(eG_property grid_property)
  {
   switch(grid_property)
     {
     }
   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void V_grid::Set_property(eG_property grid_property,long property_value)
  {
   switch(grid_property)
     {
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void V_grid::Events_grid::On_event(sEvent &event)
  {
   switch(event.id)
     {
      case CHARTEVENT_ON_PROPERTY_CHANGED_:
        {
         switch(eV_object_property(event.lparam))
           {
            case vop_position_x:
              {
               _v_grid._caption.Set_property(vop_position_x,event.dparam);
               break;
              }
            case vop_position_y:
              {
               _v_grid._col_fixing.Set_property(vop_position_y,event.dparam);
               break;
              }
           }
         break;
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void V_grid::Events_scroll_v_change::On_event(sEvent &event)
  {

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void V_grid::Events_scroll_h_change::On_event(sEvent &event)
  {

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool V_grid::Create(cV_object_base &parent_object,string name=NULL)
  {
   if(CheckPointer(_main))
     {
      cLng_add_user(cV_object_base::lng_id,20,"V_grid","");
      return false;
     }
   scroll_v_change._v_grid=GetPointer(this);
   scroll_h_change._v_grid=GetPointer(this);
   events_grid._v_grid=GetPointer(this);
   _cols=5;
   _rows=5;
   _cell_width=400;
   _cell_height=400;
   _scroll_width=20;
   _size_caption=30;
   _size_fixing_col=30;
   _is_captions=true;
   _is_cols_fixing=true;
   _is_scroll_bar_v=true;
   _is_scroll_bar_h=true;

   int width=850;
   int height=850;

   _main=new cV_object_base();
   _main.Set_property_info(vop_position_x,20);
   _main.Set_property_info(vop_position_y,20);
   _main.Set_property_info(vop_size_x,width);
   _main.Set_property_info(vop_size_y,height);
   _main.Create(parent_object,name);

   _caption_v=new cV_object_base();
   if(_is_cols_fixing)
     {
      _caption_v.Set_property_info(vop_position_x,_size_fixing_col);
      if(_is_scroll_bar_v)
        {
         _caption_v.Set_property_info(vop_size_x,width-_scroll_width-_size_fixing_col);
        }
      else
        {
         _caption_v.Set_property_info(vop_size_x,width-_cell_width);
        }
     }
   else
     {
      _caption_v.Set_property_info(vop_position_x,0);
      if(_is_scroll_bar_v)
        {
         _caption_v.Set_property_info(vop_size_x,width-_scroll_width);
        }
      else
        {
         _caption_v.Set_property_info(vop_size_x,width);
        }
     }
   _caption_v.Set_property_info(vop_position_y,0);
   _caption_v.Set_property_info(vop_size_y,_size_caption);
   _caption_v.Set_property_info(vop_is_hidden,!_is_captions);
   _caption_v.Set_property_info(vop_is_anchor_left,true);
   _caption_v.Set_property_info(vop_is_anchor_right,true);
   _caption_v.Create(_main);
   _caption_v.Add_event_handler(GetPointer(scroll_v_change));
   _caption_v.Set_property_change_event(vop_is_hidden);

   _caption=new cV_object_base();
   _caption.Set_property_info(vop_position_x,0);
   _caption.Set_property_info(vop_position_y,0);
   _caption.Set_property_info(vop_size_x,_cols*_cell_width);
   _caption.Set_property_info(vop_size_y,_size_caption);
   _caption.Set_property_info(vop_is_canvas,true);
   _caption.Create(_caption_v);
   for(int i1=0; i1<_cols; i1++)
     {
      cV_object_base *col_caption=new cV_object_base();
      col_caption.Set_property_info(vop_position_x,i1*_cell_width);
      col_caption.Set_property_info(vop_position_y,0);
      col_caption.Set_property_info(vop_size_x,_cell_width);
      col_caption.Set_property_info(vop_size_y,_size_caption);
      col_caption.Set_property_info(vop_color_back,clrWhiteSmoke);
      col_caption.Set_property_info(vop_color_borders,clrGray);
      col_caption.Set_property_info(vop_border_type,long(BORDER_FLAT));
      col_caption.Set_property_info(vop_text_anchor,TA_CENTER|TA_VCENTER);
      col_caption.Set_property_info(vop_border_line_width,1);
      col_caption.Set_property_info(vop_text,"Col "+string(i1));
      col_caption.Set_property_info(vop_is_canvas_from_parent,true);
      col_caption.Create(_caption);
     }

   _col_fixing_v=new cV_object_base();
   _col_fixing_v.Set_property_info(vop_position_x,0);
   if(_is_captions)
     {
      _col_fixing_v.Set_property_info(vop_position_y,_size_caption);
      if(_is_scroll_bar_h)
        {
         _col_fixing_v.Set_property_info(vop_size_y,height-_size_caption-_scroll_width);
        }
      else
        {
         _col_fixing_v.Set_property_info(vop_size_y,height-_size_caption);
        }
     }
   else
     {
      _col_fixing_v.Set_property_info(vop_position_y,0);
      if(_is_scroll_bar_h)
        {
         _col_fixing_v.Set_property_info(vop_size_y,height-_scroll_width);
        }
      else
        {
         _col_fixing_v.Set_property_info(vop_size_y,height);
        }
     }
   _col_fixing_v.Set_property_info(vop_size_x,_size_fixing_col);
   _col_fixing_v.Set_property_info(vop_is_anchor_top,true);
   _col_fixing_v.Set_property_info(vop_is_anchor_bottom,true);
   _col_fixing_v.Set_property_info(vop_is_hidden,!_is_cols_fixing);
   _col_fixing_v.Create(_main);

   _col_fixing=new cV_object_base();
   _col_fixing.Set_property_info(vop_position_x,0);
   _col_fixing.Set_property_info(vop_position_y,0);
   _col_fixing.Set_property_info(vop_size_x,_size_fixing_col);
   _col_fixing.Set_property_info(vop_size_y,_rows*_cell_height);
   _col_fixing.Set_property_info(vop_is_canvas,true);
   _col_fixing.Create(_col_fixing_v);
   for(int i1=0; i1<_rows; i1++)
     {
      cV_object_base *cell_fixing=new cV_object_base();
      cell_fixing.Set_property_info(vop_position_x,0);
      cell_fixing.Set_property_info(vop_position_y,i1*_cell_height);
      cell_fixing.Set_property_info(vop_size_x,_size_fixing_col);
      cell_fixing.Set_property_info(vop_size_y,_cell_height);
      cell_fixing.Set_property_info(vop_color_back,clrWhiteSmoke);
      cell_fixing.Set_property_info(vop_color_borders,clrGray);
      cell_fixing.Set_property_info(vop_border_type,long(BORDER_FLAT));
      cell_fixing.Set_property_info(vop_text_anchor,TA_CENTER|TA_VCENTER);
      cell_fixing.Set_property_info(vop_border_line_width,1);
      cell_fixing.Set_property_info(vop_text,string(i1));
      cell_fixing.Set_property_info(vop_is_canvas_from_parent,true);
      cell_fixing.Create(_col_fixing);
     }

   _grid_view=new cV_object_base();
   if(_is_cols_fixing)
     {
      _grid_view.Set_property_info(vop_position_x,_size_fixing_col);
      if(_is_scroll_bar_v)
        {
         _grid_view.Set_property_info(vop_size_x,width-_size_fixing_col-_scroll_width);
        }
      else
        {
         _grid_view.Set_property_info(vop_size_x,width-_size_fixing_col);
        }
     }
   else
     {
      _grid_view.Set_property_info(vop_position_x,0);
      if(_is_scroll_bar_v)
        {
         _grid_view.Set_property_info(vop_size_x,width-_scroll_width);
        }
      else
        {
         _grid_view.Set_property_info(vop_size_x,width);
        }
     }
   if(_is_captions)
     {
      _grid_view.Set_property_info(vop_position_y,_size_caption);
      if(_is_scroll_bar_h)
        {
         _grid_view.Set_property_info(vop_size_y,height-_size_caption-_scroll_width);
        }
      else
        {
         _grid_view.Set_property_info(vop_size_y,height-_size_caption);
        }
     }
   else
     {
      _grid_view.Set_property_info(vop_position_y,0);
      if(_is_scroll_bar_h)
        {
         _grid_view.Set_property_info(vop_size_y,height-_scroll_width);
        }
      else
        {
         _grid_view.Set_property_info(vop_size_y,height);
        }
     }
   _grid_view.Set_property_info(vop_is_anchor_left,true);
   _grid_view.Set_property_info(vop_is_anchor_right,true);
   _grid_view.Set_property_info(vop_is_anchor_top,true);
   _grid_view.Set_property_info(vop_is_anchor_bottom,true);
   _grid_view.Create(_main);
   _grid_view.Add_event_handler(GetPointer(scroll_v_change));
   _grid_view.Set_property_change_event(vop_size_y);

   _grid_cols=new cV_object_base();
   _grid_cols.Set_property_info(vop_position_x,0);
   _grid_cols.Set_property_info(vop_position_y,0);
   _grid_cols.Set_property_info(vop_size_x,_cols*_cell_width);
   _grid_cols.Set_property_info(vop_size_y,_rows*_cell_height);
   _grid_cols.Create(_grid_view);
   _grid_cols.Add_event_handler(GetPointer(events_grid));
   _grid_cols.Set_property_change_event(vop_position_x);
   _grid_cols.Set_property_change_event(vop_position_y);

   _scroll_v.Create(_main,_grid_cols,true,30);
   _scroll_h.Create(_main,_grid_cols,false,30);

   for(int i1=0; i1<_cols; i1++)
     {
      cV_object_base *col=new cV_object_base();
      col.Set_property_info(vop_position_x,i1*_cell_width);
      col.Set_property_info(vop_position_y,0);
      col.Set_property_info(vop_size_x,_cell_width);
      col.Set_property_info(vop_size_y,_rows*_cell_height);
      col.Create(_grid_cols);
      for(int i2=0; i2<_rows; i2++)
        {
         cV_object_base *cell=new cV_object_base();
         cell.Set_property_info(vop_position_x,0);
         cell.Set_property_info(vop_position_y,i2*_cell_height);
         cell.Set_property_info(vop_size_x,_cell_width);
         cell.Set_property_info(vop_size_y,_cell_height);
         cell.Set_property_info(vop_color_back,clrSlateGray);
         cell.Set_property_info(vop_color_text,clrBlack);
         cell.Set_property_info(vop_text_anchor,TA_CENTER|TA_VCENTER);
         cell.Set_property_info(vop_text,string(i1*_rows+i2));
         cell.Set_property_info(vop_color_back_mouse_moving,clrDimGray);
         cell.Create(col);
        }
     }
   return true;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
cV_object_base* V_grid::Get_main_v_object()
  {
   return GetPointer(_main);
  }
//+------------------------------------------------------------------+
 
Seria bom se alguém se ocupasse em fazer uma biblioteca gráfica para criar controles
 
Реter Konow:

Sim, achei que essa fosse a parte mais difícil, porque não há nenhuma. ))))

Uma demonstração para seu monitor. Para o canto inferior direito, você pode redimensionar a mesa

Arquivos anexados:
Test_v_grid.ex5  502 kb
 
Aliaksandr Hryshyn:

Uma demonstração para seu monitor. Para o canto inferior direito, você pode redimensionar a mesa

Obrigado pela demonstração para o meu monitor.

E assim:

  • O mecanismo de janelas "emborrachadas" é inicialmente implementado,

mas ao redimensionar:

  1. As janelas não devem piscar,
  2. deve haver 8 pegas de janela para redimensionamento - para cada lado e cada canto.
  • Na verdade, a janela como entidade não é formada. Ainda não há integridade.

Por idéia, você deve chegar a uma opção semelhante:

Bem, no geral, você certamente se saiu bem! Eu não esperava isso. ))))

Continuar.
 

Eu me lembrei !

Lembrei-me do que tudo isso me lembra...

demos da GVision (um dos descendentes da TVision).

Em cerca de 93-95 você poderia comprar as demos acima mencionadas (*que não sabe - o software foi vendido no varejo) na livraria "House of Tech Books" na Leninsky Street.
Inclusive tinha um monitor separado onde a demonstração estava rolando, e você podia "tentar". Foi legal - os letreiros, os botões, as caixas de seleção/rádio e os gráficos...

mas depois comprei um Zortec-C. Uma caixa pesada, com 5 volumes de documentação e algumas disquetes :-)

bom de lembrar.

 
Реter Konow:

Obrigado pela demonstração para o meu monitor.

E assim:

  • O mecanismo de janelas "emborrachadas" é inicialmente implementado,

mas quando você redimensiona:

  1. As janelas não devem piscar,
  2. deve haver 8 pegas de janela para redimensionamento - para cada lado e cada canto.
  • Na verdade, a janela como entidade não é formada. Ainda não há integridade.

Por idéia, você deve chegar a uma opção semelhante:

Bem, no geral, você certamente se saiu bem! Eu não esperava isso. ))))

Continuar.

1. Utilizou retângulos e kanvasses em grande número com dinâmica, talvez não piscar se tudo estivesse em uma única tela, já existem limitações da plataforma, e desenhar tudo em uma única tela não é desejável. Talvez se apenas para traduzir tudo de uma só vez no DirectX.

2. Acabei de acrescentar um pequeno componente, que implementa o trecho. E não há integridade, são apenas elementos montados, e não necessariamente gráficos.

O que você não esperava? Alongamento? Para mim é tão fácil quanto isso. Eu faço estas coisas para meu projeto, não tenho planos de criar uma biblioteca de controles gráficos, embora a base para sua criação seja muito boa

#include  <Greshnik\\\Windows_engine\\Windows_engine_base.mqh>

//Элемент, который будет изменять размер родительского окна перетаскиванием мышки
//По умолчанию окошко будеи распологаться в правом нижнем углу
class cV_resizer
  {
   cV_object_base    *_main;//Основное окно
   class My_events: public iE_event_handler
     {
   public:
      cV_object_base *_e_my;
      void           On_event(sEvent &event);
     };
   My_events         ev;
public:
   //Создание таблицы
   bool              Create(
      cV_object_base &parent_object,
      string name=NULL
   );
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void cV_resizer::My_events::On_event(sEvent &event)
  {
   if(event.id==CHARTEVENT_ON_PROPERTY_CHANGED_)
     {
      if(event.lparam==vop_position_x)
        {
         cV_object_base *par=_e_my.Get_parent();
         long p=par.Get_property(vop_size_x).data_long;
         long pos=_e_my.Get_property(vop_position_x).data_long;
         long size=_e_my.Get_property(vop_size_x).data_long;
         long d=pos+size-p;
         par.Set_property(vop_size_x,p+d);
         _e_my.Set_property(vop_position_x,par.Get_property(vop_size_x).data_long-size);
        }
      else
        {
         cV_object_base *par=_e_my.Get_parent();
         long p=par.Get_property(vop_size_y).data_long;
         long pos=_e_my.Get_property(vop_position_y).data_long;
         long size=_e_my.Get_property(vop_size_y).data_long;
         long d=pos+size-p;
         par.Set_property(vop_size_y,p+d);
         _e_my.Set_property(vop_position_y,par.Get_property(vop_size_y).data_long-size);
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool cV_resizer::Create(cV_object_base &parent_object,string name=NULL)
  {
   int width=20;
   int height=20;
   long width_p=parent_object.Get_property(vop_size_x).data_long;
   long heigth_p=parent_object.Get_property(vop_size_y).data_long;

   _main=new cV_object_base();
   _main.Set_property_info(vop_size_x,width);
   _main.Set_property_info(vop_size_y,height);

   _main.Set_property_info(vop_position_x,width_p-width);
   _main.Set_property_info(vop_position_y,heigth_p-height);
   _main.Set_property_info(vop_is_movable,true);
   _main.Create(parent_object);
   _main.Add_event_handler(GetPointer(ev));
   _main.Set_property_change_event(vop_position_x);
   _main.Set_property_change_event(vop_position_y);

   ev._e_my=GetPointer(_main);
   return true;
  }
 
Aliaksandr Hryshyn:

1. Retângulos e Kanvasses são utilizados em grandes quantidades com dinâmica, talvez não piscaria se tudo estivesse em uma única tela, mas já existem limitações de plataforma, e desenhar tudo em uma única tela não é desejável. Talvez se apenas para traduzir tudo de uma só vez no DirectX.

2. Acabei de acrescentar um pequeno componente, que implementa o trecho. E não há integridade, são apenas elementos montados, e não necessariamente gráficos.

O que você não esperava? Alongamento? Para mim é tão fácil quanto isso:

Ela pisca porque você muda o tamanho do Kanvas INTEGRAL, que consome recursos, mas se você mudar a área de imagem visível em Kanvas de tamanho MÁXIMO, você se livra deste efeito desagradável. Ou seja, você cria com antecedência uma tela do tamanho de um monitor, conecta a imagem a ele (do mesmo tamanho) e depois "corta" a imagem. E as funções de redimensionamento apenas definirão a área visível da tela, não a recriarão novamente.