ボタンやマウスクリックの傍受による自動化。 - ページ 11

 
DKeN:
cm=GetDlgItem(hdlg,ID_SYMBOL)とする。
int pos=SendMessageA(cm,CB_GETCOUNT,0,0);// リストの番号を取得します。
//ペアを探す
string fs=";
for(int l=0;l<pos;l++){
int ll=SendMessageA(cm,CB_GETLBTEXT,l,fs)。
Print(ll," ",fs);
}

オーダーウィンドウ(F9)でツールのリストを正しく取得する方法を教えてください。

要素数は取得できますが、行数を正確に取得できず、-1が返されます。

#define ID_SYMBOL 0x053E //選択する文字列の名前

cmhandle コンボボックス

テキストを受信する前に、まずテキストを受信するのに十分な大きさのバッファを準備する必要があります。そして、あなたのfsラインには長さが全くありません。この混乱で端末がクラッシュしないのは不思議です。そのため、あらかじめ十分な長さの文字列で fsを初期化する必要があるのです。一般的なケースを考えると、受信した文字列の長さがどのようなものであっても、まず CB_GETLBTEXTLEN メッセージでその長さを知り、どの程度のバッファサイズが必要かを知る必要があります。
 
lasso:

Alexeyさん、ありがとうございます。この機能は動作しますが...


2つの端子を使用しているので、スレッドIDだけは必要です。

ヘッダー判別で抜けましたが、やはりテスターの下からスレッドIDを判別する方法が知りたいのですが?

現在のスレッドのIDは、関数GetCurrentProcessId()で取得することができます。
 
Meat:
テキストを受信する前に、まずテキストを受信するのに十分な大きさのバッファを準備する必要があります。......

TEXT!!!

私のニーズに合わせて機能を調整する場合

int FindWindow(string class, string caption, bool captionexactly=false)

は、関数レベルでローカルに宣言された文字列バッファ文字列textbufが、最初の呼び出しで一度だけ初期化されるという事実に出くわしました。

で、スタティック変数として 振る舞います。

string textbuf="Абвгдежзийклмнопрсту";   // В_ЭТОЙ_СТРОКЕ_255_СИМВОЛОВ
Print("textbuf после инициализации =",textbuf);
この状況について、コメントをお願いします。
 
lasso:

TEXT!!!

私のニーズに合わせて機能を調整する場合

は、関数レベルでローカルに宣言された文字列バッファ文字列textbufが、最初の呼び出しで一度だけ初期化されるという事実に出くわしました。

で、スタティック変数として振る舞います。

この状況について、コメントをお願いします。

なるほど、そういうことだったんですね。GetTextから取得した古い値をバッファに格納するということですね。私も昔はびっくりしたのを覚えています。しかし、それはMQLの機能である。フォーラムのどこかで、開発者が「コンパイラレベルで定義された定数文字列は すべてメモリ上の別の場所に永久に保存され、関数を離れると失われる(上書きされる)ことはない」と言っていました。そのアドレスは初期状態で既知であり、プログラム動作中に変更されることはない。そのため、再度関数を呼び出すと、同じ定数文字列がアクセスされた場合、同じアドレスから取得される。しかし、そこにはGetText関数で配置された別のテキストがあるのです。
同様に、Print("Abvgdezijklmnostu")を実行するだけで、別のテキストを取得することができます :)つまり、textbuf変数ではなく、定数文字列のことです。コンパイル時にすべての定数文字列をチェックし、一意な文字列のみをデータベースに登録します。同一の文字列が検出された場合、それらの文字列に対して1つの共通のデータベースインスタンスのみが作成されます。その結果、作業中にこのインスタンスを混乱させると、プログラムのどこからでもこのような文字列を呼び出すと、混乱した結果も返されることになります。

それが嫌なら、プログラム的にバッファを作ればいい。

string textbuf="";
for (int i=0; i<255; i++)
  textbuf=textbuf+" ";

そうすれば、そのような問題は起きないでしょう。そんなことしていいのか、覚えてないんだけど。メモリーアクセスエラーは出ませんけどね。ぜひ試してみてください。

 
Meat:
そうすれば、そのような問題は起きないでしょう。でも、そんなやり方が可能かどうか、今は覚えていないんです。メモリーアクセスエラーが出ないかなぁ...。試してみてください。

255文字だと画面に収まらず、掲示板の見栄えが損なわ れる」というのを読んですぐに そうしました。

しかし、このオプションはうまくいかず、API関数は何も返しませんでした...。だから、私はあなたの変種から離れました。

......

とにかく、今回も丁寧なご回答をいただき、本当にありがとうございました。

 
lasso:

255文字だと画面に収まらず、掲示板の見栄えが損 なわれる」というのを読んですぐに、そうしました。

