처음부터 그래픽 라이브러리 만들기 - 페이지 14

 
전체 창을 만들어보십시오. 윈도우 폼처럼. 역동성이 없어도 가능하지만 부분적으로 구현했으니 윈도우 같은 '고무' 창이 나올 거라고 생각한다.
 
Реter Konow :
전체 창을 만들어보십시오. 윈도우 폼처럼. 역동성이 없어도 가능하지만 부분적으로 구현했으니 윈도우 같은 '고무' 창이 나올 거라고 생각한다.
가장 어려운 부분은 버튼을 그리는 것입니다 :))
 
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 :

모니터용 데모. 오른쪽 하단 모서리의 경우 테이블 크기를 조정할 수 있습니다.

내 모니터의 데모용 ATP.

그래서:

  • 창의 "고무성" 메커니즘이 초기에 구현되었으며,

그러나 크기를 조정할 때:

  1. 창은 깜박거리지 않아야 합니다.
  2. 크기 조정을 위한 8개의 창 그립 핸들이 있어야 합니다(각 측면 및 각 모서리에 대해).
  • 사실 창은 실체로서 형성되지 않는다. 아직 무결성이 없습니다.

아이디어에 따르면 비슷한 옵션을 선택해야 합니다.

글쎄, 일반적으로 당신은 확실히 잘했습니다! 예상치 못한.))))

계속해.
 

기억!

모든 것이 생각나는 것을 기억합니다...

GVision(TVision의 후손 중 하나)의 데모.

93년에서 95년 사이에 위에서 언급한 제품은 Leninsky의 "Dom Tech.Knigi" 서점에서 구입할 수 있었습니다(* 모르는 사람 - 소프트웨어는 소매점에서 판매됨).
데모가 스크롤되는 별도의 모니터도 있었고 "시도"할 수 있습니다. 그것은 멋졌다 - 사인, 버튼, 체크/라디오 박스, 그리고 그래픽..

그러나 나는 Zortec-C를 샀다. 5권의 설명서와 약간의 플로피 디스크가 들어 있는 무거운 상자 :-)

기억하기 좋은.

 
Реter Konow :

내 모니터의 데모용 ATP.

그래서:

  • 창의 "고무성" 메커니즘이 초기에 구현되었으며,

그러나 크기를 조정할 때:

  1. 창은 깜박거리지 않아야 합니다.
  2. 크기 조정을 위한 8개의 창 그립 핸들이 있어야 합니다(각 측면 및 각 모서리에 대해).
  • 사실 창은 실체로서 형성되지 않는다. 아직 무결성이 없습니다.

아이디어에 따르면 비슷한 옵션을 선택해야 합니다.

글쎄, 일반적으로 당신은 확실히 잘했습니다! 예상치 못한.))))

계속해.

1. 사각형과 캔버스는 역학과 함께 대량으로 사용되며 모든 것이 하나의 캔버스에 있으면 깜박이지 않을 수 있으며 이미 플랫폼 제한이 있으며 하나의 캔버스에 모든 것을 그리고 싶은 욕구가 없습니다. 모든 것을 DirectX로 즉시 전송하는 경우에만 ...

2. 스트레칭을 구현하는 하나의 작은 구성 요소를 추가하고 테이블에서 테스트했습니다. 그러나 무결성이 없으며 조립식 요소일 뿐이며 반드시 그래픽이 필요한 것은 아닙니다.

무엇을 기대하지 않았습니까? 스트레칭? 그래서 이것은 제가 하기 쉽습니다. 나는 내 프로젝트를 위해 이러한 일을 하고 있으며, 그래픽 컨트롤 라이브러리를 만들 계획은 없지만, 만들기 기반은 매우 좋습니다.

 #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. 스트레칭을 구현하는 하나의 작은 구성 요소를 추가하고 테이블에서 테스트했습니다. 그러나 무결성이 없으며 조립식 요소일 뿐이며 반드시 그래픽이 필요한 것은 아닙니다.

무엇을 기대하지 않았습니까? 스트레칭? 그래서 모든 것을 하기가 쉽습니다.

리소스 집약적 인 ENTIRE 캔버스의 크기를 변경하기 때문에 깜박이지만 MAXIMUM 크기의 캔버스에서 보이는 이미지의 영역을 변경하면 이러한 불쾌한 효과를 제거하십시오. 저것들. 미리 모니터 화면 크기의 캔버스를 만들어 동일한 크기의 이미지를 연결한 다음 "자르기"합니다. 그리고 크기 조정 기능은 캔버스를 다시 만들지 않고 캔버스의 범위만 결정합니다.