기고글 토론 "MQL5 Coobook: 지표 하위 창 컨트롤 - 버튼" - 페이지 7

 
TheXpert:
기사가 완벽하다고 확신하시나요?

읽어 주셔서 매우 기쁩니다.

해당 스레드에서 모든 질문에 기꺼이 답변해 드리겠습니다.

===

불필요한 오해가 없도록 저는 아나톨리에게 악감정이 없습니다! 기사에 대해 그에게 찬사를 보냅니다! 그러나 질문에 답할 필요가 있습니다 ...

 
DC2008:

실례합니다. 혹시 제가 다른 튜토리얼이나 레시피를 작성하는 데 방해가 되나요?

그렇지 않은 경우 표시기 하위 창에서 제어에 대한 기사에 대해 계속 논의 해 보겠습니다. 따라서 표시기에서 편리한 메뉴를 만드는 방법에 대한 대량 솔루션 (또는 아이디어)을 제공합니다. 좋아요, 기사의 목적은 매우 가치가 있습니다! 그러나 "초보자"프로그래머가이 모든 무기고를 어떻게 사용할 수 있습니까? 사용자 지정 함수를 어디에 배치할까요? 예를 들어 시연해 보겠습니다. 그리고 동시에 5 개의 버튼을 사용하기 위해 코드에서 수정해야하는 사항을 설명 하시겠습니까? 초보자의 질문이라고 생각하세요.

아니요, 그렇지 않습니다. 아직 아무것도 쓰지 않고 있습니다. 일년에 적어도 하루는 쉬어야 해요. 그냥 쉬는 것은 흥미롭지 않으며 특히 오랜 시간 동안은 더욱 그렇습니다. )

대규모 결정이 아니라서 글을 쓰지 않았어요. 일어나지 않은 일에 원인을 돌리지 말자. 이것은 보편적 인 해결책이 아니라 특별한 경우라는 것은 이미 토론 초기에 표명되었습니다. 제 생각에는 초보자가 연습하기에 좋은 예입니다. 그리고 기성품 솔루션을 무료로 받고 태양을 만나기 위해 입을 크게 벌리고 달리는 것이 아닙니다. ) 이해 하시겠습니까? 프로그래밍을 배우는 초기에 이렇게 간단하고 명확한 예제를 원합니다. 특히 이것이 당신의 인생에서 첫 번째 프로그래밍 언어이고 그 전에는 평생의 활동이 완전히 다른 분야에서 전혀 연결되어 있지 않은 경우.

이 경우 5 개의 버튼을 만들려면 배열의 크기를 변경하고 개체 이름-버튼, 버튼에 표시되는 텍스트 및 버튼 상태에 대한 배열을 선언 할 때 불필요한 요소를 제외해야합니다.

버튼 상태 배열이 있으므로 동일한 원리를 사용하여 어떤 버튼이 눌렸는지 확인하고 버튼의 색상을 변경하는 대신 다른 (사용자 필수) 작업을 수행할 수 있습니다. 예를 들어 모든 지정가 주문 삭제, 모든 포지션 청산 등 트레이딩 기능(뿐만 아니라)이 될 수 있습니다. 아이디어는 무궁무진합니다. 아이디어가 없다면 잘못된 종류의 활동을 선택한 것입니다. )

이를 구현하려면 사용자 지정 열거형의 식별자로 초기화되는 또 다른 배열을 만들어야 합니다(예: ENUM_SCRIPT라는 이름으로). 그런 다음 식별자가 호출됩니다(예: SCRIPT_01 =0, SCRIPT_02 =2 등). 또한 루프에서 패널의 버튼이 눌려 졌는지 확인할 때 눌린 버튼과 버튼의 현재 상태에 바인딩 된 식별자를 확인한 다음 해당 함수를 실행할 프로그램에 전달해야합니다.

일부러 샘플 코드를 보여주지 않겠습니다. 초보자를위한 숙제로 두십시오. )

Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства ордеров
Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства ордеров
  • www.mql5.com
Стандартные константы, перечисления и структуры / Торговые константы / Свойства ордеров - Документация по MQL5
 

말씀하신 대로 변경했습니다:

버튼에 표시되는 텍스트 //---
string button_texts[BUTTON_ROWS][BUTTON_COLUMNS]=
  {
     {"Button 01","Button 02","Button 03","Button 04"},
     {"Button 05"}
  };
//--- 개체 이름
string button_object_names[BUTTON_ROWS][BUTTON_COLUMNS]=
  {
     {"button_01","button_02","button_03","button_04"},
     {"button_05"}
  };
....
bool button_states[BUTTON_ROWS][BUTTON_COLUMNS]=
  {
     {true,false,false,false},
     {false}
  };

그리고 이것이 화면에 표시된 내용입니다:

