Erstellen einer Grafikbibliothek von Grund auf - Seite 5

 
Wie geht es mit der Bibliothek weiter?
 
Реter Konow:
Wie geht es mit der Bibliothek weiter?

ist alles mehr als in Ordnung.

 

Ich habe auch den Dreh raus, eine Grafikbibliothek zu erstellen, nur mit den Elementen, die ich brauche.

Der Haupttrick der Bibliothek ist ihre Windowing-Engine:

  • es hängt nicht von der Grafik ab, man kann sagen, dass virtuelle Fenster ohne eine einzige Funktion mit der Grafik arbeiten, sogar absolut Fenster werden korrekt funktionieren (Ereignisse, Eigenschaften)
  • Sätze von Eigenschaften für ein Fenster, die sein Verhalten beeinflussen, abhängige Eigenschaften dieses Fensters und andere

   cV_object_base::Init(my_handler);
   cV_object_rectangle *app_00=new cV_object_rectangle();
   cV_object_rectangle *app_0=new cV_object_rectangle();
   cV_object_rectangle *app_1=new cV_object_rectangle();

   cV_object_label *lb1=new cV_object_label();
   app_00.Create(cV_object_base::global_parent_object);
   app_00.Set_property(vop_size_x,800);
   app_00.Set_property(vop_size_y,500);
   app_00.Set_property(vop_color_back,clrDarkGreen);

   app_0.Create(app_00,"AAA");

   app_00.Set_property(vop_is_position_fixing_parent_x,true);
   app_00.Set_property(vop_is_position_fixing_parent_y,true);

   app_1.Create(app_00);
   app_0.Set_property(vop_is_zorder_top_on_click,true);
   app_0.Set_property(vop_is_position_fixing_parent_x,true);
   app_0.Set_property(vop_is_position_fixing_parent_y,true);
   app_1.Set_property(vop_is_zorder_top_on_click,true);

   app_0.Set_property(vop_size_x,1000);
   app_0.Set_property(vop_size_y,300);
   app_0.Set_property(vop_position_x,100);
   app_0.Set_property(vop_position_y,100);
   app_0.Set_property(vop_color_back,clrDarkBlue);
   app_0.Set_property(vop_is_movable,true);
   app_0.Set_property(vop_is_selected_multi,false);

   lb1.Create(app_0,"E_hallo_world_E");
   lb1.Set_property(vop_is_movable,true);
   lb1.Set_property(vop_color_back_selected,clrDarkTurquoise);
   lb1.Set_property(vop_is_change_color_back_on_select,true);
   lb1.Set_property(vop_is_zorder_top_on_click,true);

   app_1.Set_property(vop_size_x,300);
   app_1.Set_property(vop_size_y,500);
   app_1.Set_property(vop_position_x,200);
   app_1.Set_property(vop_position_y,200);
   app_1.Set_property(vop_is_movable,true);

   cV_object_rectangle *app_2;
   cV_object_rectangle *app_3;
   for(int i1=0; i1<4; i1++)
     {
      app_2=new cV_object_rectangle();
      app_3=new cV_object_rectangle();
      app_2.Create(app_0,ShortToString(ushort('A'+i1)));
      app_3.Create(app_1);

      app_2.Set_property(vop_size_x,100);
      app_2.Set_property(vop_size_y,75);
      app_3.Set_property(vop_size_x,75);
      app_3.Set_property(vop_size_y,100);

      app_2.Set_property(vop_position_x,i1*20);
      app_2.Set_property(vop_position_y,i1*40);
      app_3.Set_property(vop_position_x,i1*20);
      app_3.Set_property(vop_position_y,i1*40);

      app_2.Set_property(vop_color_back,clrDarkGray);
      app_3.Set_property(vop_color_back,clrLightGoldenrod);

      app_2.Set_property(vop_is_movable,true);
      app_2.Set_property(vop_is_zorder_top_on_click,true);
      app_3.Set_property(vop_is_movable,true);

      app_3.Set_property(vop_is_change_color_back_on_select,true);
      app_3.Set_property(vop_color_back_selected,clrRed);

      app_2.Set_property(vop_color_back_selected,clrDarkTurquoise);
      app_2.Set_property(vop_is_change_color_back_on_select,true);
     }
   app_3.Set_property(vop_moving_parent_index,1);
   app_3.Set_property(vop_position_x,150);
   app_3.Set_property(vop_size_y,150);

   app_2.Set_property(vop_moving_parent_index,2);
   app_2.Set_property(vop_position_x,150);
   app_2.Set_property(vop_size_y,150);

   app_2.Set_property(vop_color_borders,clrDarkTurquoise);
   app_3.Set_property(vop_color_borders,clrDarkTurquoise);

   app_2.Set_property(vop_is_change_color_back_on_mouse_move,true);
   app_3.Set_property(vop_is_change_color_back_on_mouse_move,true);
   app_2.Set_property(vop_is_change_color_borders_on_mouse_move,true);
   app_3.Set_property(vop_is_change_color_borders_on_mouse_move,true);
   app_3.Set_property(vop_is_selected,true);


  • als Grafik können Sie sowohl Standard-Objekte und Canvas als auch DirectX verwenden, was immer Sie wollen
  • Motorfenster sind die Bausteine für den Aufbau grafischer Elemente
  • Nutzung verschiedener Leistungsoptimierungen (Ausschluss von unnötigen Aufrufen von Grafiksystemfunktionen, sowie Ausschluss vom Zeichnen unsichtbarer Boxen)
  • Einfachheit bei der Erstellung eines neuen grafischen Elements, sowohl bei der Implementierung des grafischen Designs als auch bei der Erstellung der untergeordneten grafischen Elemente/Fensterstruktur. Alle Ereignisse und Berechnungen von abhängigen Eigenschaften werden auf der Ebene des Motors durchgeführt, es wird nicht zwischen benutzerdefinierten grafischen Elementen unterschieden, es funktioniert nur auf der Ebene der Basisfenster

