Librerías: MultiTester - página 54

 
hini #:

El código sólo comprueba los idiomas ruso e inglés

Si alguien da el nombre del botón Inicio en otros idiomas, lo incluiré en el código fuente.
 
fxsaber #:
Si alguien da el nombre del botón Inicio en otros idiomas, lo incluiré en la fuente.
En chino, el texto de los botones Inicio y Parar es el siguiente: "开始" y "停止".
 
hini #:
En chino, el texto de los botones "Iniciar" y "Detener" es el siguiente: "开始" y "停止".
Actualizado.
 
fxsaber #:
Actualizado.
¿Quizá sea más fácil leer una cadena del botón y luego comparar si sigue igual o ha cambiado? Hay muchos idiomas, pero el botón sólo tiene dos estados.
 
Stanislav Korotky #:
¿No sería más fácil leer una cadena del botón y luego comparar si sigue igual o ha cambiado?

Al fin y al cabo, la función no debería depender de estados anteriores. Sería más fácil utilizar el color: verde - inicio, de lo contrario - parada. Pero yo hago todo en WinAPI por el método poke, así que no sé cómo leer el color (componente verde) del botón. Si hay una variante de trabajo, por supuesto, voy a reemplazarlo.

 
fxsaber #:

Aun así, la función no debería depender de los estados anteriores. Sería más fácil utilizar el color: verde - inicio, de lo contrario - parada. Pero yo hago todo en WinAPI por el método poke, así que no sé cómo leer el color (componente verde) del botón. Si hay una variante de trabajo, por supuesto, voy a reemplazarlo.

Este código ha sido probado por mí y se confirma que funciona.

(Te recomiendo que mantengas ambos métodos, tal vez en el futuro los desarrolladores de MT5 cambien los colores).

//+------------------------------------------------------------------+
//|CheckButtonColour.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))
//+------------------------------------------------------------------+
//| Obtener handle del botón "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;
}

//+------------------------------------------------------------------+
//| Función genérica de detección de color: Comprueba si el botón es específico.
//| la posición coincide con el color RGB preestablecido |
//+------------------------------------------------------------------+
bool IsButtonBackgroundColor(HWND hButton, color targetClr) {
  if(!hButton || !user32::IsWindow(hButton)) return false;
  // 1. Obtener la posición del botón en la pantalla
  RECT rect;
  user32::GetWindowRect(hButton, rect);
  // 2. Punto de muestreo: 20 píxeles desde el borde izquierdo, centro vertical (evitar texto)
  int targetX = rect.left + 20;
  int targetY = rect.top + (rect.bottom - rect.top) / 2;
  // 3. Muestreo de pantalla
  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 de entrada del script OnStart|
//+------------------------------------------------------------------+
void OnStart() {
  HWND hBtn = (HWND)GetStartBtnHandle();
  if(hBtn == 0) return;
  // --- Llamadas flexibles basadas en las necesidades del usuario ---
  // Comprobación de: tema claro verde (156, 204, 101) hover:140, 188, 85
  bool isLightGreen = IsButtonBackgroundColor(hBtn, C'156, 204, 101') || 
                      IsButtonBackgroundColor(hBtn, C'140, 188, 85');
  
  // Buscar: Tema oscuro verde (96, 96, 0) hover:80, 80, 0
  bool isDarkGreen = IsButtonBackgroundColor(hBtn, C'96, 96, 0') || 
                     IsButtonBackgroundColor(hBtn, C'80, 80, 0');
  
  // Comprobación de: Light theme red (239, 154, 154) hover:223, 138, 138
  bool isLightRed = IsButtonBackgroundColor(hBtn, C'239, 154, 154') || 
                    IsButtonBackgroundColor(hBtn, C'223, 138, 138');
  
  // Buscar: Tema oscuro rojo (112, 14, 19) hover:128, 30, 35
  bool isDarkRed = IsButtonBackgroundColor(hBtn, C'112, 14, 19') || 
                   IsButtonBackgroundColor(hBtn, C'128, 30, 35');
  // Lógica empresarial
  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 #:

Aun así, la función no debería depender de los estados anteriores. Sería más fácil utilizar el color: verde - inicio, de lo contrario - parada. Pero yo hago todo en WinAPI por el método poke, así que no sé cómo leer el color (componente verde) del botón. Si hay una variante de trabajo, por supuesto, voy a reemplazarlo.

Es probablemente más fácil no por el color del botón, pero por el estado de la lista de Entradas - habilitado / deshabilitado.
 
Stanislav Korotky #:
Probablemente sea más fácil no por el color del botón, sino por el estado de la lista de Entradas - activadas/desactivadas.
¿Dónde obtener el estado de las Entradas? No hay API oficial, tenemos que determinarlo por colores y texto.
 
hini #:
¿Dónde obtener el estado de las Entradas? No hay API oficial, tenemos que determinarlo por colores y texto.

Bueno, no hay API oficial para todos los internos de MT5 - tienes que inspeccionarlos a través de utilidades como MS Spy - así es como se encontraron los identificadores de control, que ahora se utilizan en el multitester.

Si no te adentras en la selva de Inputs y sólo utilizas el botón de inicio ya probado, parece que la llamada GetWindowLongW(hwnd, 0) debería devolver el color actual del botón. El mío devuelve 0xD0B1DF10 para el verde. Sólo si MQ decide corregir el estilo, este ajuste podría desaparecer. Así que comprobar la actividad de los Inputs es más fiable de todas formas.

 
Stanislav Korotky #:

parece que la llamada GetWindowLongW(hwnd, 0) debería devolver el color actual del botón. Obtengo 0xD0B1DF10 para el verde.

GetPixel parece devolver un color G diferente.