MQL5에서 자신 만의 그래픽 패널 만들기
소개
표준 라이브러리에서 사용할 수있는 새로운 클래스 세트가 있습니다. 이 클래스는 MQL5 프로그램에서 컨트롤 대화 상자 및 디스플레이 패널의 독립적인 개발을 위해 설계되었습니다.
새로운 클래스 집합을 통해 모든 사람은 이벤트 기반 모델을 기본 모델로 사용하여 사용자 지정 인터페이스 구성 요소를 만들 수 있습니다. 모든 것은 포함된 차트 개체 및 터미널의 이벤트를 기반으로 합니다.
- 별도의 차트 하위 창에 패널을 표시합니다.
- Expert Adviser을 위한 컨트롤 패널;
- 맞춤형 디스플레이 컨트롤 패널.
이 글에서는 표준 라이브러리 클래스를 사용하여 별도의 차트 하위 창에 자신 만의 디스플레이 패널을 만드는 것이 얼마나 쉬운 지 보여줍니다.
표준 라이브러리는 무엇을 제공해야 합니까?
표준 라이브러리는 개발자에게 다음과 같은 즉시 사용 가능한 컨트롤을 제공합니다.
1. 간단한 컨트롤 :
컨트롤 신청 임베디드 객체 기반 구현 표준 라이브러리 파일 텍스트가 있는 버튼
마우스와 MQL 프로그램 상관 상호 작용 보장
"버튼" <Controls\Button.mqh> 이미지가 있는 버튼
마우스와 MQL 프로그램 상관 상호 작용 보장
"그래픽 라벨" <Controls\BmpButton.mqh> 편집
텍스트 정보 입력 또는 표시 ("읽기 전용") 모드
"편집" <Controls\Edit.mqh> 표제
보조 텍스트 정보 표시
"텍스트 라벨" <Controls\Label.mqh> 패널
보조 컨트롤 (시각적 컨트롤 그룹)
"직사각형 레이블" <Controls\Panel.mqh> 이미지
장식 컨트롤
"그래픽 라벨" <Controls\Picture.mqh>
2. 복잡한 컨트롤 :
컨트롤 신청 컨트롤 기반 구현 표준 라이브러리 파일 명부
목록보기
"직사각형", "이미지가 있는 버튼" 및 "편집" <Controls\List.mqh> 드롭 다운 목록이있는 필드
드롭 다운 목록에서 선택
"편집", "이미지가 있는 버튼" 및 "목록" <Controls\ComboBox.mqh> Increment/decrement field
값 열거
"편집" 및 "이미지가 있는 버튼" <Controls\SpinEdit.mqh> 라디오 버튼
스위치 "이미지가 있는 버튼" 및 "캡션" <Controls\RadioButton.mqh> 라디오 버튼 그룹 열거 형 유형의 필드 편집 "직사각형" 및 "라디오 버튼" <Controls\RadioGroup.mqh> 체크 박스
선택 옵션
"이미지가 있는 버튼" 및 "캡션" <Controls\CheckBox.mqh> 체크 박스 그룹
플래그 세트 편집
"직사각형" 및 "확인란" <Controls\CheckGroup.mqh> 대화 대화 형식 "직사각형", "이미지가 있는 버튼" 및 "편집" <Controls\Dialog.mqh>
디스플레이 패널 만들기
먼저 용어를 정의하겠습니다. 디스플레이 패널은 드로잉 버퍼가 없는 별도의 창 사용자 지정 디스플레이를 설명하는 데 사용할 용어입니다. 이러한 패널은 터미널에 내장된 차트 개체를 사용하여 필요한 정보를 표시합니다. 정보가 표시 될 수 있습니다.
- 수치적으로
- 텍스트로,
- 색상으로,
- 기타
필요한 모든 단계를 자세히 살펴보고 다음과 같이 그래픽 패널을 만듭니다.
디스플레이 패널을 만들려면 두 개의 파일이 필요합니다.
- 디스플레이 패널 클래스에 대한 설명이 포함된 포함 파일입니다.
- 인디케이터 소스 코드 파일입니다.
이러한 파일의 템플릿은 MQL5 마법사를 사용하여 얻을 수 있습니다. 인디케이터 디렉터리 (MQL5\Indicators)에서 별도의 폴더 MyIndicators 및 하위 폴더 MyPanel을 만듭니다. 폴더를 만드는 과정은 도움말에 잘 설명되어 있으므로 여기서는 다루지 않습니다.
클래스 설명
그래서 저희는 이미 작업 폴더를 만들었습니다. 이제 "네비게이터 (Navigator)"창에서 찾아서 마우스 오른쪽 버튼으로 클릭하겠습니다. 나타나는 메뉴에서 "새 파일"을 선택합니다. MQL5 마법사가 제공하는 옵션에서 "새 클래스"를 선택하고 "다음>"을 클릭하십시오. 아래와 같이 클래스 설명 대화 상자를 완료하십시오.
"마침"을 클릭하십시오. 결과적으로 다음 코드가 있습니다.
//+------------------------------------------------------------------+ //| PanelDialog.mqh | //| Copyright 2011, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2011, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CPanelDialog : public CAppDialog { private: public: CPanelDialog(); ~CPanelDialog(); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CPanelDialog::CPanelDialog() { } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CPanelDialog::~CPanelDialog() { } //+------------------------------------------------------------------+
기본 CAppDialog 클래스 및 주석에 대한 설명과 함께 표준 라이브러리에서 포함 <Controls\Dialog.mqh> 파일을 추가합니다.
//+------------------------------------------------------------------+ //| PanelDialog.mqh | //| Copyright 2011, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include <Controls\Dialog.mqh> //+------------------------------------------------------------------+ //| CPanelDialog class | //| Function: main application dialog | //+------------------------------------------------------------------+ class CPanelDialog : public CAppDialog { private: public: CPanelDialog(void); ~CPanelDialog(void); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CPanelDialog::CPanelDialog(void) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CPanelDialog::~CPanelDialog(void) { } //+------------------------------------------------------------------+
이제 인디케이터에서 대화 상자를 사용할 수있는 클래스에 대한 설명이 있습니다. 대화 상자는 현재 비어 있지만 나중에 컨트롤을 추가 할 것입니다. 지금은 지표로 진행하겠습니다.
지표 소스 코드
인디케이터는 MQL5 마법사를 사용하여 생성됩니다. 저희의 행동은 클래스 설명을 작성할 때 필요한 행동과 유사합니다. 단 한 가지 차이점이 있습니다. MQL5 마법사에서 제공하는 옵션 중에서 "사용자 지정 인디케이터"를 선택합니다. 인디케이터를 생성하려면 세 개의 대화 상자를 완료해야 합니다.
첫 번째는 인디케이터의 이름을 지정해야 합니다.
두 번째 대화 상자에서 "OnChartEvent"(필수) 및 "OnTimer"를 선택합니다.
세 번째 대화 상자에서 "개별 창 인디케이터" (필수)를 선택합니다.
그리고 "마침"을 클릭하십시오. 생성된 코드는 다음과 같습니다.
//+------------------------------------------------------------------+ //| PanelIndicator.mq5 | //| Copyright 2011, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2011, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property indicator_separate_window //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping //--- return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) { //--- //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| Timer function | //+------------------------------------------------------------------+ void OnTimer() { //--- } //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- } //+------------------------------------------------------------------+
이제 다음을 추가하여 템플릿을 완성 할 수 있습니다.
- 인디케이터 속성에 대한 설명이 누락되었습니다.
- 대화 상자의 클래스 설명이 포함된 파일을 포함합니다.
- 전역 변수 - 대화 상자의 클래스 개체입니다.
- 대화 상자 생성, 응용 프로그램 시작 및 OnInit() 함수 본문에 대한 타이머 생성을 위한 코드;
- 대화 상자를 파괴하고 타이머를 종료하는 코드를 포함하는 OnDeinit() 함수;
- OnChartEvent(...) 함수를 이벤트 핸들러 호출 코드에 추가합니다.
- 코멘트.
바로 사용할 수 있는 인디케이터가 있습니다.
//+------------------------------------------------------------------+ //| PanelIndicator.mq5 | //| Copyright 2011, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2011, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property indicator_separate_window #property indicator_plots 0 #property indicator_buffers 0 #property indicator_minimum 0.0 #property indicator_maximum 0.0 //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "PanelDialog.mqh" //+------------------------------------------------------------------+ //| Global variables | //+------------------------------------------------------------------+ CPanelDialog ExtDialog; //+------------------------------------------------------------------+ //| Initialization | //+------------------------------------------------------------------+ int OnInit() { //--- creating the application dialog if(!ExtDialog.Create(0,"Panel Indicator",0,0,0,0,130)) return(-1); //--- starting the application if(!ExtDialog.Run()) return(-2); //--- creating the timer EventSetTimer(1); //--- success return(0); } //+------------------------------------------------------------------+ //| Deinitialization | //+------------------------------------------------------------------+ int OnDeinit() { //--- destroying the dialog ExtDialog.Destroy(); //--- killing the timer EventKillTimer(); } //+------------------------------------------------------------------+ //| Iteration | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) { //--- returning the prev_calculated value for the next call return(rates_total); } //+------------------------------------------------------------------+ //| Timer event handler | //+------------------------------------------------------------------+ void OnTimer() { //--- } //+------------------------------------------------------------------+ //| Chart event handler | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- handling the event ExtDialog.ChartEvent(id,lparam,dparam,sparam); } //+------------------------------------------------------------------+
위 양식의 인디케이터는 아직 아무것도 표시하지 않습니다. 차트의 네비게이터에서 컴파일 및 드롭하면 별도의 창에 빈 대화 상자로 표시됩니다.
대화 상자가 비어 있음에도 불구하고 인디케이터는 이미 특정 기능을 획득했습니다.
- 하위 창 높이는 생성 중에 인디케이터에 의해 대화 상자 높이로 조정되었습니다.
- 대화 상자 너비는 항상 차트 너비와 같습니다.
- 인디케이터는 자체 하위 창을 최소화하고 최대화 할 수 있습니다.
표시해봅시다
패널이 정보를 표시하기 시작하려면 세 가지 질문에 대한 답을 결정해야 합니다.
- 어떤 종류의 정보를 표시하고 싶습니까?
- 대화 상자에 배치하려면 어떤 추가 디스플레이 요소 및/또는 컨트롤이 필요합니까?
- 이러한 추가 요소/컨트롤은 어떻게 상호 작용합니까?
또 다른 중요한 요소는 대화가 시각적으로 매력적이고 사용자 친화적이어야 한다는 것입니다. 대화 상자의 기능에는 영향을 주지 않지만 향후 MQL5 프로그램의 사용자에 대해 관심이 있음을 보여줍니다.
1 단계. 어떤 종류의 정보를 표시하고 싶습니까?
이 글은 학습 도구 역할을 하므로 지표의 유용성에 대해 생각하지 마십시오. 색상은 세 가지 매개 변수의 함수로 표시됩니다. 매개 변수를 과도하게 복잡하게 만들지 않을 것입니다. - "Red", "Green" 및 "Blue" 수준이 됩니다.
매개 변수 값은 다음과 같이 설정됩니다.
그건 그렇고, 이러한 수준의 값은 저희 지표에도 표시됩니다.
2 단계. 어떤 추가 컨트롤이 필요합니까?
3 단계. 이러한 추가 대화 컨트롤은 어떻게 상호 작용합니까?
- 색상은 "패널" 컨트롤을 사용하여 표시됩니다.
- "읽기 전용" 모드에서 "편집" 컨트롤을 사용하여 "Red" 및 "Green" 수준이 표시됩니다.
- "Blue" 레벨은 "Spin Edit" 컨트롤에 의해 관리됩니다. 동일한 컨트롤이 레벨 값을 표시하는 데 도움이 됩니다.
- "Edit" 및 "Spin Edit" 컨트롤은 "Caption" 컨트롤을 통해 설명 캡션으로 향상됩니다.
주석을 제공한 클래스 설명에 매개 변수 값을 저장하는 필수 컨트롤 및 변수 뿐만 아니라 표준 라이브러리의 포함 파일을 추가하십시오.
저희는 다음을 갖게 됩니다.
//+------------------------------------------------------------------+ //| PanelDialog.mqh | //| Copyright 2011, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include <Controls\Dialog.mqh> #include <Controls\Panel.mqh> #include <Controls\Edit.mqh> #include <Controls\Label.mqh> #include <Controls\SpinEdit.mqh> //+------------------------------------------------------------------+ //| CPanelDialog class | //| Function: main application dialog | //+------------------------------------------------------------------+ class CPanelDialog : public CAppDialog { private: //--- additional controls CPanel m_color; // object for displaying color CLabel m_label_red; // "red" level caption object CEdit m_field_red; // "red" value display object CLabel m_label_green; // "green" level caption object CEdit m_field_green; // "green" value display object CLabel m_label_blue; // "blue" level caption object CSpinEdit m_edit_blue; // "blue" value control object //--- parameter values int m_red; // "red" value int m_green; // "green" value int m_blue; // "blue" value public: CPanelDialog(void); ~CPanelDialog(void); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CPanelDialog::CPanelDialog(void) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CPanelDialog::~CPanelDialog(void) { } //+------------------------------------------------------------------+
대화 컨트롤 간의 상호 작용 원리는 매우 간단합니다. - "대화 상자는 모든 매개 변수 ("빨간색 ","녹색 " 및 "Blue" 수준)의 변경 사항을 표시해야 합니다". 상호 작용 알고리즘의 구현은 이제 대화 생성을 시작할 때가 되면 나중에 다룰 것입니다.
눈 호소에 대한 몇 마디
대화 만들기를 진행하기 전에 눈의 호소에 대해 빠르게 살펴 보겠습니다. 또는 대화 컨트롤의 사용자 친화적인 배열 및 (가능한) 향후 재배치입니다. 명명된 상수 (#define)는 이러한 목적에 가장 적합합니다.
미리 정의된 명명된 상수가 제공하는 몇 가지 이점이 있습니다.
- 특정 경우에 사용되는 특정 숫자 값은 기억할 필요가 없습니다. 정확하게 선택된 상수 이름은 "자동 목록 이름"을 통해 빠른 액세스를 제공합니다,
- 상수 값이 추가로 수정 될 때 숫자 값의 수많은 포함을 검색하고 바꿀 필요가 없습니다. 상수 설명만 변경하면 충분합니다.
다음 상수를 사용하는 것이 좋습니다.
//+------------------------------------------------------------------+ //| defines | //+------------------------------------------------------------------+ //--- indents and spacing #define INDENT_LEFT (11) // left indent (including the border width) #define INDENT_TOP (11) // top indent (including the border width) #define INDENT_RIGHT (11) // right indent (including the border width) #define INDENT_BOTTOM (11) // bottom indent (including the border width) #define CONTROLS_GAP_X (10) // spacing along the X-axis #define CONTROLS_GAP_Y (10) // spacing along the Y-axis //--- for labels #define LABEL_WIDTH (50) // size along the X-axis //--- for edits #define EDIT_WIDTH (50) // size along the Y-axis #define EDIT_HEIGHT (20) // size along the Y-axis //--- for base colors (RGB) #define BASE_COLOR_MIN (0) // minimum value of the color component #define BASE_COLOR_MAX (255) // maximum value of the color component
디스플레이 패널 채우기
이전에 디스플레이 패널 클래스를 만들었습니다. 이제 필요한 기능을 얻으려면 다음을 수행해야 합니다.
1. 부모 클래스의 Create(...) 메소드를 재정의합니다. 원래 방법은 다음과 같이 나타납니다.
//+------------------------------------------------------------------+ //| Creation | //+------------------------------------------------------------------+ bool CPanelDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2) { //--- calling the method of the parent class if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2)) return(false); //--- additional controls shall be created here //--- success return(true); }
2. 추가 컨트롤을 만듭니다.
약간의 서정적 여담. 모든 추가 컨트롤을 생성하기위한 코드는 물론 Create(...) 메소드 본문에 직접 삽입 할 수 있지만 이렇게하면 읽을 수없는 큰 "대량"으로 발생할 위험이 있습니다.
따라서 저희는 생성 프로세스를 방법으로 표현되는 자체 포함된 부분으로 나눌 것입니다.
- bool CreateColor(void) - 색상 패널 생성
- bool CreateRed(void) - 설명 캡션이 있는 표시 요소 'Red' 생성,
- bool CreateGreen(void) - 설명 캡션이 있는 디스플레이 요소 "Green" 생성,
- bool CreateBlue(void) - 설명 캡션이 있는 컨트롤 "Blue" 생성.
이러한 메소드는 Create(...) 메소드에서 순차적으로 호출됩니다.
//+------------------------------------------------------------------+ //| Creation | //+------------------------------------------------------------------+ bool CPanelDialog::Create(const long chart,const string name,const int subwin, const int x1,const int y1,const int x2,const int y2) { //--- calling the parent class method if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2)) return(false); //--- creating additional elements if(!CreateColor()) return(false); if(!CreateRed()) return(false); if(!CreateGreen()) return(false); if(!CreateBlue()) return(false); //--- success return(true); }
컨트롤 생성
모든 추가 컨트롤 생성을 검토하지는 않지만 bool CreateBlue(void) 메소드에 대해 자세히 살펴 보겠습니다.
다음과 같습니다.
//+------------------------------------------------------------------+ //| Creating the "Blue" control with explanatory caption | //+------------------------------------------------------------------+ bool CPanelDialog::CreateBlue(void) { //--- coordinates int x1=INDENT_LEFT; int y1=INDENT_TOP+2*(EDIT_HEIGHT+CONTROLS_GAP_Y); int x2=x1+EDIT_WIDTH; int y2=y1+EDIT_HEIGHT; //--- creating the caption if(!m_label_blue.Create(m_chart_id,m_name+"LabelBlue",m_subwin,x1,y1+1,x2,y2)) return(false); if(!m_label_blue.Text("Blue")) return(false); if(!Add(m_label_blue)) return(false); //--- adjusting coordinates x1+=LABEL_WIDTH+CONTROLS_GAP_X; x2=x1+EDIT_WIDTH; //--- creating the control if(!m_edit_blue.Create(m_chart_id,m_name+"Blue",m_subwin,x1,y1,x2,y2)) return(false); if(!Add(m_edit_blue)) return(false); m_edit_blue.MinValue(BASE_COLOR_MIN); m_edit_blue.MaxValue(BASE_COLOR_MAX); m_edit_blue.Value(m_blue); //--- success return(true); }
두 가지 뉘앙스가 있습니다.
- 컨트롤은 상대 좌표로 생성됩니다. 즉, 오프셋은 생성 후 컨트롤이 추가 될 컨테이너 (복잡한 요소)의 왼쪽 상단 모서리를 기준으로 설정됩니다.
- 생성 후에는 Add(...) 메소드를 사용하여 컨테이너에 컨트롤을 추가해야 합니다. 저희의 경우 대화 상자가 컨테이너 역할을 합니다.
매개 변수 변경
색상 패널의 색상을 변경하려면 void SetColor(void) 메소드를 추가합니다.
매개 변수 (기본 색상의 수준)를 외부에서 변경할 수 있도록 세 가지 공개 메소드를 추가합니다.
- void SetRed(const int value) - "Red" 레벨을 변경하고 인디케이터의 변경 사항을 표시합니다.
- void SetGreen(const int value) - "Green" 레벨을 변경하고 인디케이터의 변경 사항을 표시합니다.
- void SetBlue(const int value) - "Blue" 레벨을 변경하고 인디케이터에 변경 사항을 표시합니다.
"인디케이터의 변화를 표시합니다" 라는 문구는 기본 색상 수준의 새 값이 해당 컨트롤에 숫자 형식으로 표시되고 색상 패널이 색상을 변경함을 의미합니다.
다음은 예제로 사용할 메소드 중 하나의 코드입니다.
//+------------------------------------------------------------------+ //| Setting the "Red" value | //+------------------------------------------------------------------+ void CPanelDialog::SetRed(const int value) { //--- checking if(value<0 || value>255) return; //--- saving m_red=value; //--- setting m_field_red.Text(IntegerToString(value)); //--- setting the panel color SetColor(); }
위에서 동의한대로 :
원래 인디케이터에 관련 코드를 추가해 보겠습니다.
//+------------------------------------------------------------------+ //| PanelIndicator.mq5 | //| Copyright 2011, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2011, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property indicator_separate_window #property indicator_plots 0 #property indicator_buffers 0 #property indicator_minimum 0.0 #property indicator_maximum 0.0 //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "PanelDialog.mqh" //+------------------------------------------------------------------+ //| Global variables | //+------------------------------------------------------------------+ CPanelDialog ExtDialog; //+------------------------------------------------------------------+ //| Initialization | //+------------------------------------------------------------------+ int OnInit() { //--- creating the application dialog if(!ExtDialog.Create(0,"Panel Indicator",0,0,0,0,130)) return(-1); //--- starting the application if(!ExtDialog.Run()) return(-2); //--- creating the timer EventSetTimer(1); //--- success return(0); } //+------------------------------------------------------------------+ //| Deinitialization | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- destroying the dialog ExtDialog.Destroy(); //--- killing the timer EventKillTimer(); } //+------------------------------------------------------------------+ //| Iteration | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) { //--- changing the dialog property ExtDialog.SetRed(MathRand()%256); //--- returning the prev_calculated value for the next call return(rates_total); } //+------------------------------------------------------------------+ //| Timer event handler | //+------------------------------------------------------------------+ void OnTimer() { //--- changing the dialog property ExtDialog.SetGreen(MathRand()%256); } //+------------------------------------------------------------------+ //| Chart event handler | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- handling the event ExtDialog.ChartEvent(id,lparam,dparam,sparam); } //+------------------------------------------------------------------+
이벤트 처리
대화 상자와 터미널 간의 전체 상호 작용과 대화 컨트롤 간의 상호 작용은 이벤트 메커니즘을 기반으로 합니다. 저희는 그 기능을 검토하지 않고 단순히 사용합니다.
이벤트는 일반적으로 두 그룹으로 나눌 수 있습니다.
- 터미널 이벤트 큐를 우회하여 처리되는 내부 이벤트;
- 터미널 이벤트 큐를 통해 처리되는 외부 이벤트.
두 가지 유형의 이벤트를 모두 처리합니다.
내부 이벤트 중 대화 상자 크기 조정 이벤트 만 처리하면됩니다. 이를 위해 부모 클래스의 OnResize() 메소드를 다시 로드합니다. 저희의 방법은 대화 높이에 변화가 없기 때문에 간단합니다. 대화 상자 너비가 변경되면 색상 패널 너비 만 수정하면됩니다.
//+------------------------------------------------------------------+ //| Resize handler | //+------------------------------------------------------------------+ bool CPanelDialog::OnResize(void) { //--- calling the parent class method if(!CAppDialog::OnResize()) return(false); //--- changing the color panel width m_color.Width(ClientAreaWidth()-(INDENT_RIGHT+LABEL_WIDTH+CONTROLS_GAP_X+EDIT_WIDTH+CONTROLS_GAP_X+INDENT_LEFT)); //--- success return(true); }
외부 이벤트 목록도 "Blue" 레벨을 변경하는 이벤트 인 한 항목으로 제한됩니다. 외부 이벤트 핸들러에 대한 요구 사항은 최소한입니다. 핸들러는 void 유형의 매개 변수없는 클래스 메소드여야 합니다.
이 이벤트의 핸들러를 설명하겠습니다.
//+------------------------------------------------------------------+ //| Handler of the event of changing the "blue" level | //+------------------------------------------------------------------+ void CPanelDialog::OnChangeBlue(void) { //--- saving m_blue=m_edit_blue.Value(); //--- setting the panel color SetColor(); }
보시다시피 어려운 것은 없습니다.
대화 상자에서 외부 이벤트를 처리하려면 부모 클래스 메소드를 다시 로드해야 합니다.
virtual bool OnEvent(const int id,const long &lparam, const double &dparam,const string &sparam);
그리고 이제 약간의 미스터리가 남았습니다. Editor에서 PanelDialog.mqh 파일을 이미 연 경우 OnEvent(...) 메소드 본문이 없음을 알 수 있습니다.
혼동하지 마십시오. 외부 이벤트 처리에 대한 설명은 일련의 매크로가 생성되었습니다 (표준 라이브러리의 <Controls\Defines.mqh> 파일 참조).
이벤트 핸들러는 다음과 같습니다.
//+------------------------------------------------------------------+ //| Handling events | //+------------------------------------------------------------------+ EVENT_MAP_BEGIN(CPanelDialog) ON_EVENT(ON_CHANGE,m_edit_blue,OnChangeBlue) EVENT_MAP_END(CAppDialog)
처음에는 명확하지 않을 수 있는 이 유사 코드는 다음을 수행합니다.
- m_edit_blue 컨트롤에서 ON_CHANGE 이벤트가 수신되면 OnChangeBlue 메소드가 호출되고 이벤트 처리가 완료됩니다 (true 반환).
- 다른 이벤트를 수신하면 컨트롤가 상위 클래스 메소드로 전송됩니다.
결론
이 표준 라이브러리 클래스를 사용하여 디스플레이 패널을 만드는 과정에 대한 검토를 제공했습니다.
생성된 대로 지표를 사용할 가능성은 낮지만 불필요한 정보로 과부하가 걸리지 않으며 생성 할 때 프로세스의 거의 모든 특성을 다룰 수 있었습니다.
더 복잡한 표준 배송 예제는 터미널의 다음 디렉토리에서 찾을 수 있습니다.
- Experts\Examples\Controls\
- Indicators\Examples\Panels\ChartPanel\
- Indicators\Examples\Panels\SimplePanel\
MetaQuotes 소프트웨어 사를 통해 러시아어가 번역됨.
원본 기고글: https://www.mql5.com/ru/articles/345