ライブラリ: イージーキャンバス - ページ 12

 
Nikolai Semko:

これは通常モードとテスターのどちらに適用されますか?

ノーマルモードだよ、ニコライ。

 
Nikolai Semko:

ありがとう!

この機能は適していないのでしょうか?

残念ながらそうではありません。この関数はビットマップオブジェクト自体を移動させるので、コンテンツのx点を移動させる関数が必要なのです。内部的にメモリがx,yの配列で構成されていることは知っているが、mqlにはmemmoveとかはない。メモリを素早く移動させる方法がわからない。

 
Владислав Качило :

ノーマルモードだよ、ニコライ

私は通常、次のようなスキームに従っている:

  1. 例えば、void Draw()のように。
  2. OnChartEventで チャートの変化イベント(新しいバーはチャートの変化でもある。
    if (id == CHARTEVENT_CHART_CHANGE ) Draw (); 
    チャート・チェンジ・イベントをトラッキングする(新しいバーはチャート・チェンジ・イベントでもある)。
  3. テスト・モードのOnCalculateでは、OnChartEventが機能しないため、例えば新しいバーが発生したときに再描画するための線を追加します。
     if(rate_total-prev_calculated == 1) if (Canvas.tester) {ChartChanged (); Draw ();}

MT4で動作しないのであれば、CHARTEVENT_CHART_CHANGEイベントの何かが間違っています。今はまだ相場がないので確認できません。

 
Nikolai Semko:

私はいつも次のようにしている:

  1. 例えば、void Draw()のように、バーや時間に関連するすべての描画を1つの関数で行う。
  2. OnChartEventに、チャート・チェンジ・イベントを追跡するための 行を追加する (新しいバーもチャート・チェンジ・イベントである)。
  3. テスト・モードのOnCalculateでは、OnChartEventが機能しないので、例えば新しいバーが発生したときに再描画するための行を追加します:

MT4で動作しないのであれば、CHARTEVENT_CHART_CHANGEイベントがおかしいということになります。今はまだ相場がないので確認できません。

ニコラス、あなたが時間を無駄にしないように、私の問題を解決した解決策を上に書きました、すなわち、あなたが正しく気づいたように、OnCalcucate()に挿入した以下のコードです:

if(rates_total - prev_calculated == 1)ChartChanged();

 
Mighty7:

残念ながらそうではない。ビットマップオブジェクト自体を移動させるので、コンテンツのx点を移動させる関数が必要なのだ。内部的にメモリがx,yの配列で構成されていることは知っているが、mqlにはmemmoveとかはない。メモリを素早く移動させる方法がわからない。

キャンバス全体の中の矩形領域を移動させるのですか?

 
Vladyslav Katsylo:

ニコラス、あなたの時間を無駄にしないために、私の問題を解決した解決策を上に書いた、つまり、あなたが正しく気づいたように、OnCalcucate()に次のコードを挿入した:

なぜなら、ChartChanged()関数が2回続けて実行されるからです。結局、この関数は、iCanvas.mqh ファイル内で CHARTEVENT_CHART_CHANGE イベントが発生したときに実行されます。
ChartChanged() を使用せずに、ウィンドウ変更イベント(CHARTEVENT_CHART_CHANGE)が発生したときにOnChartEvent でバーまたは時間にバインドされたキャンバスを再描画するのが正しいです。

 
Vladyslav Katsylo:

ニコラス、あなたの時間を無駄にしないために、私の問題を解決した解決策を上に書きました、つまり、あなたが正しく気づいたように、OnCalcucate()に次のコードを挿入しました:

次のことを考慮する必要があります:

  • ChartChanged() は、iCanvas クラス内部のOnChartEventCHARTEVENT_CHART_CHANGE イベントが発生するたびに実行されます。
  • iCanvas クラス内部の OnChartEvent が最初に実行され 、その後、 あなたのコードの OnChartEvent 実行されます

あなたの問題は、OnCalculate がOnChartEvent の 前に実行され、ChartChanged() がまだ実行されていないことが原因です。
だからこそ、再描画ハンドラをOnCalculate 内ではなく、OnChartEvent 内で正確に実装するのが合理的です
。特に、ユーザーがウィンドウのサイズをいつでも変更できるため、そうすべきです。CHARTEVENT_CHART_CHANGE イベントがこのすべての責任を負います。

 
Nikolai Semko:

よくわからなかったのですが、キャンバス全体の中にある長方形のエリアを移動させる必要があるのですか?

そうです。例:全画面のキャンバスの真ん中に円を描いて、その円を左に移動させたい。でも、移動するたびに全領域を削除して円を再描画するのではなく、単純にメモリを左にスクロールさせたい。

CCanvasは単に点のx/y配列である。

   uint              m_pixels[];               // ピクセルの配列
//+------------------------------------------------------------------+
//| ピクセルの色を取得|
//+------------------------------------------------------------------+
uint CCanvas::PixelGet(const int x,const int y) const
  {
//--- 座標のチェック
   if(x>=0 && x<m_width && y>=0 && y<m_height)
      return(m_pixels[y*m_width+x]);
//--- エラー
   return(0);
  }

つまり、m_pixelsを左、右、上、下に移動させる関数が 必要だ。

 
Mighty7:

はい。例:フルスクリーン・キャンバスの真ん中に円を描き、その円を左に移動させたいのですが、移動のたびに全領域を削除して円を塗り直すのではなく、単にメモリを左にスクロールさせたいのです。

CCanvasは単に点のx/y配列である。

つまり、m_pixelsを左、右、上、下に移動させる関数が 必要だ。


しかも、それを実装するのは難しくない。
考えてみたが、共通キャンバスの矩形部分を移動する必要があるなら、もっと簡単な実装方法があるという結論に達した:

  • 新しい小さなキャンバスを作成するのです。この場合、移動する部分の背景を塗りつぶす心配はない。

そう、根拠のある願望だ。
しかも、実装は難しくない。
いろいろ考えたが、共通キャンバスの矩形部分を移動させる必要があるのなら、もっと簡単な方法があるという結論に達した:
  • 新しい、より小さなキャンバスを作るのだ。この場合、移動部分の背景を塗りつぶす心配はない。
 
Nikolai Semko:


さらに言えば、それを実装するのは難しくない。
それについて考えたが、一般的なキャンバスの長方形部分を移動させる必要があるのなら、もっと簡単な実装方法があるという結論に達した:

  • 新しい小さなキャンバスを作成します。この場合、移動する部分の背景を塗りつぶす心配はありません。

そう、根拠のある願望だ。
しかも、実装は難しくない。
いろいろ考えたが、共通キャンバスの矩形部分を移動させる必要があるのなら、もっと簡単な方法があるという結論に達した:
  • 新しい、より小さなキャンバスを作るのだ。この場合、移動部分の背景を塗りつぶす心配はない。

私のキャンバスはフルスクリーンなので、これではうまくいかない。これはティックチャートのようなものですが、背景を完全に消して、すべてを新しく構築してペイントするには時間がかかりすぎるため、コンテンツを左(たとえば8ピクセル)に移動して、新しい8ピクセル(x方向に8ピクセル、高さいっぱい)だけを新しいデータで描画する必要があります。MoveCanvasでキャンバスを左に8ピクセル移動させようとしたところ、うまくいきましたが、左から8ピクセルの幅が削除され、右から8ピクセルが追加されるようにサイズを変更することができません。お分かりいただけたでしょうか?