Automation with button and mouse click interception. - page 11

 
DKeN:
cm=GetDlgItem(hdlg,ID_SYMBOL);
int pos=SendMessageA(cm,CB_GETCOUNT,0,0);//get number in the list
//find the pair
string fs=";
for(int l=0;l<pos;l++){
int ll=SendMessageA(cm,CB_GETLBTEXT,l,fs);
Print(ll," ",fs);
}

please advise how to correctly get a list of tools in the Order window (F9)?

I get the number of elements, but can not get exactly the rows by number, returns -1.

#define ID_SYMBOL 0x053E //character name to select

cmhandle ComboBox

Before you can receive any text, you must first prepare a buffer big enough to receive the text. And your fs line has no length at all. It's strange that your terminal doesn't crash because of this mess. That's why you need to initialize fs beforehand with a long enough string. If we consider general case, when received string length can be any length at all, we should first know this length with CB_GETLBTEXTLEN message to know what buffer size is required.
 
lasso:

Alexey, thanks, the function works, but...


Just the thread ID is needed, because I have two terminals in use.

I got out of it with header identification, but I'd still like to know how to determine the thread ID from under the tester?

The ID of the current thread can be obtained with function GetCurrentProcessId()
 
Meat:
Before receiving any text, you must first prepare a buffer large enough to receive the text........

TEXT!!!

When adapting your function to my needs

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

came across the fact that the string buffer string textbuf, declared locally on the function level, is initialized only once in the first call,

and then behaves as a static variable.

string textbuf="Абвгдежзийклмнопрсту";   // В_ЭТОЙ_СТРОКЕ_255_СИМВОЛОВ
Print("textbuf после инициализации =",textbuf);
Would you care to comment on this situation?
 
lasso:

TEXT!!!

When adapting your function to my needs

came across the fact that the string buffer string textbuf, declared locally on the function level, is initialized only once in the first call,

and then behaves as a static variable.

Could you comment on this situation?

I see what I mean. You mean the buffer stores the old value fetched from GetText. I remember it used to surprise me too. But it is an MQL feature. Somewhere on the forum, the developers said that all constant strings defined at the compiler level are permanently stored in memory in a separate place and are not lost (overwritten) when leaving the function. Their address is initially known and does not change during the program operation. Therefore, when calling the function again, when the same constant string is accessed, it is taken from the same address. But we have a different text there that was placed by the GetText function.
Similarly, you can do just Print("Abvgdezijklmnostu") and get a different text there :) So, it's not about textbuf variable, it's about a constant string. At compile time all constant strings are checked and placed in the database, and only unique strings. If identical strings are detected, only one common database instance is created for them. Consequently, if you mess up this instance while working, all calls to such a string from anywhere in the program will also return a messed up result.

If you don't like it, you can create a buffer programmatically:

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

Then there will be no such problem. I don't remember if it's okay to do that. You won't get a memory access error, though. You should give it a try.

 
Meat:
That way such a problem wouldn't occur. But I don't remember now if it's possible to do it that way. I wonder if a memory access error would occur... Give it a try.

As soon as I read that "255 characters doesn't fit in the screen and ruins the look of the forum", I did so.

But this option didn't work, API function didn't return anything... Therefore I left your variant.

......

Thank you very much anyway, for another thorough reply.

 
lasso:

As soon as I read that "255 characters doesn't fit in the screen and spoils the look of the forum", I did so.

But this option didn't work, API function didn't return anything... That's why I left your variant.

......

Thank you very much anyway, for another thorough reply.


My pleasure.

As far as I understand, the reason is that in this case the reference to the original text buffer belonging to the variable is not passed to the function, but to its copy, i.e. a temporary buffer that is created before the function is called. Accordingly, even if the function changes the text in this buffer, it has no effect, because the original buffer remains unchanged. And the reference to the temporary buffer is lost when the function exits. I once struggled with passing a string into DLL because of this. But there is a solution. You need to pass an element of string array into the function. In this case, no intermediate buffer is created, and the function gets a reference to the original buffer.

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

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

This should work.

 
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;
       }
   }
}

I can get the length normally, but I can't get the text :-(

Please explain how to initialize the string correctly, and in general, is it possible to implement it without external dll ?

it is necessary to find a symbol in the list of tools and select it.


 
DKeN:

I can get the length normally, but I can't get the text :-(

Please explain how to initialize the string correctly, and in general, is it possible to implement it without external dll ?

it is necessary to find a symbol in the list of tools and select it.

About the initialization of the string, I just explained in a previous message to comrade lasso. You either use an element of string array, or simply initialize the string variable with constant of sufficient length. In your case, it's easier to use a constant, because you know in advance that the size of the resulting string won't exceed 78 bytes:

12 bytes (instrument ticker) + 2 bytes (comma and space) + 64 bytes (full instrument name) . This is the maximum possible string length. Well, you can round up to 80.

But if you just want to SELECT a specific instrument in the list, you don't need to get its name. You just have to use CB_SELESTRING message. There as a string parameter you just need to send only the initial part of the name ("EURUSD,") and it will find and select the appropriate item from the list by itself.

 

The Million Dollar Robot API advisor of the near future: It draws a lot of profitable deals in the terminal itself... :) and when in a month or two a new-found millionaire tries to withdraw his profit from the broker, he will find out that there was not a single trade... but the refund period for the advisor is over... :))))))))

 

Guys, please help me identify the handle of the Buy/Sell buttons in the Order box. I have found the handle of the Order box:

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); // хэндл от Ордер-а

Next I try to determine the handle of the button (e.g. Buy), but I get 0 in response.

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

The most interesting thing is that I can't find the handle of any item in theImmediate Execution box. I can't find a handle for the Immediate Execution itself either. Although WinSpy++ sees it as a separate element and shows ID 0xFFFFFF for it.

Please don't judge strictly, I'm a beginner.

Reason: