ライブラリ: EasyAndFastGUIグラフィックインターフェース作成ライブラリ - ページ 8

 

ExampleEAF.mq5をコンパイルするとうまくいった。

ライブラリを使って独自のものを作りたいときは、ライブラリをコンパイルしなければならないと思い込んでいた。

でも、本当にありがとう!

それと、ほとんどのライブラリファイルの一番上にあるこのコードの行でつまずきました:

class CWindow;

偽のクラス」の作成は、#includeの悪夢を避けるためのトリックなのでしょうか?後でコンパイラは、実際に使われている正しいクラスをどうやってリンクするのでしょうか?

 

まず、今あるものを最終確認したいのですが...。結局のところ、まだ多くの欠陥がある。

アーキテクチャについていくつか指摘があります。 指定されたオブジェクトのプロパティと 表示された画像は、互いに独立して独自の生活を送っています。 そして、Update()の呼び出しが必須 です。そうでなければ、並行した現実のままになってしまいます。イベント・ベースのモデル であることを考えると、これは間違っていると思います。手動更新(再描画)は前提条件であるべきではなく、変更を即座に表示できるようにするだけで、とにかくすべての変更が表示されるべきなのだ。 そのためには、このオブジェクトを再描画するためのメッセージ(イベント)を送るべきで、それは後で処理される。

つまり、だいたいこんな感じだ:

class CSomeControl
{
  int  m_property;
  bool m_changed;
  bool m_event_sent;
 public:
  void Property(int value)  { m_property= value;  m_changed=true;  if (!m_event_sent) m_event_sent= EventChartCustom(m_chart_id, ON_CHANGE, m_id, 0, 0); }  

  void Update()             { /*...再描画...*/.  m_changed=false; }

  void OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {  
    if (id==CHARTEVENT_CUSTOM+ON_CHANGE) { m_event_sent=false;  if (m_changed) Update(); }
  }                       
};
 

ChangeWindowWidthを使って、ウィンドウの幅を現在のチャートの外に出るように変更しました。 その後、このウィンドウを移動させようとすると、自動的にチャートの左端にくっついてしまいます。 これを無効にするにはどうしたらよいでしょうか? コード内に場所が見つかりません。

 
Alexey Navoykov:

ChangeWindowWidthを使って、ウィンドウの幅を現在のチャートの外に出るように変更しました。 その後、このウィンドウを動かそうとすると、自動的にチャートの左端にくっついてしまいます。 これを無効にするにはどうしたらよいでしょうか? コードに場所が見当たりません。

CWindow::UpdateWindowXY()メソッドを書き直す必要があります。現在のところ、ウィンドウを移動してもウィンドウの端がチャートの外に出ないように実装されています。

 

ところで、ウィンドウ幅の変更について

   m_window1.ChangeWindowWidth(NEW_WIDTH);
   m_window1.Update(true);

MT5では問題ないのですが、MT4ではこのようになっています。

ヘッダーをクリックすると、ボタンが適切な場所に移動します。どっちを見ればいいのか教えてください。ボタンの移動はどこに実装されているのでしょうか?

 
Oleksii Chepurnyi:

ところで、ウィンドウの幅の変更についてだが

MT5では問題ないのですが、MT4では以下のようになっています。

ヘッダーをクリックすると、ボタンが適切な場所に移動します。どっちを見ればいいのか教えてください。これらのボタンの移動はどこに実装されていますか?

Moving()メソッドを見てください。

ポインターを介してウィンドウ・ボタンにアクセスし、このメソッドを呼び出してみてください。

 
Alexey Navoykov:

すべての列の幅を比例して大きくするか、最後の列だけを大きくする必要がある。 後者が望ましい。

というのも、あなたのクラスには現在の列幅を取得するメソッドが見つからず、すべてのフィールドがprivateだからです。 一般的には、少なくともこのメソッドは追加されるべきです。

このようにして、あなたが今必要としているものを実装してみてください:

//--- ウィンドウのサイズ変更イベント
   if(id==CHARTEVENT_CUSTOM+ON_WINDOW_CHANGE_YSIZE)
     {
      //--- サマリーテーブルのカラムの幅を調整する。
      if(m_table_symbols.RowsTotal()>(uint)m_table_symbols.VisibleRowsTotal())
        {
         int width[]={79};
         m_table_symbols.ColumnsWidth(width);
        }
      else
        {
         int width[]={95};
         m_table_symbols.ColumnsWidth(width);
        }
      //---
      m_table_symbols.Update(true);
      m_table_symbols.GetScrollVPointer().CurrentPos(0);
      m_table_symbols.GetScrollVPointer().Update(true);
      return;
     }
 
Anatoli Kazharski:

Moving()メソッドを見てください。

ポインターを介してウィンドウ・ボタンにアクセスし、このメソッドを呼び出してみてください。

はい、これで終わりです :)ありがとう!

もう全部目を通したつもりだったのに、一番わかりやすいところを見逃していたよ :)

 
Anatoli Kazharski:

そうやって、今自分に必要なものを実現しようとするのだ:

これは固定された列の幅だが、我々は以前の幅に基づいて列の幅を動的に変更することについて話していた。 しかし、私はすでにそこにint ColumnWidth(int i)メソッドを追加することによってクラスを完成させた。

 

こんにちは。

問題はもっと大きいです。)

動的なオブジェクト、例えばラベルを作成します。

   labels[i] = new CTextLabel;
   labels[i].MainPointer(m_window1);
   labels[i].XSize(SYMBOLS_COL_WIDTH);
   labels[i].YSize(HEAD_HIGHT);
   labels[i].Alpha(SYMBOLS_HEAD_BACK_ALPHA);
   labels[i].FontSize(SYMBOLS_HEAD_FONT_SIZE);
   labels[i].TextAlign(SYMBOLS_HEAD_TEXT_ALIGN,HORIZONTAL_SPACE,0);
   labels[i].FontStyle(SYMBOLS_HEAD_FONT_STYLE);
   labels[i].BackColor(SYMBOLS_HEAD_BACK_COLOR);
   labels[i].CreateTextLabel("0",x_gap,ProfitHeadGap);
   CWndContainer::AddToElementsArray(0,labels[i]);
   labels[i].Update(true);

しかし、どのように削除するのですか?

私はこの方法で削除します。

      labels[i].Delete();
      delete labels[i];

しかし、削除した後、クラッシュします。ポインタへのアクセスが正しくないというのです。

私が理解した限りでは、CWndContainer::AddToElementsArrayは オブジェクトを共通配列に追加しますが、Delete()はそこから削除せず、ウィンドウはオブジェクトにアクセスしようとします。Delete()に似たようなものは他に見当たりません。

オブジェクトを正しく削除するには?