Anlegen und Löschen des Standardobjekts OBJ_RECTANGLE_LABEL

bool cV_object_rectangle::_Create_resource()
  {
   if(!ObjectCreate(0,visual_object_name,OBJ_RECTANGLE_LABEL,0,0,0))
     {
      cLng_add_user(lng_id,8,EnumToString(OBJ_RECTANGLE_LABEL),"");
      return false;
     }
   return true;
  }

bool cV_object_rectangle::_Delete_resource()
  {
   ObjectDelete(0,visual_object_name);
   return true;
  }

Dies implementiert eine Methode zum Ändern der Eigenschaften des Standardobjekts OBJ_RECTANGLE_LABEL, indem es die Hilfe durchforstet und die gewünschten Eigenschaften verwendet

bool cV_object_rectangle::_Set_property(eV_object_property property,sV_property_value &property_value)
  {
   _is_redraw_object=true;
   switch(property)
     {
      case vop_s_is_hidden:
        {
         if(property_value.data_long)
           {
            ObjectSetInteger(0,visual_object_name,OBJPROP_XSIZE,0);
            ObjectSetInteger(0,visual_object_name,OBJPROP_YSIZE,0);
            ObjectSetInteger(0,visual_object_name,OBJPROP_XDISTANCE,-20);
            ObjectSetInteger(0,visual_object_name,OBJPROP_YDISTANCE,-20);
           }
         else
           {
            ObjectSetInteger(0,visual_object_name,OBJPROP_XSIZE,_property_values[vop_s_size_real_x].data_long);
            ObjectSetInteger(0,visual_object_name,OBJPROP_YSIZE,_property_values[vop_s_size_real_y].data_long);
            ObjectSetInteger(0,visual_object_name,OBJPROP_XDISTANCE,_property_values[vop_s_position_real_x].data_long);
            ObjectSetInteger(0,visual_object_name,OBJPROP_YDISTANCE,_property_values[vop_s_position_real_y].data_long);
           }
         break;
        }
      case vop_s_color_back:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_BGCOLOR,property_value.data_long);
         break;
        }
      case vop_border_type:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_BORDER_TYPE,property_value.data_long);
         break;
        }
      case vop_s_color_borders:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_COLOR,property_value.data_long);
         break;
        }
      case vop_s_position_real_x:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_XDISTANCE,property_value.data_long);
         break;
        }
      case vop_s_position_real_y:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_YDISTANCE,property_value.data_long);
         break;
        }
      case vop_s_size_real_x:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_XSIZE,property_value.data_long);
         break;
        }
      case vop_s_size_real_y:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_YSIZE,property_value.data_long);
         break;
        }
      case vop_font_size:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_FONTSIZE,property_value.data_long);
         break;
        }
      case vop_line_width:
        {
         ObjectSetInteger(0,visual_object_name,OBJPROP_WIDTH,property_value.data_long);
         break;
        }
      default:
        {
         _is_redraw_object=false;
        }
     }
   return true;
  }

  • einfache Ereignisbehandlung
Dies ist ein externer Event-Handler, der Name des interessierenden Objekts (Fenster/Grafikelement) kann bei der Erstellung angegeben werden
class My_handler:public iE_event_handler
  {
   void              On_event(sEvent &event)
     {
      if(event.id==CHARTEVENT_CLICK_)
        {
         if(
            (event.sparam=="A")||
            (event.sparam=="B")||
            (event.sparam=="C")||
            (event.sparam=="D")||
            (event.sparam=="E_hallo_world_E")
         )
           {
            sV_property_value v;
            cV_object_base *obj;
            obj=cV_object_base::Get_object_from_name(event.sparam);
            obj.Get_property(vop_is_selected,v);
            v.data_long=!v.data_long;
            obj.Set_property(vop_is_selected,v.data_long);
           }
         else
            if(event.sparam=="AAA")
              {
               sV_property_value v;
               cV_object_base *obj;
               obj=cV_object_base::Get_object_from_name("AAA");
               obj.Get_property(vop_is_selected_multi,v);
               v.data_long=!v.data_long;
               obj.Set_property(vop_is_selected_multi,v.data_long);
              }
            else
               if(event.sparam=="vt_rectangle_4")
                 {
                  sV_property_value v;
                  cV_object_base *obj;
                  obj=cV_object_base::Get_object_from_name("AAA");
                  obj.Get_property(vop_position_x,v);
                  v.data_long=v.data_long+5;
                  obj.Set_property(vop_position_x,v.data_long);
                  ulong ms=cV_object_base::Get_timer_msc();
                  if(ms!=ULONG_MAX)
                    {
                     Print(ms/1000.0," мс");
                    }
                 }
        }
     }
  };

