mql5 언어의 특징, 미묘함 및 작업 방법 - 페이지 189

 
Nikolai Semko :

CTestTimer 클래스의 Timer4 메서드(파란색으로 강조 표시됨)를 시작해야 합니다.

그것에 들어가지 않았다.

 #property indicator_chart_window
#include <Timer.mqh> // https://www.mql5.com/ru/code/31306

//+------------------------------------------------------------------+
class CTestTimer {
 private :
   //typedef void (CTestTimer::*TFunc2)(); // так работает в C++, но здесь не работает
 public :
   static int x4;
   CTestTimer() {
       //TFunc2 p=CTestTimer::Timer4;
       //TFunc2 p=Timer4;
       //timers.NewTimer(700,p);
      timers.NewTimer( 700 ,Method2Function); // ошибка 'Timer4' - pointer to this function type is not supported yet
   };
   ~CTestTimer(){};
   static void Timer4() {
      x4++;
       if (x4== 7 ) timers.KillTimer(Method2Function); // удаляем этот таймер
   }
};
//+------------------------------------------------------------------+

static int CTestTimer::x4 = 0 ;

void Method2Function()
{
  CTestTimer::Timer4();
}
 

거래, 자동 거래 시스템 및 거래 전략 테스트에 관한 포럼

mql5 언어의 특징, 미묘함 및 작업 방법

fxsaber , 2020.05.14 02:57

다시 부딪쳤다. 드문 경우지만 재로그인 중에 이런 일이 발생할 수 있다고 생각합니다.

해결 방법 - 거짓이면 잠시 멈춘 후 다시 시도하십시오.

 bool IsTradeAllowed( const int Attempts = 0 )
{        
   // https://www.mql5.com/ru/forum/170952/page174#comment_16363677
   bool Res = false ;
   int Count = 0 ;
  
   // https://www.mql5.com/ru/forum/170952/page174#comment_16363677
   while (!(Res = :: MQLInfoInteger ( MQL_TRADE_ALLOWED ) &&
                 :: AccountInfoInteger ( ACCOUNT_TRADE_EXPERT ) &&
                 :: AccountInfoInteger ( ACCOUNT_TRADE_ALLOWED ) &&
                 :: TerminalInfoInteger ( TERMINAL_TRADE_ALLOWED )) &&
         (Count++ < Attempts) && !:: IsStopped ())
    :: Sleep ( 100 );
    
   return (Res);
}

이것은 잘못된 결정입니다. 그게 훨씬 낫습니다.

 const bool Init = EventSetMillisecondTimer ( 1 );

bool Allowed()
{
   return (:: MQLInfoInteger ( MQL_TRADE_ALLOWED ) &&
         :: AccountInfoInteger ( ACCOUNT_TRADE_EXPERT ) &&
         (:: AccountInfoInteger ( ACCOUNT_TRADE_ALLOWED ) || !:: TerminalInfoInteger ( TERMINAL_CONNECTED ) ) &&
         :: TerminalInfoInteger ( TERMINAL_TRADE_ALLOWED ));
}

void OnTimer ()
{
   if (!Allowed())
     ExpertRemove ();
}

수동으로 다시 로그인하면 이 어드바이저가 계속 작동합니다. 강조 표시된 줄이 없으면 자체적으로 삭제됩니다.

 
fxsaber :

그것에 들어가지 않았다.

시간 내 주셔서 감사합니다. 그러나 나는 그 방법이 비정적이어야 한다고 위에서 썼습니다. 이것이 static으로 가능하다는 것은 분명합니다. 정적 메서드는 전혀 OOP가 아닙니다.
분명히, 나는 너무 많이 원했거나 오히려 불가능했습니다.
C++로 할 수 있다는 사실에 혼란스러웠는데, 알아낸 결과 그런 포인터의 구조가 완전히 다르다는 것을 깨달았습니다.

https://habr.com/en/post/333334/


그리고 이것은 이해할 수 있습니다.