어떻게 고쳐야 하나요? (저는 초보자입니다)

 
DC2008:

말씀하신 대로 변경했습니다:

그리고 이것이 화면에 표시된 내용입니다:

어떻게 고쳐야 하나요? (저는 초보자입니다)

이렇게요:

#define  BUTTON_COLUMNS 5 // 너비별 버튼 수
#define  BUTTON_ROWS    1 // 높이별 버튼 수
...
버튼에 표시되는 텍스트 //---
string button_texts[BUTTON_ROWS][BUTTON_COLUMNS]=
  {
     {"Button 01","Button 02","Button 03","Button 04","Button 05"}
  };
//--- 개체 이름
string button_object_names[BUTTON_ROWS][BUTTON_COLUMNS]=
  {
     {"button_01","button_02","button_03","button_04","button_05"}
  };
...
//--- 버튼 상태
bool button_states[BUTTON_ROWS][BUTTON_COLUMNS]=
  {
     {true,false,false,false,false}
  };
 

오, 잘됐네요! 작동합니다.

하지만 내 기능을 버튼에 연결하는 방법을 모르겠어요. 예를 보여주세요.

 
DC2008:

오, 잘됐네요! 작동합니다.

하지만 내 기능을 버튼에 연결하는 방법을 모르겠어요. 예를 보여주세요.

그럼, 여러분이 시작한 "초보자" 게임을 계속해 보겠습니다. )

어느 지점에서 막히나요? 현재 시점에서 얼마나 이해했는지 보여주세요. 다섯 개의 식별자가 있는 열거형과 그 식별자를 요소에 할당해야 하는 배열을 만듭니다.

 
bool fun_states[BUTTON_ROWS][BUTTON_COLUMNS]=
  {
     {true,false,false,false,false}
  };
enum ENUM_SCRIPT
  {
   SCRIPT_01 =0,
   SCRIPT_02 =1,
   SCRIPT_03 =2,
   SCRIPT_04 =3,
   SCRIPT_05 =4,
  };
void F1()
  {Print("F1");}
bool F2()
  {Print("F2");return(false);}
int F3()
  {Print("F3");return(0);}
double F4()
  {Print("F4");return(0.1);}
color F5()
  {Print("F5");return(clrAliceBlue);}

그렇다면 이제 어떻게 해야 할까요?

 
DC2008:

그렇다면 이제 어떻게 해야 할까요?

이것이 바로 여러분이 필요로 하는 배열입니다:

//--- 스크립트
ENUM_SCRIPT buttons_scripts[NUMBER_BUTTONS_HEIGHT][NUMBER_BUTTONS_WIDTH]=
  {
     {SCRIPT_01,SCRIPT_02,SCRIPT_03,SCRIPT_04,SCRIPT_05}
  };

그런 다음 다음과 같은 함수를 작성해야 합니다:

//+------------------------------------------------------------------+
//|| 스크립트 실행하기 |
//+------------------------------------------------------------------+
void ScriptOn()
  {
   for(int i=0; i<NUMBER_BUTTONS_WIDTH; i++)
     {
      for(int j=0; j<NUMBER_BUTTONS_HEIGHT; j++)
        {
         //--- 이 버튼을 누르면 해당 스크립트가 실행됩니다.
         if(buttons_state[j][i])
           {
            if(buttons_scripts[j][i]==SCRIPT_01)
              {
               F1();
               return;
              }
            //---
            if(buttons_scripts[j][i]==SCRIPT_02)
              {
               F2();
               return;
              }
            //---
            if(buttons_scripts[j][i]==SCRIPT_03)
              {
               F3();
               return;
              }
            //---
            if(buttons_scripts[j][i]==SCRIPT_04)
              {
               F4();
               return;
              }
            //---
            if(buttons_scripts[j][i]==SCRIPT_05)
              {
               F5();
               return;
              }
           }
        }
     }
  }

...그리고 이 함수를 코드의 이 부분에 배치합니다:

//--- 그래픽 개체에서 마우스 왼쪽 버튼 클릭 추적
   if(id==CHARTEVENT_OBJECT_CLICK)
     {
      //--- 버튼을 클릭하면
      if(InitializeButtonStates(sparam))
        {
         //--- 버튼의 색상을 설정합니다.
         ChangeButtonColorOnClick();
         //--- 스크립트 실행
         ScriptOn();
        }
      //--- 차트 업데이트
      ChartRedraw();
      return;
     }

그런 다음 필요한 경우 코드를 최적화하는 방법에 대해 생각할 수 있습니다. :)

 
tol64:

저는 그렇게 하고 있습니다.

시작할 때 추적이 활성화된 프로그램은 언로드할 때 추적이 꺼집니다. 그리고 차트에 남아 있고 추적이 필요한 프로그램은 활성화되어 있는지 확인하고 비활성화 된 경우 활성화합니다.