Die Textbeschriftung wird über eine Leinwand implementiert, da die Breite und Höhe im OBJ_LABEL-Objekt nicht geändert werden können. Aus diesem Grund wird das Rendering durchgeführt, wenn ein CHARTEVENT_ON_PAINT-Ereignis eintritt (was ein erneutes Zeichnen erfordert).

bool cV_object_label::_On_event(const sEvent &event)
  {
   if(event.id==CHARTEVENT_ON_PAINT)
     {
      color color_back=clrBlack;
      if(CheckPointer(_object_parent))
        {
         color_back=color(_object_parent._property_values[vop_color_back].data_long);
        }
      int width=int(_property_values[vop_s_size_real_x].data_long);
      int height=int(_property_values[vop_s_size_real_y].data_long);
      int x=int(_property_values[vop_s_position_global_x].data_long-_property_values[vop_s_position_real_x].data_long);
      int y=int(_property_values[vop_s_position_global_y].data_long-_property_values[vop_s_position_real_y].data_long);
      _canvas.Resize(width,height);
      width=int(_property_values[vop_size_x].data_long);
      height=int(_property_values[vop_size_y].data_long);
      _canvas.Erase(ColorToARGB(color_back));
      switch(int(_property_values[vop_text_anchor].data_long))
        {
         case TA_CENTER:
           {
            x=x+(width-_canvas.TextWidth(_property_values[vop_text].data_string))/2;
            break;
           }
         case TA_RIGHT:
           {
            x=x+(width-_canvas.TextWidth(_property_values[vop_text].data_string));
            break;
           }
        }
      _canvas.TextOut(x,y,_property_values[vop_text].data_string,ColorToARGB(color(_property_values[vop_s_color_back].data_long)));//);
      _canvas.Update(false);
     }
   return true;
  }

Was gerendert und aktualisiert werden soll, wird automatisch bestimmt. Die Eigenschaften werden vor dem Aufruf von ChartRedraw() protokolliert. Ereignisse, die nicht zum Neuzeichnen des Diagramms geführt haben, werden übersprungen.

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   cV_object_base::On_chart_event(id,lparam,long(dparam),sparam);
   ulong ms=cV_object_base::Get_timer_msc();
   if(ms!=ULONG_MAX)
     {
      Print(ms/1000.0," мс");
     }
  }

Die Demo befindet sich in der angehängten Datei, die oben genannten Quellen werden darin verwendet.

Dateien:
Test_forms.ex5  221 kb
 

In der Demo werden nicht alle möglichen Eigenschaften angezeigt, sondern nur einige von ihnen:

Bislang ist es noch ein unfertiges Werk.

 
Aliaksandr Hryshyn:

In der Demo werden nicht alle möglichen Eigenschaften angezeigt, sondern nur einige von ihnen:

Im Moment ist es noch eine Baustelle, die noch nicht abgeschlossen ist.

Viel Erfolg bei der Entwicklung! :)

 
Реter Konow:

Viel Erfolg bei der Entwicklung! :)

Danke :)

 

Getestet wurde die Funktionalität und das Potenzial der 3D-Grafik in MT5 auf einem schwachen Computer mit 4 GB RAM und 2 Prozessorkernen.



Sie funktioniert auch nach einer längeren Programmierpause einwandfrei. Aber das Ding ist schwer und es erfordert viel harte Arbeit, um etwas Ernsthaftes zu schaffen.

 
Hilft es, Geld zu verdienen?
 
Реter Konow:

Getestet wurde die Funktionalität und das Potenzial der 3D-Grafik in MT5 auf einem schwachen Computer mit 4 GB RAM und 2 Prozessorkernen.

Sie funktioniert auch nach einer längeren Programmierpause einwandfrei. Aber das Ding ist schwer und es erfordert viel harte Arbeit, um etwas Ernsthaftes zu entwickeln.

Für HFT wird 3D meiner Meinung nach für die grafische Analyse des Volumens und des Auftragsflusses in der Tasse nützlich sein.
Aber ich weiß nicht, wie ich solche Informationen interpretieren soll.

dom

Strom

 

Mein Gott, was soll das alles?