라이브러리: 멀티 테스터 - 페이지 54

 
hini #:

이 코드는 러시아어와 영어만 확인합니다.

누군가 다른 언어로 시작 버튼의 이름을 제공하면 소스 코드에 포함하겠습니다.
 
fxsaber #:
다른 언어로 된 시작 버튼의 이름을 알려주시면 소스에 포함하겠습니다.
중국어의 경우 시작 및 중지 버튼의 텍스트는 다음과 같습니다: "开始" 및 "停止".
 
hini #:
중국어의 경우 '시작' 및 '중지' 버튼의 텍스트는 다음과 같습니다: "开始" 및 "停止".
업데이트되었습니다.
 
fxsaber #:
업데이트되었습니다.
버튼에서 문자열을 읽은 다음 동일하게 유지되는지 또는 변경되었는지 비교하는 것이 더 쉬울까요? 많은 언어가 있지만 버튼에는 두 가지 상태만 있습니다.
 
Stanislav Korotky #:
버튼에서 문자열을 읽은 다음 동일하게 유지되는지 또는 변경되었는지 비교하는 것이 더 쉽지 않을까요?

결국 함수는 이전 상태에 의존해서는 안 됩니다. 색상을 사용하는 것이 더 쉬울 것입니다: 녹색 - 시작, 그렇지 않으면 - 중지. 하지만 WinAPI에서 모든 작업을 포크 방식으로 수행하므로 버튼의 색상 (녹색 구성 요소)을 읽는 방법을 모릅니다. 물론 작동하는 변형이 있으면 교체하겠습니다.

 
fxsaber #:

하지만 함수가 이전 상태에 의존해서는 안 됩니다. 색상을 사용하는 것이 더 쉬울 것입니다: 녹색 - 시작, 그렇지 않으면 - 중지. 하지만 WinAPI에서 모든 작업을 포크 방식으로 수행하므로 버튼의 색상 (녹색 구성 요소)을 읽는 방법을 모릅니다. 물론 작동하는 변형이 있으면 교체하겠습니다.

이 코드는 제가 테스트 한 결과 작동하는 것으로 확인되었습니다.

(두 가지 방법을 모두 유지하는 것이 좋습니다. 향후 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) 마우스오버: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에서 모든 작업을 포크 방식으로 수행하므로 버튼의 색상 (녹색 구성 요소)을 읽는 방법을 모릅니다. 물론 작동하는 변형이 있으면 교체하겠습니다.

버튼의 색상이 아니라 입력 목록의 상태 (활성화 / 비활성화)가 더 쉬울 것입니다.
 
Stanislav Korotky #:
버튼의 색이 아니라 입력 목록의 상태(사용/사용 안 함)로 확인하는 것이 더 쉬울 것입니다.
입력의 상태는 어디에서 확인할 수 있나요? 공식적인 API가 없기 때문에 색상과 텍스트로 확인해야 합니다.
 
hini #:
입력 상태는 어디에서 확인할 수 있나요? 공식 API가 없기 때문에 색상과 텍스트로 확인해야 합니다.

모든 MT5 내부에 대한 공식 API는 없으며, MS Spy와 같은 유틸리티를 통해 검사해야 하며, 이것이 현재 멀티테스터에서 사용되는 제어 식별자를 찾은 방법입니다.

입력의 야생으로 들어가지 않고 이미 테스트된 시작 버튼만 사용한다면 GetWindowLongW(hwnd, 0) 호출은 버튼의 현재 색상을 반환해야 할 것 같습니다. 제 것은 녹색 버튼에 대해 0xD0B1DF10을 반환합니다. MQ가 스타일을 수정하기로 결정한 경우에만 이 설정이 사라질 수 있습니다. 따라서 입력의 활동을 확인하는 것이 더 안정적입니다.

 
Stanislav Korotky #:

는 GetWindowLongW(hwnd, 0) 호출이 버튼의 현재 색상을 반환해야 하는 것처럼 보입니다. 녹색 버튼의 경우 0xD0B1DF10이 반환됩니다.

GetPixel은 다른 G 색상을 반환하는 것 같습니다.