キャンバスがカッコいい! - ページ 84

 
Martin Moreno #:
Canvasクラスを使ってユーザー・インターフェースを作りたいと思っています。唯一の問題は、ダッシュボードをチャート上で移動可能にする方法がわからないことです。
たくさん検索したのですが、例が見つかりませんでした。ヒントをいただければ幸いです。


この記事から始めることができます: https://www.mql5.com/en/articles/12751

Improve Your Trading Charts With Interactive GUI's in MQL5 (Part I): Movable GUI (I)
Improve Your Trading Charts With Interactive GUI's in MQL5 (Part I): Movable GUI (I)
  • www.mql5.com
Unleash the power of dynamic data representation in your trading strategies or utilities with our comprehensive guide on creating movable GUI in MQL5. Dive into the core concept of chart events and learn how to design and implement simple and multiple movable GUI on the same chart. This article also explores the process of adding elements to your GUI, enhancing their functionality and aesthetic appeal.
 
Samuel Manoel De Souza #:

https://www.mql5.com/en/articles/12751

ありがとうございます!

 
Martin Moreno #:
Canvasクラスを使ってユーザー・インターフェースを作りたいと思っています。ー ダッシュボードをー
たくさん検索したのですが、例が見つかりませんでした。ヒントをいただければ幸いです。


すでに4年前に例を挙げています :))

取引、自動取引システム、取引戦略のテストに関するフォーラム

すべてのオブジェクトを1つのオブジェクトに変換する方法

ニコライ・セムコ, 2019.10.05 22:39

確かに、Canvasは解決策です。

そして、Canvasは一見したところよりもずっと簡単です。

ここに、1つのオブジェクトOBJ_BITMAP_LABELを持つインジケータ(MQL5とMQL4)の原始的な例を示します。

#property indicator_chart_window
#include <Canvas\iCanvas.mqh> //https://www.mql5.com/ru/code/22164 - MQL5
                              //https://www.mql5.com/en/code/23840 - MQL4

struct win {
   int               x;
   int               y;
   int               width;
   int               height;
   uint              clr;
};
win wnd[30];
int OnInit() {
   for (int i=0; i<ArraySize(wnd); i++) {
      wnd[i].width=rand()%200+70;
      wnd[i].height=rand()%150+50;
      wnd[i].x=rand()%(W.Width-wnd[i].width);
      wnd[i].y=rand()%(W.Height-wnd[i].height);
      wnd[i].clr=ARGB(255,rand()%150+100,rand()%150+100,rand()%150+100);
   }
   ShowAllWind();
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+

int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) {
   return(rates_total);
}

//+------------------------------------------------------------------+

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam) {
   static bool click = false;
   static int x_mouse=0, y_mouse=0;
   static int focus=-1, xfocus=0, yfocus=0;
   int x=(int)lparam;
   int y=(int)dparam;
   if (sparam!="1" && click) focus=-1;
   if (sparam=="1" && !click) {
      focus=-1;
      for (int i=ArraySize(wnd)-1; i>=0; i--) {
         if (wnd[i].x<x && wnd[i].y<y && wnd[i].x+wnd[i].width>x && wnd[i].y+20>y) {
            focus=i;
            xfocus=x;
            yfocus=y;
            break;
         }
      }
      if (focus>=0) ChartSetInteger(0,CHART_MOUSE_SCROLL,false);
      else ChartSetInteger(0,CHART_MOUSE_SCROLL,true);
   }
   click=(sparam=="1")?true:false;
   if (id==CHARTEVENT_MOUSE_MOVE && focus>=0) {
      wnd[focus].x+=x-xfocus;
      wnd[focus].y+=y-yfocus;
      xfocus=x;
      yfocus=y;
      ShowAllWind();
   }
   if (id==CHARTEVENT_CHART_CHANGE) ShowAllWind();
}

//+------------------------------------------------------------------+

void ShowAllWind() {
   Canvas.Erase();
   for (int i=0; i<ArraySize(wnd); i++) {
      Canvas.FillRectangle(wnd[i].x,wnd[i].y,wnd[i].x+wnd[i].width,wnd[i].y+wnd[i].height,ARGB(255,GETRGBR(wnd[i].clr)*0.5,GETRGBG(wnd[i].clr)*0.5,GETRGBB(wnd[i].clr)*0.5));
      Canvas.FillRectangle(wnd[i].x+3,wnd[i].y+23,wnd[i].x+wnd[i].width-3,wnd[i].y+wnd[i].height-3,wnd[i].clr);
      Canvas.FillRectangle(wnd[i].x+3,wnd[i].y+3,wnd[i].x+wnd[i].width-3,wnd[i].y+20,ARGB(255,GETRGBR(wnd[i].clr)*0.7,GETRGBG(wnd[i].clr)*0.7,GETRGBB(wnd[i].clr)*0.7));
   }
   Canvas.Update();
}
//+------------------------------------------------------------------+

この新しい記事には、インフォメーション・パネルを実装するための別のオプションがあります。

https://www.mql5.com/ru/articles/13179

ファイル:
 
Nikolai Semko #:
例えば、それを明確に示すスクリプトをスケッチしてみた。右側がこの高速アルゴリズムで、左側が私のアルゴリズム(約4~10倍遅い)である。 。
ニコライ・セムコ、こんにちは。この例https://www.mql5.com/ru/forum/227736/page66#comment_20456641 では、Bmpのリサイズ(縮小)を実演していますね。

私はBmp画像を縮小することができますが、キャンバスは同じサイズのままです。同じ理由で画像を拡大することもできず、元のサイズ、つまりキャンバスのサイズでトリミングされます。

私は配列を完全に理解しているわけではないので、説明してもらえますか:

