Librerie: MultiTester - pagina 54

 
hini #:

Il codice controlla solo le lingue russa e inglese

Se qualcuno fornisce il nome del pulsante Start in altre lingue, lo includerò nel codice sorgente.
 
fxsaber #:
Se qualcuno fornisce il nome del pulsante Start in altre lingue, lo includerò nella fonte.
Per il cinese, il testo dei pulsanti Start e Stop è il seguente: "开始" e "停止".
 
hini #:
In cinese, il testo dei pulsanti "Start" e "Stop" è il seguente: "开始" e "停止".
Aggiornato.
 
fxsaber #:
Aggiornato.
Forse è più facile leggere una stringa dal pulsante e poi confrontare se è rimasta la stessa o è cambiata? Ci sono molte lingue, ma il pulsante ha solo due stati.
 
Stanislav Korotky #:
Non sarebbe più semplice leggere una stringa dal pulsante e poi confrontare se è rimasta la stessa o è cambiata?

Dopo tutto, la funzione non dovrebbe dipendere dagli stati precedenti. Sarebbe più semplice usare il colore: verde - avvio, altrimenti - arresto. Ma io faccio tutto in WinAPI con il metodo poke, quindi non so come leggere il colore (componente verde) del pulsante. Se esiste una variante funzionante, ovviamente, la sostituirò.

 
fxsaber #:

Tuttavia, la funzione non dovrebbe dipendere dagli stati precedenti. Sarebbe più semplice utilizzare il colore: verde - avvio, altrimenti - arresto. Ma io faccio tutto in WinAPI con il metodo poke, quindi non so come leggere il colore (componente verde) del pulsante. Se esiste una variante funzionante, ovviamente, la sostituirò.

Questo codice è stato testato da me ed è confermato che funziona.

(Vi consiglio di mantenere entrambi i metodi, forse in futuro gli sviluppatori di MT5 cambieranno i colori).

//+------------------------------------------------------------------+
//|Colore del pulsante di controllo.mq5|
//+------------------------------------------------------------------+
#include <WinAPI/winapi.mqh>

#define private public
#include <fxsaber/MultiTester/MTTester.mqh>
#undef private

#ifdef __MQL5__
#define  ULONG_PTR   ulong
#else
#define  ULONG_PTR   uint
#endif

#define  WORD           int
#define  DWORD_PTR      ULONG_PTR
#define  BYTE           uchar

#define  LOBYTE(w)           ((BYTE)(((DWORD_PTR)(w)) & 0xff))
#define  GetRValue(rgb)      (LOBYTE(rgb))
#define  GetGValue(rgb)      (LOBYTE(((WORD)(rgb)) >> 8))
#define  GetBValue(rgb)      (LOBYTE((rgb)>>16))
//+------------------------------------------------------------------+
//| Ottenere l'handle del pulsante "Start|
//+------------------------------------------------------------------+
long GetStartBtnHandle(void) {
  static const int ControlID[] = {0xE81E, 0x804E, 0x2712, 0x4196};
  static const long Handle = MTTESTER::GetHandle(ControlID);
  if(Handle <= 0) return 0;
  return Handle;
}