이전 페이지의 내 게시물에서 전문가 고문 및 지표 코드의 예제에 대한 변형을 제공하여 진술의 모호성을 배제하는 것이 바람직합니다.

누군가가 마우스 이벤트 추적을 비활성화했는지 지속적으로 확인할 필요가 없습니다. 더 정확히 말하자면, 어떤 상황에서도 자신을 보호하고 싶다면 확인할 수 있지만 너무 과하다고 생각합니다.

개발자에게 차트 이벤트가 변경되면 차트 이벤트가 변경될 때 CHARTEVENT_CHART_CHANGE를 생성하도록 제안하면 어떨까요? 그러면 Expert Advisor가 실행 중일 때 필요한 설정을 우아하게 복원할 수 있을 것 같습니다.

지금까지는 이 변형이 있습니다:

#property copyright "Copyright 2013, komposter"
#property link      "http://www.komposter.me/"
#property version   "1.00"
#property indicator_chart_window

input   bool    EnableMouseDetect = false; // true-마우스 추적과 함께 작동, false-마우스 추적 없이 작동

bool PrevState = false;

//+------------------------------------------------------------------+
//| 사용자 지정 표시기 초기화 기능 |
//+------------------------------------------------------------------+
int OnInit()
{
        if ( EnableMouseDetect )
        {
                //--- 현재 상태 가져오기
                PrevState = (bool)ChartGetInteger(0,CHART_EVENT_MOUSE_MOVE);
                //--- 마우스 이벤트 추적 사용
                if ( PrevState == false ) ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
        }

        return(0);
}

//+------------------------------------------------------------------+
//| 전문가의 초기화 기능 ||
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
        if ( EnableMouseDetect )
        {
                //--- 마우스 이벤트 추적 비활성화
                if ( PrevState == false )
                {
                        ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,false);
                        ChartRedraw(); // 이 줄이 없으면 틱이 도착할 때만 추적이 비활성화됩니다. 이것이 설계된 방식인가요?
                }
        }
}

//+------------------------------------------------------------------+
//| OnTick|
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                     const int prev_calculated,
                     const datetime& time[],
                     const double& open[],
                     const double& high[],
                     const double& low[],
                     const double& close[],
                     const long& tick_volume[],
                     const long& volume[],
                     const int& spread[])
       {
        
        return(rates_total);
       }
//+------------------------------------------------------------------+
//| 차트 이벤트 함수|
//+------------------------------------------------------------------+
void OnChartEvent(const int    id,
                  const long   &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--- 마우스 움직임 및 마우스 왼쪽 버튼 누름 추적
   if(id==CHARTEVENT_MOUSE_MOVE)
     {
      static int count=1;
      Print("CHARTEVENT_MOUSE_MOVE; EXPERT; ",count);
      count++;
     }
  }
//+------------------------------------------------------------------+

하나의 표시기를 만들었지만 매개 변수가 있습니다. EnableMouseDetect = true로 실행 - 추적을 제어하고 false - 추적이 활성화 된 경우 이벤트 수만 인쇄합니다.


------------------
이제 좀 더 생각해 보니 이 옵션은 작동하지 않습니다. 마우스를 추적하는 프로그램을 먼저 실행한 다음(추적 활성화), 두 번째 프로그램을 실행한 다음(이미 활성화된 것을 확인) 첫 번째 프로그램을 삭제하면 추적이 비활성화되고 두 번째 프로그램은 아무것도 남지 않습니다. 즉, 추적이 필요하다는 신호를 보내는 일종의 세마포어를 생각해내야 합니다.

그리고 여기에서 수행 된 연구 (프로세서 부하에 대한)에 비추어 볼 때 그러한 목발은 필요하지 않습니다.

그래서 저는 개발자들에게 제 제안을 투표 할 것을 제안하고 주제를 닫을 수 있습니다.

 
ChartRedraw(); // 이 줄이 없으면 틱이 도착할 때만 추적이 비활성화됩니다. 이것이 설계된 방식인가요?
MT5는 차트 프로퍼티를 비동기식으로 업데이트합니다. 즉, 프로퍼티를 설정했다고 해서 터미널이 즉시 프로퍼티를 가져온다는 의미는 아닙니다. ChartRedraw() 함수는 터미널에서 모든 프로퍼티를 다시 읽도록 하는 데 사용됩니다. ChartGet... ObjectGet을 사용할 수도 있는데, 이 경우 프로퍼티도 다시 읽습니다.
Документация по MQL5: Операции с графиками / ChartRedraw
Документация по MQL5: Операции с графиками / ChartRedraw
  • www.mql5.com
Операции с графиками / ChartRedraw - Документация по MQL5