Automazione con intercettazione di pulsanti e clic del mouse. - pagina 11

 
DKeN:
cm=GetDlgItem(hdlg,ID_SYMBOL);
int pos=InviareMessaggioA(cm,CB_GETCOUNT,0,0);//ottenere il numero nella lista
/trovare la coppia
stringa fs=";
for(int l=0;l<pos;l++){
int ll=SendMessageA(cm,CB_GETLBTEXT,l,fs);
Stampa (ll," ", fs);
}

come ottenere correttamente un elenco di strumenti nella finestra dell'ordine (F9)?

Ottengo il numero di elementi, ma non posso ottenere esattamente le righe per numero, restituisce -1.

#define ID_SYMBOL 0x053E //nome del carattere da selezionare

cmhandle ComboBox

Prima di poter ricevere qualsiasi testo, dovete prima preparare un buffer abbastanza grande per ricevere il testo. E la tua linea fs non ha alcuna lunghezza. È strano che il tuo terminale non vada in crash a causa di questo casino. Ecco perché è necessario inizializzare fs in anticipo con una stringa abbastanza lunga. Se consideriamo il caso generale, quando la lunghezza della stringa ricevuta può essere di qualsiasi lunghezza, dovremmo prima conoscere questa lunghezza con il messaggio CB_GETLBTEXTLEN per sapere quale dimensione del buffer è richiesta.
 
lasso:

Alexey, grazie, la funzione funziona, ma...


Solo l'ID del filo è necessario, perché ho due terminali in uso.

Ne sono uscito con l'identificazione dell'intestazione, ma vorrei ancora sapere come determinare l'ID del filo da sotto il tester?

L'ID del thread corrente può essere ottenuto con la funzione GetCurrentProcessId()
 
Meat:
Prima di ricevere qualsiasi testo, è necessario preparare un buffer abbastanza grande per ricevere il testo........

TESTO!!!

Quando si adatta la vostra funzione alle mie esigenze

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

si è imbattuto nel fatto che il buffer di stringhe textbuf, dichiarato localmente a livello di funzione, viene inizializzato solo una volta nella prima chiamata,

e poi si comporta come una variabile statica.

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

TESTO!!!

Quando si adatta la vostra funzione alle mie esigenze

si è imbattuto nel fatto che il buffer di stringhe textbuf, dichiarato localmente a livello di funzione, viene inizializzato solo una volta nella prima chiamata,

e poi si comporta come una variabile statica.

Potrebbe commentare questa situazione?

Ho capito cosa voglio dire. Vuoi dire che il buffer memorizza il vecchio valore recuperato da GetText. Ricordo che una volta sorprendeva anche me. Ma è una funzione MQL. Da qualche parte sul forum, gli sviluppatori hanno detto che tutte le stringhe costanti definite a livello di compilatore sono memorizzate in modo permanente nella memoria in un luogo separato e non vengono perse (sovrascritte) quando si lascia la funzione. Il loro indirizzo è inizialmente noto e non cambia durante l'operazione di programma. Pertanto, quando si richiama la funzione, quando si accede alla stessa stringa costante, questa viene presa dallo stesso indirizzo. Ma abbiamo un testo diverso che è stato inserito dalla funzione GetText.
Allo stesso modo, potete fare solo Print("Abvgdezijklmnostu") e ottenere un testo diverso :) Quindi, non si tratta di una variabile textbuf, ma di una stringa costante. Al momento della compilazione tutte le stringhe costanti sono controllate e messe nel database, e solo le stringhe uniche. Se vengono rilevate stringhe identiche, viene creata solo un'istanza di database comune per loro. Di conseguenza, se si incasina questa istanza mentre si lavora, tutte le chiamate a tale stringa da qualsiasi parte del programma restituiranno anche un risultato incasinato.

Se non ti piace, puoi creare un buffer programmaticamente:

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

Allora non ci sarà questo problema. Non ricordo se va bene farlo. Non otterrete però un errore di accesso alla memoria. Dovresti fare una prova.

 
Meat:
In questo modo un tale problema non si verificherebbe. Ma ora non ricordo se è possibile farlo in questo modo. Mi chiedo se non ci sarà un errore di accesso alla memoria... Fate una prova.