//+------------------------------------------------------------------+
//| Funzione generica di rilevamento del colore: verifica se il pulsante è specifico |
//| la posizione corrisponde al colore RGB preimpostato |
//+------------------------------------------------------------------+
bool IsButtonBackgroundColor(HWND hButton, color targetClr) {
  if(!hButton || !user32::IsWindow(hButton)) return false;
  // 1. Ottenere la posizione del pulsante sullo schermo
  RECT rect;
  user32::GetWindowRect(hButton, rect);
  // 2. Punto di campionamento: 20 pixel dal bordo sinistro, centro verticale (evitare il testo)
  int targetX = rect.left + 20;
  int targetY = rect.top + (rect.bottom - rect.top) / 2;
  // 3. Campionamento dello schermo
  HANDLE hdcScreen = user32::GetDC(NULL);
  uint clr = gdi32::GetPixel(hdcScreen, targetX, targetY);
  user32::ReleaseDC(NULL, hdcScreen);
  if(clr == 0xFFFFFFFF) return false;
  return targetClr == clr;
}
//+------------------------------------------------------------------+
//| Punto di ingresso dello script OnStart|
//+------------------------------------------------------------------+
void OnStart() {
  HWND hBtn = (HWND)GetStartBtnHandle();
  if(hBtn == 0) return;
  // --- Chiamate flessibili in base alle esigenze dell'utente ---
  // Verifica per: tema chiaro verde (156, 204, 101) hover:140, 188, 85
  bool isLightGreen = IsButtonBackgroundColor(hBtn, C'156, 204, 101') || 
                      IsButtonBackgroundColor(hBtn, C'140, 188, 85');
  
  // Verifica per: Tema scuro verde (96, 96, 0) hover:80, 80, 0
  bool isDarkGreen = IsButtonBackgroundColor(hBtn, C'96, 96, 0') || 
                     IsButtonBackgroundColor(hBtn, C'80, 80, 0');
  
  // Verifica per: Tema chiaro rosso (239, 154, 154) hover:223, 138, 138
  bool isLightRed = IsButtonBackgroundColor(hBtn, C'239, 154, 154') || 
                    IsButtonBackgroundColor(hBtn, C'223, 138, 138');
  
  // Controllo per: tema scuro rosso (112, 14, 19) hover:128, 30, 35
  bool isDarkRed = IsButtonBackgroundColor(hBtn, C'112, 14, 19') || 
                   IsButtonBackgroundColor(hBtn, C'128, 30, 35');
  // Logica aziendale
  if(isLightGreen || isDarkGreen) {
    Print("Current button state: Green (Ready to start)");
  } else if(isLightRed || isDarkRed) {
    Print("Current button state: Red (Running/Stopped)");
  } else {
    Print("Current button state: Other color/Unknown");
  }
}
//+------------------------------------------------------------------+
 
fxsaber #:

Tuttavia, la funzione non dovrebbe dipendere dagli stati precedenti. Sarebbe più semplice utilizzare il colore: verde - avvio, altrimenti - arresto. Ma io faccio tutto in WinAPI con il metodo poke, quindi non so come leggere il colore (componente verde) del pulsante. Se esiste una variante funzionante, ovviamente, la sostituirò.

Probabilmente non è più semplice leggere il colore del pulsante, ma lo stato dell'elenco degli ingressi (abilitato/disabilitato).
 
Stanislav Korotky #:
Probabilmente è più facile non in base al colore del pulsante, ma in base allo stato dell'elenco Ingressi: abilitato/disabilitato.
Dove trovare lo stato degli ingressi? Non esiste un'API ufficiale, dobbiamo determinarlo in base ai colori e al testo.
 
hini #:
Dove trovare lo stato degli ingressi? Non esiste un'API ufficiale, dobbiamo determinarlo in base ai colori e al testo.

Beh, non esiste un'API ufficiale per tutti gli interni della MT5: bisogna ispezionarli attraverso utility come MS Spy - è così che sono stati trovati gli identificatori di controllo, che ora sono utilizzati nel multitester.

Se non ci si addentra nei meandri di Inputs e si utilizza semplicemente il pulsante di avvio già testato, sembra che la chiamata GetWindowLongW(hwnd, 0) debba restituire il colore corrente del pulsante. Il mio restituisce 0xD0B1DF10 per quello verde. Solo se MQ decide di correggere lo stile, questa impostazione potrebbe scomparire. Quindi il controllo dell'attività degli ingressi è comunque più affidabile.

 
Stanislav Korotky #:

sembra che la chiamata GetWindowLongW(hwnd, 0) debba restituire il colore corrente del pulsante. Ottengo 0xD0B1DF10 per quello verde.

GetPixel sembra restituire un colore G diverso.