Попробуйте сначала через поиск в MetaEditor
Спасибо, но, это я уже находил, попытался еще раз взглянуть на код и даже подебажить, мой код выполняется точно также, без единой ошибки, ни один метод не возвращает FALSE и т.д., но список не выпадает по клику ...
Переписал один в один из примера :
CurrencyBox = new CCurrencyBox(); CurrencyBox.Create(ChartID(), "Demo", ChartWindow, selectorX, selectorY, selectorX + selectorWidth, selectorY + selectorHeight); int total=SymbolsTotal(true); for (int i=0;i<total;i++) if (!CurrencyBox.ItemAdd(SymbolName(i,true))) { Print("Error"); } CurrencyBox.SelectByText(Symbol()); CurrencyBox.Alignment(WND_ALIGN_RIGHT, 0,0,11,0);
После добавления вызова метода SelectByText() в комбо боксе появилась одна валюта, но выпадающий список так и не появляется по клику. Suggestions?
И тогда вопрос вдогонку - можно ли размещать выпадающий список прямо на графике или обязательно делать его приватным свойством диалога?
Только что поробовал создать ListView - элементы добавляются, похоже просто не раотают события ... точки останова внутри обработчиков событий ComboBox не срабатывают, т.е. сообщения о том, что я кликнул на комбо-боксе просто не посылаются. Почему?
Покажите код (в т.ч. обработчика событий).
А вообще - готовьтесь к долгим увлекательным часам изучения особенностей стандартной библиотеки ;)
Примеров к ней - минимум, документация, в основном, формальная. Поэтому постоянно приходится изучать внутренности и догадываться о возможном поведении.
![Документация по MQL5: Стандартная библиотека Документация по MQL5: Стандартная библиотека](/i/community/logo_mql5_small.png)
- www.mql5.com
Спасибо за интерес к теме. Да, я примерно так и понял ... долгие увлекательные часы ...
Так как именно вы заинтересовались этой темой, я вспомнил, что вас и еще группу разработчиков интересовала тема синхронизации пропущенных баров по времени ... поэтому в целях удовлетворения интереса выкладываю индикатор целиком (мат.значения еще не закончены + надо протестировать на рабочем рынке, а сейчас выходные, но вцелом вроде работает правильно)
Вобщем, данный индикатор - это корреляция валют, кол-во валют задаете в виде строки с разделителем во входных параметрах, пока что кол-во буферов ограничено 9ю. Вас могут заинтересовать функции Synchronize() и GetBarByTime() - это собственно синхронизация.
Теперь, что касается моего вопроса - я хотел сделать выбор валюты для которой будет считаться корреляция с другими с помощью комбо бокса, сначала попытался отнаследоваться от базового класса создав свой CCurrencyBox, но решил, что слишком много головняка + в примерах метаквотов они CComboBox используют без наследования от него, просто создают инстанс базового класса, поэтьому я убрал свой класс и создаю инстанс базового CComboBox - НИЧЕГО не меняется, айтемы добавляются, но событие клика не посылается.
Т.е. сейчас я просто использую стандартный класс CComboBox и его стандартные обработчики событий, все равно не работает, что дебажить, в какую сторону копать - понятия не имею и как продебажить отправление сообщений о событии если дебагер даже не попадает внутрь обработчика - я не знаю. Вот что используется сейчас в методе PrepareControls() (создание инстанса и все, обработчики - не перекрываются, используются станартные метаквотовские) :
CComboBox * CurrencyBox; void PrepareControls() { long chartWidth = ChartGetInteger(ChartID(), CHART_WIDTH_IN_PIXELS, ChartWindow); double chartShift = chartWidth * ChartGetDouble(ChartID(), CHART_SHIFT_SIZE, ChartWindow) / 100; int selectorX = int(chartWidth - chartShift + 115); int selectorY = 12; int selectorWidth = 100; int selectorHeight = 20; CurrencyBox = new CComboBox(); CurrencyBox.Create(ChartID(), "Demo", ChartWindow, selectorX, selectorY, selectorX + selectorWidth, selectorY + selectorHeight); for (int i = 0; i < Currencies.Total(); i++) { CurrencyBox.ItemAdd(SymbolName(i,true)); } }
Как видите, инстанс создается на основе CComboBox, а значит и обработчики должны срабатывать из файла Controls\ComboBox.mqh - но НЕ срабатывают - по клику стрелочка выпадающего списка меняется, но сам список не появляется, даже если принудительно вызвать CurrencyBox.Show()
Обработчики - стандартные, НЕ мои :
EVENT_MAP_BEGIN(CComboBox) ON_EVENT(ON_CLICK,m_edit,OnClickEdit) ON_EVENT(ON_CLICK,m_drop,OnClickButton) ON_EVENT(ON_CHANGE,m_list,OnChangeList) CheckListHide(id,(int)lparam,(int)dparam); EVENT_MAP_END(CWndContainer) bool CComboBox::OnClickEdit(void) { //--- change button state if(!m_drop.Pressed(!m_drop.Pressed())) return(false); //--- call the click on button handler return(OnClickButton()); } //+------------------------------------------------------------------+ //| Handler of click on button | //+------------------------------------------------------------------+ bool CComboBox::OnClickButton(void) { //--- show or hide the drop-down list depending on the button state return((m_drop.Pressed()) ? ListShow() : ListHide()); } //+------------------------------------------------------------------+ //| Handler of click on drop-down list | //+------------------------------------------------------------------+ bool CComboBox::OnChangeList(void) { string text=m_list.Select(); //--- hide the list, depress the button ListHide(); m_drop.Pressed(false); //--- set text in the main entry field m_edit.Text(text); //--- send notification EventChartCustom(m_chart_id,ON_CHANGE,m_id,0.0,m_name); //--- handled return(true); }
Если будете открывать в терминале индикатор, то подключаемый файл статистики можно взять отсюда - https://www.mql5.com/ru/articles/387
![Документация по MQL5: Стандартная библиотека / Классы для создания панелей и диалогов / CComboBox Документация по MQL5: Стандартная библиотека / Классы для создания панелей и диалогов / CComboBox](/i/community/logo_mql5_small.png)
- www.mql5.com
Я не пробовал создавать комбобокс без родителя, он у меня является частью панели, как и в метаквотовском примере (ControlsDialog.mqh).
А тогда обработчик выбора другого варианта выглядит так:
EVENT_MAP_BEGIN(CControlsDialog) ON_EVENT(ON_CHANGE,m_combo_box,OnChangeComboBox) EVENT_MAP_END(CAppDialog)
void CControlsDialog::OnChangeComboBox(void) { Alert(__FUNCTION__+" \""+m_combo_box.Select()+"\""); }
Попробуйте оттолкнуться от готового (как-бы работающего) примера метаквотов, и удаляйте все лишнее, пока не перестанет работать.
причина найдена - сюрприз - это нельзя реализовать без диалогового окна :)
1. моей первой ошибкой было то, что я не добавил в индикатор основной обработчик событий чарта - оно транслирует событие клика по графику на выбранные дочерние элементы, в моем случае demo.OnEvent() - событие выпадалки
void OnChartEvent( const int id, const long &lparam, const double &dparam, const string &sparam) { //CurrencyBox.OnEvent(id, lparam, dparam, sparam); demo.OnEvent(id, lparam, dparam, sparam); }
2. подебажив еще немного я дошел наконец-то до макросов, описывающих какой обработчик реагирует на какое событие и там есть такая вот проверка
#define ON_EVENT(event,control,handler) if(id==(event+CHARTEVENT_CUSTOM) && lparam==control.Id()) { handler(); return(true); }
Это означает, что событие сработает только если в эотй проверке параметр lparam будет равен реальному ID контрола, который это событие вызвал ... но есть одна проблема ... у контрола есть метод control.Id() который всегда возвращает -1 ... до тех пор пока он не станет дочерним, т.е. пока не будет добавлен методом Add() к диалоговому окну.
Я попытался отнаследоваться от класса CComboBox и создать свой макрос, который не будет проверять ID контрола, а просто молча вызывать событие для него ... и о чудо - выпадалка наконец-то выпала ... НО ... теперь уже не работает клик по выпавшему списку, т.е. чтобы такая система работала без наличия диалогового окна необходимо перекрывать каждый из классов используемых в классе CComboBox ... проще все же использовать Диалог
И последнее - ответ на мой предыдущий вопрос : И тогда вопрос вдогонку - можно ли размещать выпадающий список прямо на графике или обязательно делать его приватным свойством диалога?
Нет, нельзя, контролы, которые не были добавлены внутрь какого-либо диалогового окна работать НЕ будут. Тему можно закрывать.
Тему можно закрывать.
И открывать заявку в сервис-деск, чтоб убрали это искусственное ограничение.
Не поленитесь, они действительно воплощают толковые предложения.
Тему можно закрывать.
Все контролы должны быть добавлены в CAppDialog ("дети", "внуки", "внучатые племянники" и т.д.).
После вызова CAppDialog::Run(), контролам раздаются идентификаторы. Дальше события будут работать.
А вообще - готовьтесь к долгим увлекательным часам изучения особенностей стандартной библиотеки ;)
зато интересно )) в учебный целях самое оно ))
в справке нужно дописать, что метод Select, может не только bool возвращать, но и string. хорошо что Alt + G есть, а то часы могут в сутки превращатся ))
![MQL5 - Язык торговых стратегий для клиентского терминала MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Привет,
Есть ли у кого ссылки на то как правильно создавать, заполнять и реагировать на события CComboBox.
Создаю его так :
Он появляется, но заполнить данными не получается - он всегда пустой, при этом даже Width / Height не меняются.
В результате вижк такую картину :
Спасибо, Артем