Appena ho letto che "255 caratteri non entrano nello schermo e rovinano l'aspetto del forum", l'ho fatto.

Ma questa opzione non ha funzionato, la funzione API non ha restituito nulla... Perciò ho lasciato la vostra variante.

......

Grazie mille comunque, per un'altra risposta esauriente.

 
lasso:

Appena ho letto che "255 caratteri non entrano nello schermo e rovinano l'aspetto del forum", l'ho fatto.

Ma questa opzione non ha funzionato, la funzione API non ha restituito nulla... Ecco perché ho lasciato la vostra variante.

......

Grazie mille comunque, per un'altra risposta esauriente.


Piacere mio.

Per quanto ho capito, la ragione è che in questo caso il riferimento al buffer di testo originale appartenente alla variabile non viene passato alla funzione, ma alla sua copia, cioè un buffer temporaneo che viene creato prima che la funzione venga chiamata. Di conseguenza, anche se la funzione cambia il testo in questo buffer, non ha effetto, perché il buffer originale rimane invariato. E il riferimento al buffer temporaneo viene perso quando la funzione esce. Una volta ho lottato con il passaggio di una stringa nella DLL a causa di questo. Ma c'è una soluzione. Dovete passare un elemento dell'array di stringhe nella funzione. In questo caso, non viene creato alcun buffer intermedio, e la funzione ottiene un riferimento al buffer originale.

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

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

Questo dovrebbe funzionare.

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

Posso ottenere la lunghezza normalmente, ma non posso ottenere il testo :-(

Per favore, spiegate come inizializzare correttamente la stringa, e in generale, è possibile implementarla senza dll esterne?

è necessario trovare un simbolo nella lista degli strumenti e selezionarlo.


 
DKeN:

Posso ottenere la lunghezza normalmente, ma non posso ottenere il testo :-(

Per favore, spiegate come inizializzare correttamente la stringa, e in generale, è possibile implementarla senza dll esterne?

è necessario trovare un simbolo nella lista degli strumenti e selezionarlo.

Riguardo all'inizializzazione della stringa, l'ho appena spiegato in un messaggio precedente al compagno lasso. Si può usare un elemento dell'array di stringhe, o semplicemente inizializzare la variabile stringa con una costante di lunghezza sufficiente. Nel tuo caso, è più facile usare una costante, perché sai in anticipo che la dimensione della stringa risultante non supererà i 78 byte:

12 byte (ticker dello strumento) + 2 byte (virgola e spazio) + 64 byte (nome completo dello strumento) . Questa è la lunghezza massima possibile della stringa. Beh, puoi arrotondare a 80.

Ma se vuoi solo SELEZIONARE uno strumento specifico nella lista, non hai bisogno di ottenere il suo nome. Dovete solo usare il messaggio CB_SELESTRING. Lì come parametro stringa basta inviare solo la parte iniziale del nome ("EURUSD,") e troverà e selezionerà da solo l'elemento appropriato dalla lista.

 

Il consulente API Million Dollar Robot del prossimo futuro: Attira un sacco di affari redditizi nel terminale stesso... :) e quando tra un mese o due un milionario ritrovato cercherà di ritirare il suo profitto dal broker, scoprirà che non c'era un solo trade... ma il periodo di rimborso per il consulente è finito... :))))))))

 

Ragazzi, per favore aiutatemi a identificare la maniglia dei pulsanti Compra/Vendi nella casella dell'ordine. Ho trovato la maniglia della scatola dell'ordine:

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

Poi cerco di determinare l'handle del pulsante (ad esempio Buy), ma ottengo 0 in risposta.

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

La cosa più interessante è che non riesco a trovare l'handle di nessun elemento nella casellaEsecuzione immediata. Non riesco nemmeno a trovare una maniglia per l'esecuzione immediata stessa. Anche se WinSpy++ lo vede come un elemento separato e mostra l'ID 0xFFFFFF per esso.

Per favore, non giudicate severamente, sono un principiante.