程序库: 多功能测试仪 - 页 54

 
hini #:

代码只检查俄语和英语

如果有人提供了其他语言的 "开始 "按钮名称,我将把它添加到源代码中。
 
fxsaber #:
如果有人提供了其他语言的 "开始 "按钮名称,我将在源文件中注明。
中文 "开始 "和 "停止 "按钮的文本如下:"开始 "和 "停止"。
 
hini #:
中文 "开始 "和 "停止 "按钮的文字如下:"开始 "和 "停止"。
已更新。
 
fxsaber #:
已更新。
也许从按钮中读取一个字符串,然后比较它是保持不变还是发生了变化会更容易些?语言有很多,但按钮只有两种状态。
 
Stanislav Korotky #:
从按钮中读取一个字符串,然后比较它是保持不变还是发生了变化,不是更简单吗?

毕竟,功能不应该依赖于之前的状态。使用颜色会更简单:绿色--开始,否则--停止。但我在 WinAPI 中使用的都是 poke 方法,所以我不知道如何读取按钮的颜色(绿色部分)。如果有可行的变体,我当然会替换它。

 
fxsaber #:

不过,该功能不应依赖于之前的状态。使用颜色会更简单:绿色--开始,否则--停止。但我在 WinAPI 中使用的都是 poke 方法,所以我不知道如何读取按钮的颜色(绿色部分)。如果有可行的变体,我当然会替换它。

我已经对这段代码进行了测试,并确认它可以正常工作。

(我建议您保留这两种方法,也许将来 MT5 开发人员会更改颜色)。

//+------------------------------------------------------------------+
//|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))
//+------------------------------------------------------------------+
//| 获取 "开始 "按钮的句柄|
//+------------------------------------------------------------------+
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;
}

//+------------------------------------------------------------------+
//| 通用颜色检测功能:检查按钮是否具有特定颜色。
//| 位置与预设的 RGB 颜色相匹配
//+------------------------------------------------------------------+
bool IsButtonBackgroundColor(HWND hButton, color targetClr) {
  if(!hButton || !user32::IsWindow(hButton)) return false;
  // 1.获取按钮在屏幕上的位置
  RECT rect;
  user32::GetWindowRect(hButton, rect);
  // 2.采样点:左边缘起 20 像素,垂直中心(避开文字)
  int targetX = rect.left + 20;
  int targetY = rect.top + (rect.bottom - rect.top) / 2;
  // 3. 屏幕取样
  HANDLE hdcScreen = user32::GetDC(NULL);
  uint clr = gdi32::GetPixel(hdcScreen, targetX, targetY);
  user32::ReleaseDC(NULL, hdcScreen);
  if(clr == 0xFFFFFFFF) return false;
  return targetClr == clr;
}
//+------------------------------------------------------------------+
//| 脚本入口 OnStart|
//+------------------------------------------------------------------+
void OnStart() {
  HWND hBtn = (HWND)GetStartBtnHandle();
  if(hBtn == 0) return;
  // --- 根据用户需求灵活调用 ---
  // 检查:浅绿色主题 (156, 204, 101) 悬停:140, 188, 85
  bool isLightGreen = IsButtonBackgroundColor(hBtn, C'156, 204, 101') || 
                      IsButtonBackgroundColor(hBtn, C'140, 188, 85');
  
  // 检查:深色主题绿色 (96, 96, 0) hover:80, 80, 0
  bool isDarkGreen = IsButtonBackgroundColor(hBtn, C'96, 96, 0') || 
                     IsButtonBackgroundColor(hBtn, C'80, 80, 0');
  
  // 检查:浅色主题红色 (239, 154, 154) hover:223, 138, 138
  bool isLightRed = IsButtonBackgroundColor(hBtn, C'239, 154, 154') || 
                    IsButtonBackgroundColor(hBtn, C'223, 138, 138');
  
  // 检查:深色主题红色 (112, 14, 19) 悬停:128, 30, 35
  bool isDarkRed = IsButtonBackgroundColor(hBtn, C'112, 14, 19') || 
                   IsButtonBackgroundColor(hBtn, C'128, 30, 35');
  // 业务逻辑
  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 #:

不过,该功能不应依赖于之前的状态。使用颜色会更简单:绿色--开始,否则--停止。但我在 WinAPI 中使用的都是 poke 方法,所以我不知道如何读取按钮的颜色(绿色部分)。如果有可行的变体,我当然会替换它。

也许不是通过按钮的颜色,而是通过输入列表的状态--启用/禁用--会更容易些。
 
Stanislav Korotky #:
这可能不是通过按钮的颜色,而是通过输入列表的状态(启用/禁用)来实现的。
从哪里获取输入状态?没有官方的应用程序接口,我们只能通过颜色和文字来确定。
 
hini #:
从哪里获取输入状态?没有官方 API,我们只能通过颜色和文字来确定。

所有 MT5 内部组件都没有官方 API - 您必须通过 MS Spy 等实用程序进行检查 - 这就是控制标识符的发现方式,现在在多重测试器中也使用了这些标识符。

如果不使用输入法,只使用已经测试过的启动按钮,GetWindowLongW(hwnd, 0) 调用似乎应该返回按钮的当前颜色。我的按钮是绿色的,返回值是 0xD0B1DF10。只有当 MQ 决定修正样式时,这一设置才可能消失。因此,无论如何,检查 Inputs 的活动更为可靠。

 
Stanislav Korotky #:

看起来 GetWindowLongW(hwnd, 0) 调用应该返回按钮的当前颜色。我得到的绿色按钮是0xD0B1DF10

GetPixel 似乎返回的是不同的 G 颜色。