결국, 비정적 클래스 메소드는 메모리 어딘가에 있는 구현을 가지고 있으며 클래스의 모든 객체를 위한 것입니다.
그러나 결국 각 개체는 고유한 내부 변수의 현재 상태를 가지므로 비정적 메서드에 대한 이러한 포인터는 여전히 채워지는 순간 이 메서드가 적용되는 개체의 매개 변수 구조를 가지고 있어야 합니다.
시간을 낭비한 모든 분들께 사과드립니다.
다양한 클래스의 개체를 일반적으로 제어하는 다른 방법을 찾아야 합니다.

해결책이 없다는 증거도 해결책입니다.

 
Nikolai Semko :

시간 내 주셔서 감사합니다. 그러나 나는 그 방법이 비정적이어야 한다고 위에서 썼습니다. 이것이 static으로 가능하다는 것은 분명합니다.

위에서 두 가지 예를 제시했습니다. 하나는 완전한 구현
 
TheXpert :
위에서 두 가지 예를 제시했습니다. 하나는 완전한 구현

제 임무를 잘못 이해하신 것 같습니다.
그녀는 해결책이 없습니다.

 
Nikolai Semko :

제 임무를 잘못 이해하신 것 같습니다.
그녀는 해결책이 없습니다.

근처에 문이 있으면 왜 벽에 머리를 부딪치나요? 외부 클래스의 핸들러 호출이 있는 다중 타이머 작업이 해결됩니다.

동지는 당신이 보는 대로 당신의 문제에 대한 해결책을 가지고 있습니다. 비공개 진실입니다.

 
TheXpert :
근처에 문이 있는데 왜 벽에 머리를 부딪치나요? 외부 클래스의 핸들러 호출이 있는 다중 타이머 작업이 해결됩니다.

그것은 더 이상 타이머에 관한 것이 아니었습니다.
나는 단지 꿈과 투파눌.

 
Nikolai Semko :

나는 단지 꿈과 투파눌.

나는 mql 또는 동일한 바인드에 본격적인 typedef가 있는 경우에만 해당됩니다. 그러나 우리는 무엇을 가지고 있습니까?

 

지시 자나 조언자가 만든 개체와 수동으로 만든 그래픽 개체를 어떻게 든 구별할 수 있습니까?

기능에서

 void OnChartEvent ( const int id, const long &lparam, const double &dparam, const string &sparam)
  {
   if (id == CHARTEVENT_OBJECT_CREATE )
     {

     }
  }
 
Vladimir Pastushak :

지시 자나 조언자가 만든 개체와 수동으로 만든 그래픽 개체를 어떻게 든 구별할 수 있습니까?

기능에서

마우스 왼쪽 버튼을 누르는 제어를 통해 수행할 수 있습니다.
예를 들면 다음과 같습니다.

 #property indicator_chart_window
#include <Timer.mqh> //https://www.mql5.com/ru/code/31306

uint t_LMB= 0 ;
int OnInit () {
   ChartSetInteger ( 0 , CHART_EVENT_OBJECT_CREATE , 0 , true );
   ChartSetInteger ( 0 , CHART_EVENT_MOUSE_MOVE , true );
   return ( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+
int OnCalculate ( const int rates_total, const int prev_calculated, const int begin, const double &price[]) {
   return (rates_total);
}
//+------------------------------------------------------------------+
void OnChartEvent ( const int id, const long &lparam, const double &dparam, const string &sparam) {
   static string str=sparam;
   if (str!= "1" && sparam== "1" ) t_LMB= GetTickCount (); // нажате левая кнопка мышки
   if (id == CHARTEVENT_OBJECT_CREATE ) {
      CheckManual( GetTickCount ());
   }
   str=sparam;
}
//+------------------------------------------------------------------+
void CheckManual( uint start= 0 ) {
   static uint s= 0 ;
   if (start> 0 ) {
      s=start;
      timers.NewTimer( 20 ,Timer1); // Создаем таймер на 20 милисекунд и функцией-обработчиком Timer1()
       return ;
   }
   int pause = int (t_LMB-s);
   if (pause>= 0 && pause< 20 ) Print ( "Создан графический объект в ручную" );
   else Print ( "Создан графический объект программно" );
   timers.KillTimer(Timer1); // удаляем таймер Timer1
}
//+------------------------------------------------------------------+
void Timer1() {CheckManual();}
사유: