Automatización con interceptación de botones y clics del ratón. - página 11

 
DKeN:
cm=GetDlgItem(hdlg,ID_SYMBOL);
int pos=EnviarMensajeA(cm,CB_GETCOUNT,0,0);//obtener el número de la lista
//encontrar el par
cadena fs=";
for(int l=0;l<pos;l++){
int ll=EnviarMensajeA(cm,CB_GETLBTEXT,l,fs);
Print(ll," ",fs);
}

Por favor, indíqueme cómo obtener correctamente una lista de herramientas en la ventana de pedidos (F9).

Obtengo el número de elementos, pero no puedo obtener exactamente las filas por número, devuelve -1.

#define ID_SYMBOL 0x053E //nombre del carácter a seleccionar

cmhandle ComboBox

Antes de poder recibir cualquier texto, debes preparar un búfer lo suficientemente grande como para recibir el texto. Y tu línea fs no tiene ninguna longitud. Es extraño que tu terminal no se cuelgue por este lío. Por eso hay que inicializar fs de antemano con una cadena suficientemente larga. Si consideramos el caso general, cuando la longitud de la cadena recibida puede ser cualquier longitud, deberíamos conocer primero esta longitud con el mensaje CB_GETLBTEXTLEN para saber qué tamaño de búfer se necesita.
 
lasso:

Alexey, gracias, la función funciona, pero...


Sólo se necesita la identificación del hilo, porque tengo dos terminales en uso.

Me he librado con la identificación de la cabecera, pero todavía me gustaría saber cómo determinar el ID del hilo de debajo del probador?

El ID del hilo actual se puede obtener con la función GetCurrentProcessId()
 
Meat:
Antes de recibir cualquier texto, debe preparar un búfer lo suficientemente grande para recibir el texto........

¡¡¡TEXTO!!!

Al adaptar su función a mis necesidades

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

se encontró con el hecho de que el buffer de cadena textbuf, declarado localmente en el nivel de la función, se inicializa sólo una vez en la primera llamada,

y se comporta como una variable estática.

string textbuf="Абвгдежзийклмнопрсту";   // В_ЭТОЙ_СТРОКЕ_255_СИМВОЛОВ
Print("textbuf после инициализации =",textbuf);
¿Quiere comentar esta situación?
 
lasso:

¡¡¡TEXTO!!!

Al adaptar su función a mis necesidades

se encontró con el hecho de que el buffer de cadena textbuf, declarado localmente en el nivel de la función, se inicializa sólo una vez en la primera llamada,

y se comporta como una variable estática.

¿Podría comentar esta situación?

Ya veo lo que quiero decir. Quieres decir que el buffer almacena el valor antiguo obtenido de GetText. Recuerdo que a mí también me sorprendía. Pero es una característica de MQL. En algún lugar del foro, los desarrolladores dijeron que todas las cadenas constantes definidas a nivel del compilador se almacenan permanentemente en la memoria en un lugar separado y no se pierden (se sobrescriben) al salir de la función. Su dirección es inicialmente conocida y no cambia durante la operación del programa. Por lo tanto, al llamar de nuevo a la función, cuando se accede a la misma cadena constante, se toma de la misma dirección. Pero tenemos un texto diferente allí que fue colocado por la función GetText.
Del mismo modo, usted puede hacer sólo Print("Abvgdezijklmnostu") y obtener un texto diferente allí :) Por lo tanto, no se trata de la variable textbuf, sino de una cadena constante. En tiempo de compilación se comprueban todas las cadenas constantes y se colocan en la base de datos, y sólo las cadenas únicas. Si se detectan cadenas idénticas, sólo se crea una instancia de base de datos común para ellas. En consecuencia, si se estropea esta instancia mientras se trabaja, todas las llamadas a dicha cadena desde cualquier parte del programa también devolverán un resultado estropeado.

Si no te gusta, puedes crear un buffer de forma programada:

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

Entonces no habrá ese problema. No recuerdo si está bien hacer eso. Sin embargo, no obtendrá un error de acceso a la memoria. Deberías probarlo.

 
Meat:
Así no se produciría ese problema. Pero ahora no recuerdo si es posible hacerlo así. Me pregunto si no habrá un error de acceso a la memoria... Pruébalo.

En cuanto leí que "255 caracteres no caben en la pantalla y arruinan el aspecto del foro", lo hice.

Pero esta opción no funcionó, la función API no devolvió nada... Por lo tanto, dejé su variante.

......

Muchas gracias de todos modos, por otra respuesta exhaustiva.

 
lasso:

En cuanto leí que "255 caracteres no caben en la pantalla y estropean el aspecto del foro", lo hice.

Pero esta opción no funcionó, la función API no devolvió nada... Por eso dejé tu variante.

......

De todas formas, muchas gracias por otra respuesta tan completa.


Es un placer.

Según tengo entendido, la razón es que en este caso la referencia al buffer de texto original perteneciente a la variable no se pasa a la función, sino a su copia, es decir, a un buffer temporal que se crea antes de llamar a la función. Por lo tanto, aunque la función cambie el texto de este búfer, no tiene ningún efecto, ya que el búfer original permanece inalterado. Y la referencia al buffer temporal se pierde cuando la función sale. Una vez tuve problemas para pasar una cadena a la DLL debido a esto. Pero hay una solución. Es necesario pasar un elemento de la matriz de cadenas a la función. En este caso, no se crea ningún búfer intermedio, y la función obtiene una referencia al búfer original.

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

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

Esto debería funcionar.

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

Puedo obtener la longitud normalmente, pero no puedo obtener el texto :-(

Por favor, explique cómo inicializar la cadena correctamente, y en general, ¿es posible implementarlo sin dll externa?

es necesario encontrar un símbolo en la lista de herramientas y seleccionarlo.


 
DKeN:

Puedo obtener la longitud normalmente, pero no puedo obtener el texto :-(

Por favor, explique cómo inicializar la cadena correctamente, y en general, ¿es posible implementarlo sin dll externa?

es necesario encontrar un símbolo en la lista de herramientas y seleccionarlo.

Sobre la inicialización de la cadena, lo acabo de explicar en un mensaje anterior al compañero lasso. Puede utilizar un elemento de la matriz de cadenas, o simplemente inicializar la variable de cadena con una constante de longitud suficiente. En tu caso, es más fácil utilizar una constante, porque sabes de antemano que el tamaño de la cadena resultante no superará los 78 bytes:

12 bytes (ticker del instrumento) + 2 bytes (coma y espacio) + 64 bytes (nombre completo del instrumento) . Esta es la máxima longitud de cadena posible. Bueno, puedes redondear a 80.

Pero si sólo quieres SELECCIONAR un instrumento específico de la lista, no necesitas obtener su nombre. Sólo tiene que utilizar el mensaje CB_SELESTRING. Allí, como parámetro de cadena, sólo hay que enviar la parte inicial del nombre ("EURUSD,") y encontrará y seleccionará el elemento apropiado de la lista por sí mismo.

 

El asesor de la API del Robot del Millón de Dólares del futuro próximo: Atrae muchos tratos rentables en la propia terminal... :) y cuando dentro de uno o dos meses un millonario recién llegado intente retirar sus ganancias del broker, descubrirá que no hubo ni una sola operación... pero el período de reembolso para el asesor ha terminado... :))))))))

 

Chicos, por favor ayúdenme a identificar el mango de los botones de compra/venta en la caja de pedidos. He encontrado el asa de la caja de pedidos:

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

A continuación, intento determinar la manija del botón (por ejemplo, Comprar), pero obtengo 0 como respuesta.

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

Lo más interesante es que no encuentro la manija de ningún elemento en el cuadro deEjecución Inmediata. Tampoco encuentro un asidero para la propia Ejecución Inmediata. Aunque WinSpy++ lo ve como un elemento separado y muestra el ID 0xFFFFFF para él.

Por favor, no juzguen estrictamente, soy un principiante.