しかし、このオプションはうまくいかず、API関数は何も返しませんでした...。だから、私はあなたの亜種を残したのです。

......

とにかく、今回も丁寧なご回答をいただき、本当にありがとうございました。


よろしくお願いします。

私の理解では、この場合、変数に属する元のテキストバッファへの参照は関数に渡されず、そのコピー、つまり関数が呼ばれる 前に作成される一時的なバッファに渡されるからだと思います。したがって、この関数がこのバッファのテキストを変更しても、元のバッファは変更されないので、何の影響もない。また、一時的なバッファへの参照は、関数が終了するときに失われます。このため、DLLに文字列を渡すのに苦労したことがあります。しかし、解決策はある。関数には、文字列配列の要素を 渡す必要があります。この場合、中間バッファは作成されず、関数は元のバッファへの参照を取得します。

string buffer[1]={""};
for (int i=0; i<500; i++)
  buffer[0]=buffer[0]+" ";

GetWindowTextA(h,buffer[0],500);

これでうまくいくはずです。

 
void SetSymbol(int hdlg,string symbol,int len){
   int cm=GetDlgItem(hdlg,ID_SYMBOL);
   int pos=SendMessageA(cm,CB_GETCOUNT,0,0);//получим количество в списке
   string fs,ff;
   
   for(int l=0;l<pos;l++){
       //SendMessageA(cm,CB_SETCURSEL,l,0);
       int len_text=SendMessageA(cm,CB_GETLBTEXTLEN,l,0);
       fs=" ";
       for(int m=0;m<len_text+1;m++) fs=StringConcatenate(fs," ");
       int ll=SendMessageA(cm,CB_GETLBTEXT,l,fs);
       Print(len_text," = ",fs); //пусто!!! длину получает.

          
       ff=StringSubstr(fs,0,len);
      // Print(symbol);
       if(ff==symbol) {
            SendMessageA(cm,CB_SETCURSEL,l,0);
            break;
       }
   }
}

長さは正常に取得できるのですが、テキストが取得できません :-(

文字列を 正しく初期化 する方法と、一般的に外部DLLを使わずに実装することが可能かどうかを教えてください。

の場合は、ツールの一覧からシンボルを探して選択する必要があります。


 
DKeN:

長さは正常に取得できるのですが、テキストが取得できません :-(

文字列を正しく初期化する方法と、一般的に外部DLLを使わずに実装することが可能かどうかを教えてください。

は、ツールの一覧からシンボルを見つけて選択することです。

文字列の初期化については、以前、lasso 同志へのメッセージで説明したところです。文字列配列の要素を使うか、十分な長さの定数で文字列変数を初期化するだけです。あなたの場合、定数を使う方が簡単です。なぜなら、結果の文字列のサイズが78バイトを超えないことがあらかじめ分かっているからです。

12 バイト(商品ティッカー)+2 バイト(カンマとスペース)+64 バイト(商品名) .これは、可能な限りの最大文字列長である。まあ、四捨五入して80でもいいんですけどね。

しかし、リスト中の特定の楽器をSELECTするだけなら、その名前を取得する必要はありません。CB_SELESTRINGメッセージを使用すればよいのです。文字列のパラメータとして、名前の最初の部分("EURUSD,")だけを送れば、それだけでリストから適切な項目を検索して選択することができます。

 

近未来の100万ドルロボットAPIアドバイザー。 端末自体に収益性の高い案件が多く集まるので...。そして、1ヶ月か2ヶ月後、新参の大富豪がブローカーから利益を引き出そうとしたとき、一度も取引がなかったことに気づくだろう...」と。が、アドバイザーの返金期間は終了している...。:))))))))

 

皆さん、オーダーボックスのBuy/Sellボタンのハンドルを特定するのを手伝ってください。オーダーボックスの取っ手が見つかりました。

int chart_handle = WindowHandle(Symbol(), Period());
int MT_handle = GetAncestor(chart_handle, GA_ROOT); // GA_ROOT 2
PostMessageA(MT_handle, WM_KEYDOWN, VK_F9, 0); // открываем окошко Ордер
Sleep(1000); // Wait. This is important!
int Order_handle = GetLastActivePopup(MT_handle); // хэндл от Ордер-а

次に、ボタンのハンドル(例:Buy)を決定しようとしますが、応答が0になります。

int Buy_handle = GetDlgItem(Order_handle, 0x40C); // 0x40C найдено с помощью WinSpy++

一番気になるのは、即時実行の ボックスにどの項目のハンドルも見当たらないことです。Immediate Execution自体のハンドルも見当たりません。しかし、WinSpy++はこれを別の要素として認識し、そのIDを0xFFFFFFと表示します。

初心者なので、厳しく判断しないでください。