Функция МЕНЮ(). Управление работой программ (+ вывод информации).
При работе программы (советника, индикатора, скрипта) часто возникает желание (необходимость) изменить какие-то параметры, управлять работой функций, запускать или отключать участки кода, выводить информацию о работе программы. Такое управление удобно осуществлять с помощью графических объектов на графике, и есть множество решений этого, например, от простого управления уровнями ордеров с помощью горизонтальных линий до целых программных комплексов.
Для себя я разработал достаточно универсальную функцию, с помощью которой можно легко создавать Меню с произвольным набором пунктов и встраивать его в любые программы. Меню выводится на график в виде Курсора (двойной стрелки), Заголовка и вертикального списка Пунктов меню; (а также - при желании - вертикального списка значений актуальных переменных программы).
Пункты меню - могут быть трех видов: 1. Run(Выполнить)(Кнопка без фиксации). 2. CheckBox(Включить/Отключить)(Кнопка с фиксацией). 3. RadioButton(Выбор одного из пунктов)(Переключатель).
Перечень возможных действий с Меню: 1. Выбор пункта меню - выделяем двойную стрелку (курсор Меню), перетаскиваем и бросаем её на нужный Пункт. (1а.При этом произойдёт подтверждение выбора - выбранный пункт кратковременно изменит свой цвет). 2. Перемещение Меню - выделяем Заголовок меню и перетаскиваем его на требуемое место на графике. (2а.Вслед за заголовком при его передвижении будет перемещаться всё Меню). 3. Свернуть/Развернуть Меню - выделяем двойную стрелку, перетаскиваем и бросаем её на Заголовок меню. (3а.Таким образом можно скрыть все пункты Меню, сворачивая его до одного Заголовка). 4. Активность Меню - задается внутри функции, можно привязать к любому пункту, который отвечает за работу (активность) какой-либо функции или алгоритма. (4а.Влияет на цвет Заголока (Активный или Неактивный). Наглядно отображает, работает или отключена эта функция/алгоритм, даже в случае свёрнутого Меню. Например, в демо-скрипте привязана к первому пункту Меню). 5. Восстановление исходного положения Меню (после перемещений) - выделяем двойную стрелку и удаляем её (кнопкой Delete или через контекстное меню).
Практически весь код, от инициализации пунктов Меню, логической обработки их, и до выдачи результата (номера выбранного пункта) помещён в одну функцию. Это очень упрощает встраивание Меню в любую программу. Остается лишь поместить функцию в программу, задать начальные параметры и список пунктов Меню. И затем в программе нужно просто опрашивать состояние пунктов Меню и управлять ее работой в зависимости от их состояния. Также легко можно встроить не одно, а несколько Меню, поместив нужное количество функций и настроив их; при желании можно создавать даже вложенные Меню. Для универсальности и корректной работы в индикаторах, все временные задержки формируются посредством GetTickCount(), а не Sleep().
В этом посте я выкладываю текущую версию функции Menu(v00) в составе демо-скрипта. Скрипт выводит на экран описание основных приёмов работы с Меню, с тем чтобы можно было освоить функцию, поработав с ней вживую. В следующих постах планирую написать инструкцию по встраиванию функции в программу, привести другие примеры использования функции, в том числе с выводом информации (значений переменных). По мере усовершенствования функции буду выкладывать новые версии. Например, можно сделать отсчет координат не от нулевого угла, а любого из четырех; можно добавить возможность ввода числовых значений; для индикаторов и скриптов можно подумать над возможностью выполнения всех действий функции за один тик.
П.С. Просьба писать лишь по существу, желательно конкретные вопросы и предложения. Ваши предложения и замечания постараюсь учитывать в новых версиях. Сорри за стиль кодирования, т.к. осваивал МТ4 и работаю сейчас на нетбуке с выводом 20 строк на экран, и привык уже к такому компактному стилю, мне так даже комфортнее.
- Использование аналитических объектов - Графики котировок, технический и фундаментальный анализ
- Профилирование кода - Разработка программ
- Торговые советники и собственные индикаторы - Алгоритмический трейдинг, торговые роботы
Удобная и полезная прога. Надо поместить в кодобазу. Я обычно управляю своим советником с помощью набора скриптов включающих необходимые глобальные переменные, которые опрашиваются советником и он выполняет те или иные действия. Ваш способ, наверно, более удобный и наглядный. А вообще было бы удобней, если бы открывалось окно с пунктами меню. Но это видимо можно сделать только с использованием длл.
Есть еще вот такой вариант - перетаскиваем звездочки на нужную опцию и управляем ею.
Удобная и полезная прога. Надо поместить в кодобазу. . А вообще было бы удобней, если бы открывалось окно с пунктами меню. Но это видимо можно сделать только с использованием длл.
В базу помещать наверно рано, я совсем недавно разработал эту функцию, работаю над ней дальше, и планирую помещать сюда новые версии; и уже после обкатки на этом форуме можно будет и выложить. А сейчас готова следующая версия, покажу ее чуть позже.
Насчет отдельного окна и ДЛЛ. Думаю, новая версия функции во многом учитывает это пожелание, причем вполне обходится средствами МТ4. По аналогии с окнами, Меню теперь выводится на передний план на цветном фоне , закрывая под собой почти все другие объекты, может перемещаться по графику, может закрываться, точнее сворачиваться до Заголовка Меню. По умолчанию правильнее задавать такие настройки функции, чтобы Заголовок был прижат к верхнему (как вариант - к нижнему) краю графика, а Меню было свёрнуто - то есть максимально соответствовать привычному стандартному расположению меню (и даже в таком виде по цвету Заголовка мы будем знать, работает ли заданная функция (алгоритм или вся программа) или отключена). Если же Меню сворачивать нежелательно, то удобнее всего будет прижать его к левому краю графика.
Есть одна большая проблема в четверке (подходе к программированию) - все пытаются решить только свою проблему, и видят ситуацию со своей колокольни. Проблема в несовместимости подходов (кодов). будь в четверке модель ООП - таких бы проблем не было.
1) Вы уверены в том, что кто то другой сможет эфективно применить вашу разработку (хотя бы просто разобраться в коде) ?
2) Вы уверены в том, что ваша графика не будет мешать другой - даже вашей же, и ее не придется кардинально переделывать каждый раз ?
3) Вы уверены в том, что пользователь незнакомый с вашим меню сможет им пользоваться без предварительного обучения ?
4) Вы уверены в том, что это будет работать всегда и везде ?
Вот когда сможете ответить хотя бы на эти главные вопросы утвердительно - тогда и продвигайте Ваш продукт в массы, а так мы только о реализации с вами тут говорим.
А красивостей на этом форуме могут делать, только мало то выкладывает, и даже не из жадности, а хотя бы потому что не уверен в ответах.
Удобная и полезная прога. Надо поместить в кодобазу. Я обычно управляю своим советником с помощью набора скриптов включающих необходимые глобальные переменные, которые опрашиваются советником и он выполняет те или иные действия. Ваш способ, наверно, более удобный и наглядный. А вообще было бы удобней, если бы открывалось окно с пунктами меню. Но это видимо можно сделать только с использованием длл.
В самом начале обещал написать инструкцию по подключению функции Меню. Тут обозначу основные моменты, чтобы было понятно, для чего и как её можно использовать. А пошаговые, конкретные, привязанные к данной, конкретной версии пояснения планирую сделать в ближайшем времени, в самОм тексте кода.
___ПОДКЛЮЧЕНИЕ ФУНКЦИИ МЕНЮ() В ПРОГРАММУ___ Функция Меню позволяет организовать удобное управление любой программой (советник, индикатор, скрипт), и использует три стандартных типа интерактивных управляющих элементов: 1. Run(Выполнить)(Кнопка без фиксации). 2. CheckBox(Включить/Отключить)(Кнопка с фиксацией). 3. RadioButton(Выбор одного из пунктов)(Переключатель).
Итак, сначала копируем функцию MenuAАА() в код нашей программы, работой которой нам нужно управлять. Затем начинаем настраивать функцию под свои требования. Те строки кода, которые требуют обязательной настройки, помечены в конце строки символами "<. >", а которые могут быть изменены при желании или необходимости - символами "(<!>)".
Вначале задаём глобальные переменные программы, они помещаются в самом её начале, перед всеми функциями и определяют основные параметры Меню по умолчанию - координаты и вид Меню (свёрнуто-развёрнуто), а также массив флагов, отражающий текущее состояние пунктов Меню.
В теле самой функции прежде всего мы должны задать Заголовок и список Пунктов Меню, в виде строковых переменных, причем три первых символа строго и однозначно определяют тип пункта Меню:
1. " " (три пробела) - это Run(Выполнить)(Кнопка без фиксации). 2. "[ ]/[v]" - это CheckBox(Включить/Отключить)(Кнопка с фиксацией). 3. "( )/(о)" - это RadioButton(Выбор одного из пунктов)(Переключатель).
При этом 2й и 3й тип задают состояние этих пунктов (включен/отключен) по умолчанию. В случае использования 3го типа, в разделе функции "ЛОГИКА ОБРАБОТКИ ПУНКТОВ МЕНЮ" мы также должны задать матрицу обработки пунктов этого типа.
___УПРАВЛЕНИЕ ПРОГРАММОЙ С ПОМОЩЬЮ ФУНКЦИИ МЕНЮ()___ Обращение к функции (её вызов) следует поместить один раз, где-нибудь в начале функции start(), до того, как мы будем обрабатывать результат ее работы. Далее, в любом месте нашей программы, в любой другой её функции, мы можем управлять работой программы, опрашивая значения переменных, формируемых функцией Меню: a) Основной способ - использует массив флагов AAA[1]. AAA[N]; флаги отражают текущее состояние N пунктов Меню. Например, If(AAA[5]). сработает, если 5й пункт Меню был выбран/включен, If(!AAA[5]). - наоборот. b) Вспомогательный способ - использует значение, возвращаемое функцией int Z=MenuAAA(); оно равно номеру выбранного пункта, его можно использовать как признак выбора одного (конкретного) или любого из пунктов, группы пунктов (например, группы пунктов RadioButton). А также для организации более сложной логики взаимодействия пунктов Меню между собой. c) Вспомогательный способ - использует значение флага AAA[0]; этот флаг содержит признак работы пользователя с Меню. Флаг AAA[0] поднимается, если выполняются любые действия с Меню (выбор пункта, перемещение курсора Меню, сворачивание Меню).
В качестве примера прилагается простой демо-скрипт, включающий в себя и использующий функцию MenuAAA(). Скрипт поможет разобраться и понять принципы управления программами с помощью функции Меню. Вот вся функция start() в этом демо-скрипте - вызов функции Меню, опрос флагов AАА[N] - всё очень просто, если не сказать элементарно!
В данной версии в функцию добавлен код, который рисует фон под пунктами Меню, имитируя таким образом вывод Меню в отдельном окне. Отрисовка фона также поддерживает опцию Активность меню (подробнее см. первый пост) - так, если Меню не активно, тогда и Заголовок и фон Меню будет серого цвета; в демо-скрипте Активность Меню привязана к первому пункту Меню. Ещё в новой версии изменена идентификация (индексирование) имён функции и её переменных - не одной буквой (MenuA(), A[0]), а тремя (MenuAAA(), AAA[0]), для того чтобы можно было создавать клоны функции практически одним кликом (например, MenuВВВ(), ВВВ[0]) с помощью простой замены.
На следующем рисунке приведён пример использования в разрабатываемом советнике сразу четырёх Меню, каждое для своего алгоритма; на рисунке наглядно показаны различные состояния Меню, с привязкой Активности меню к первому пункту. Там же можно увидеть использование дополнительной сервисной функции MenuComment(), для вывода информации (актуальных параметров и переменных алгоритма) отдельно в каждом окошке Меню. При перемещении Заголовка вместе с ним будет перемещаться единым блоком и само Меню и выводимая информация (MenuComment).