1.画像の拡大

2.画像を縮小または拡大した場合、そのサイズと同じキャンバス。

ありがとうございました。

 
Vitaliy Kuznetsov #:
Nikolai Semko さん、こんにちは。この例(https://www.mql5.com/ru/forum/227736/page66#comment_20456641)では、Bmpのリサイズ(縮小)を実演していますね。

Bmp画像を縮小することはできますが、キャンバスは同じサイズのままです。同じ理由で画像を拡大することもできず、元のサイズ、つまりキャンバスのサイズでトリミングされてしまいます。

私は配列を完全に理解しているわけではないので、説明してもらえますか:

1.画像の拡大

2.画像を縮小または拡大した場合、そのサイズと同じキャンバス。

ありがとうございました。

こんにちは、
CCanvas には Resize() 関数があります。
 
Vitaliy Kuznetsov #:

クールで便利です。ちょっと興味があるのですが、これはMT4で使えますか?

残念ながら、MQL4ではリソースを配列としてアタッチすることはできません。しかし、それ以外はすべて機能します。
もちろん、ハードタンバリンで実装することはできます。例えば、PNG画像をBMPファイルに挿入します。つまり、pngの先頭にBMPヘッダーを追加し、png自体をbmp画像として渡します(つまり、そのようなBMPを開くと、透明度の異なるカラーピクセルのノイズが発生します)。そして、この「bmpファイル」をMQL4のリソースとして添付する。これは市場にとって必要なことで、ex4にはより高密度なpng形式の画像がすでに含まれている。
参考までに:pngは同じBMP画像より約10倍小さく、画質も損なわず、さらに完全な透明度をサポートしています。
ex5(ex4)ファイル内の真のbmpリソースは、コンパクト化されたフォーマットで保存されますが、桁が1つ少ないわけではありません。正確な確認が必要である。
 

皆さん、こんにちは。私もこのコードに興味があります。しかし、Resize()を使ってもうまくいきません。多分、別の順序で行うべきです。

 
Vladimir Nikolaychuk #:

皆さん、こんにちは。私もこのコードに興味があります。しかし、Resize()を使ってもうまくいきません。多分、別の順序で行うべきです。

わかりました、後で例をあげます。
しかし、私はチャート全体を1つのキャンバスで作業することを好む。95%の確率でそうする。
 
Nikolai Semko #:
では、もう少し後で例を挙げよう。
しかし、私はチャート全体を1つのキャンバスで作業することを好む。これは95%の確率で正当化される。

コード例を教えていただけるとありがたいです。よろしくお願いします。

 
Nikolai Semko #:
では、もう少し後で例を挙げよう。
しかし、私はチャート全体を1つのキャンバスで作業することを好む。これは95%の確率で正当化される。

これはpng.mql ライブラリに基づく例で、マウスを動かすとキャンバスの位置が変わり、サイズも変わる。マウス・ポインタが水平方向の中央にある場合は、画像の元のサイズに対応し、左にある場合はズーム・アウト、右にある場合はズーム・インする。
ただ、png.mqlの変数Cと_Cをprivateからpublicに投げ直す必要があった。そのため、このライブラリがすでにインストールされている場合は上書きする必要がある。
この例には2つの動作モードがある(入力変数bool resize_canvas):

  • 画像のサイズが変更されるたびにCanvasのサイズを変更する場合
  • 画像が リサイズされるたびにCanvasのサイズを変更するモード。 Canvasの初期サイズは、作業の論理に従って、可能な最大画像サイズに等しく設定されます。
残念なことに、MQL5の最初のモードでは、画像が点滅するという古くからのバグがあり、これを治すには、キャンバスのサイズを変えないという1つの方法しかない。CCanvas.Resize()関数を変更しようと試みたが、何も得られなかった。すべてが同じように点滅する。もしかしたら、誰かがやってくれるかもしれない :))
だから、画面全体には1つのキャンバスを使いたいのだ!

#define  MAX_ZOOM 2
#include <Canvas\png.mqh> //https://www.mql5.com/en/code/45439
CPng img("cubes.png"); // Get PNG from a file, create a canvas and display it on the screen at coordinates (X=500, Y=100)

input bool resize_canvas = false;
int chart_width,chart_height;


//+------------------------------------------------------------------+
int OnInit() {
   img.Resize(resize_canvas?10:img.width*MAX_ZOOM); // формируем массив _bmp[] максимального размера в режиме без изменения размера canvas
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
   chart_width = (int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
   chart_height = (int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
   img._CreateCanvas(chart_width/3, chart_height/3);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
}
//+------------------------------------------------------------------+
void OnTick() {
}
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam) {
   if (id == CHARTEVENT_MOUSE_MOVE) {
      double new_width = img.width*(MAX_ZOOM*(double)lparam/chart_width);
      img.Resize(new_width);
      if (resize_canvas) { // режим с изменением размера canvas  Моргает!!!
         img._C.Resize(img._width,img._height);
         ArrayCopy(img._C.m_pixels,img._bmp);
      } else {  // режим без изменения размера canvas         не Мограет!!!
         img._C.Erase(0x00FFFFFF);
         for(int i =0; i++<img._height;) ArrayCopy(img._C.m_pixels,img._bmp,int(i*img.width*MAX_ZOOM),i*img._width,img._width);
      }
      img._C.Update();
      img._MoveCanvas(int(lparam)/5, int(dparam)/5);
   }
}



PNG
PNG
  • www.mql5.com
Forget about BMP files like a bad dream. Thanks to this library, you can now use the PNG format, which has a number of advantages, such as being more compact without losing image quality and maintaining transparency.
ファイル:
理由: