Bibliotecas: MultiTester - página 54

 
hini #:

O código verifica apenas os idiomas russo e inglês

Se alguém fornecer o nome do botão Iniciar em outros idiomas, eu o incluirei no código-fonte.
 
fxsaber #:
Se alguém fornecer o nome do botão Iniciar em outros idiomas, eu o incluirei na fonte.
Para o chinês, o texto dos botões Iniciar e Parar é o seguinte: "开始" e "停止".
 
hini #:
Em chinês, o texto dos botões "Iniciar" e "Parar" é o seguinte: "开始" e "停止".
Atualizado.
 
fxsaber #:
Atualizado.
Talvez seja mais fácil ler uma cadeia de caracteres do botão e depois comparar se ela permanece a mesma ou se foi alterada? Há muitos idiomas, mas o botão tem apenas dois estados.
 
Stanislav Korotky #:
Não seria mais fácil ler uma cadeia de caracteres do botão e depois comparar se ela permanece a mesma ou se foi alterada?

Afinal de contas, a função não deve depender de estados anteriores. Seria mais fácil usar cores: verde - iniciar, caso contrário - parar. Mas eu faço tudo na WinAPI pelo método poke, então não sei como ler a cor (componente verde) do botão. Se houver uma variante funcional, é claro, eu a substituirei.

 
fxsaber #:

Ainda assim, a função não deve depender de estados anteriores. Seria mais fácil usar a cor: verde - iniciar, caso contrário - parar. Mas eu faço tudo na WinAPI pelo método poke, então não sei como ler a cor (componente verde) do botão. Se houver uma variante funcional, é claro, eu a substituirei.

Esse código foi testado por mim e foi confirmado que ele funciona.

(Recomendo que você mantenha os dois métodos, pois talvez no futuro os desenvolvedores do MT5 mudem as cores).

//+------------------------------------------------------------------+
//|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))
//+------------------------------------------------------------------+
//| Obter o identificador do botão "Start" (Iniciar)|
//+------------------------------------------------------------------+
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;
}

//+------------------------------------------------------------------+
//| Função genérica de detecção de cor: verificar se o botão é específico
//| a posição corresponde à cor RGB predefinida
//+------------------------------------------------------------------+
bool IsButtonBackgroundColor(HWND hButton, color targetClr) {
  if(!hButton || !user32::IsWindow(hButton)) return false;
  // 1. obter a posição do botão na tela
  RECT rect;
  user32::GetWindowRect(hButton, rect);
  // 2. Ponto de amostragem: 20 pixels da borda esquerda, centro vertical (evite o texto)
  int targetX = rect.left + 20;
  int targetY = rect.top + (rect.bottom - rect.top) / 2;
  // 3. amostragem de tela
  HANDLE hdcScreen = user32::GetDC(NULL);
  uint clr = gdi32::GetPixel(hdcScreen, targetX, targetY);
  user32::ReleaseDC(NULL, hdcScreen);
  if(clr == 0xFFFFFFFF) return false;
  return targetClr == clr;
}
//+------------------------------------------------------------------+
//| Ponto de entrada do script OnStart|
//+------------------------------------------------------------------+
void OnStart() {
  HWND hBtn = (HWND)GetStartBtnHandle();
  if(hBtn == 0) return;
  // --- Chamadas flexíveis com base nas necessidades do usuário ---
  // Verificação 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');
  
  // Verificação de: tema escuro verde (96, 96, 0) hover:80, 80, 0
  bool isDarkGreen = IsButtonBackgroundColor(hBtn, C'96, 96, 0') || 
                     IsButtonBackgroundColor(hBtn, C'80, 80, 0');
  
  // Verificação de: tema claro vermelho (239, 154, 154) hover:223, 138, 138
  bool isLightRed = IsButtonBackgroundColor(hBtn, C'239, 154, 154') || 
                    IsButtonBackgroundColor(hBtn, C'223, 138, 138');
  
  // Verificação de: tema escuro vermelho (112, 14, 19) hover:128, 30, 35
  bool isDarkRed = IsButtonBackgroundColor(hBtn, C'112, 14, 19') || 
                   IsButtonBackgroundColor(hBtn, C'128, 30, 35');
  // Lógica de negócios
  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 #:

Ainda assim, a função não deve depender de estados anteriores. Seria mais fácil usar a cor: verde - iniciar, caso contrário - parar. Mas eu faço tudo na WinAPI pelo método poke, então não sei como ler a cor (componente verde) do botão. Se houver uma variante funcional, é claro, eu a substituirei.

Provavelmente, não é mais fácil ler a cor do botão, mas o estado da lista Inputs - ativado/desativado.
 
Stanislav Korotky #:
Provavelmente, isso é mais fácil não pela cor do botão, mas pelo status da lista de entradas - ativado/desativado.
Onde obter o status das entradas? Não existe uma API oficial, temos que determinar isso por cores e texto.
 
hini #:
Onde obter o status das entradas? Não existe uma API oficial, temos que determinar isso por cores e texto.

Bem, não existe uma API oficial para todos os componentes internos do MT5 - é preciso inspecioná-los por meio de utilitários como o MS Spy - foi assim que os identificadores de controle foram encontrados, que agora são usados no multitester.

Se você não entrar na selva de Inputs e usar apenas o botão Iniciar já testado, parece que a chamada GetWindowLongW(hwnd, 0) deve retornar a cor atual do botão. O meu retorna 0xD0B1DF10 para o botão verde. Somente se o MQ decidir corrigir o estilo, essa configuração poderá desaparecer. Portanto, verificar a atividade dos Inputs é mais confiável de qualquer forma.

 
Stanislav Korotky #:

Parece que a chamada GetWindowLongW(hwnd, 0) deve retornar a cor atual do botão. Recebo 0xD0B1DF10 para o botão verde.

GetPixel parece retornar uma cor G diferente.