グラフィックライブラリーをゼロから作成する - ページ 14

 
本格的なウィンドウを作ってみる。Windowsのフォームのように。ダイナミズムがなくてもできるのですが、部分的に実装しているので、Windowsのような「ゴム」のようなウィンドウになると思います。
 
Реter Konow:
本格的なウィンドウを作ってみる。Windowsのフォームのように。ダイナミズムがなくてもできるのですが、部分的に実装しているので、Windowsのような「ゴム」のようなウィンドウになるかと思います。
一番大変なのは、ボタンを描くことです :))
 
Aliaksandr Hryshyn:
一番大変なのは、ボタンを描くことです :))

ええ、それが一番難しいと思ってました、だって無いんですもの ))))

 

スクロールは別に作られ、特定のウィンドウ構成に適用することができ、残りの部分(イベント、必要なプロパティの変更)は自動的に行われます。接続はとても簡単です。

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

テーブルを作る 難しさについて ですが、 エンジンの出来が非常に良いので、それを使ってテーブルを作ることはそれほど難しくはありません。

//+------------------------------------------------------------------+
//|                                                       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);
  }
//+------------------------------------------------------------------+
 
コントロールを作成するためのグラフィックライブラリーを 誰か忙しく作ってくれるといいのだが
 
Реter Konow:

うん、それが一番難しいと思っていたよ、だって無いんだもん )))

モニター用のデモです。右下は、テーブルのサイズを変更することができます

ファイル:
Test_v_grid.ex5  502 kb
 
Aliaksandr Hryshyn:

モニター用のデモです。右下は、テーブルのサイズを変更することができます

モニター用のデモをありがとうございました。

といった具合に。

  • 当初は「ゴム窓」機構を実装しています。

が、リサイズすると

  1. ウィンドウが点滅しないこと。
  2. リサイズ用のウィンドウグリップハンドルは、各辺と各コーナーに8個ずつあるはずです。
  • 実は、実体としてのウィンドウは形成されていないのです。まだ整合性がとれていない。

アイデア次第で、同じような選択肢に行き着くはずです。

まあ、全体的に見れば、確かによくやったと思います。予想外でした ))))

続けてください。
 

思い出した !

その中で思い出したのが...。

GVision(TVisionの末裔の一つ)のデモ。

93~95年頃、レニンスキー通りの「House of Tech Books」という本屋で、上記のデモ(※知らない人はいないだろうが、ソフトは小売で売られていた)を買うことができた。
さらに、デモがスクロールする別のモニターがあり、「トライ」することができました。看板、ボタン、チェック/ラジオボックス、グラフィック......カッコよかったです。

が、その後、ゾルテックCを購入。5冊のドキュメントとフロッピーディスクが入った、重厚な箱です :-)

を覚えておくといいですね。

 
Реter Konow:

モニター用のデモをありがとうございました。

といった具合に。

  • 当初は「ゴム窓」機構を実装しています。

が、リサイズすると

  1. ウィンドウが点滅しないこと。
  2. リサイズ用のウィンドウグリップハンドルは、各辺と各コーナーに8個ずつあるはずです。
  • 実は、実体としてのウィンドウは形成されていないのです。まだ整合性がとれていない。

アイデア次第で、同じような選択肢に行き着くはずです。

まあ、全体的に見れば、確かによくやったと思います。予想外でした ))))

続けて

1.ダイナミクスで大量の矩形とカンヴァスを使用し、すべてが1カンヴァスにあった場合、多分瞬きしない、すでにプラットフォームの制限があり、1カンヴァスにすべてを描くことは望ましくありません。DirectXで一気に翻訳するだけならいいかもしれませんが...。

2.ストレッチを実装した小さなコンポーネントを1つ追加したところです。しかも、整合性がなく、ただ要素を組み立てただけで、必ずしもグラフィックとは言えない。

予想外だったことは?ストレッチング?それくらい、私にとっては簡単なことなのです。私は自分のプロジェクトのためにこれらのものを作っているので、グラフィックコントロールの ライブラリを作る予定はないのですが、作るための基礎はとても良いものです

#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.矩形やカンバスはダイナミクスで大量に使われる、全てが一つのカンバスに収まればブレないのかもしれないが、既にプラットフォームの制約があり、全てを一つのカンバスに描くことは好ましくない。DirectXで一気に翻訳するだけならいいかもしれませんが...。

2.ストレッチを実装した小さなコンポーネントを1つ追加したところです。しかも、整合性がなく、ただ要素を組み立てただけで、必ずしもグラフィックとは言えない。

予想外だったことは?ストレッチング?それくらい、私にとっては簡単なことなのです。

キャンバス全体のサイズを変更するため、リソースを消費して点滅しますが、最大サイズのキャンバスに表示される画像の領域を変更すれば、この不快な効果は解消されます。つまり、あらかじめモニターの画面サイズのカンヴァスを作っておき、そこに(同じサイズの)画像をつないで「切り抜き」を行うのです。また、リサイズ機能は、キャンバスの可視領域を定義するだけで、再作成することはありません。