Sergey Eremin: Спасибо за ответ и понимание! Если я не ошибаюсь, то в одной из статей я видел Ваше решение. Если так, то, надеюсь, Вы не будете сильно возражать, если я напишу статью целиком полностью про утверждения и сделаю ссылку на Вас, как на пример применения оных (и если не будете против, то очень прошу скинуть сюда или в личку ссылку на ту статью)?
Ну и как человеку, понимающему мою задачу, отдельная просьба - оцените сам мой макрос (третье сообщение ветки), как оно Вам? Может что-то режет глаз?
В общем-то я статей не публиковал, поэтому не очень понятно, о какой ссылке идет речь. Хотя хальт выдернут действительно из кода моей забракованной статьи.
Что касается макроса, наверно он сгодится, хотя я не люблю таких многострочных дефайнов. Понятно, что экономится вызов, но с точки зрения читабельности в контексте статьи... И потом у меня сомнения относительно диалогов сообщений - если ассертов будет много подряд (например, в цикле), пользователь не успеет ответить на первый запрос, как появится следующий (если я ничего не путаю). В общем нужно как-то сделать более дружественно.
В общем-то я статей не публиковал, поэтому не очень понятно, о какой ссылке идет речь. Хотя хальт выдернут действительно из кода моей забракованной статьи.
Что касается макроса, наверно он сгодится, хотя я не люблю таких многострочных дефайнов. Понятно, что экономится вызов, но с точки зрения читабельности в контексте статьи... И потом у меня сомнения относительно диалогов сообщений - если ассертов будет много подряд (например, в цикле), пользователь не успеет ответить на первый запрос, как появится следующий (если я ничего не путаю). В общем нужно как-то сделать более дружественно.
Видимо, ошибся насчёт статьи. Просто сейчас и сам не могу найти ту статью, но точно помню, что там был не макрос, а функция.
Преимущества макроса в основном такие: можно вывести выражение (#condition), имя файла (__FILE__), сигнатуру функции (__FUNCSIG__) и номер строки (__LINE__), где утверждение оказалось ложным. Получается примерно как на картинке. При варианте с функцией этих всех вкусностей уже не будет, придётся как-то через параметр указывать место в программе так, чтобы оно оставалось понятным программисту.
А насчёт диалога - задумка такая: если нажать "No", т.е. ответ на вопрос "Continue?" будет "No", то программа завершается, и последующие диалоги не будут выданы (см. UPD).
Спасибо!
UPD: посмотрел вариант с циклом и, похоже, ExpertRemove тоже не годится, т.к. в случае с циклом он не моментально грохнет программу, а дождётся окончания цикла (выдаст все диалоговые окна). Только хардкор, только ошибки времени выполнения :(
Преимущества макроса в основном такие: можно вывести выражение (#condition), имя файла (__FILE__), сигнатуру функции (__FUNCSIG__) и номер строки (__LINE__), где утверждение оказалось ложным. Получается примерно как на картинке. При варианте с функцией этих всех вкусностей уже не будет, придётся как-то через параметр указывать место в программе так, чтобы оно оставалось понятным программисту.
А насчёт диалога - задумка такая: если нажать "No", т.е. ответ на вопрос "Continue?" будет "No", то программа завершается, и последующие диалоги не будут выданы (см. UPD).
UPD: посмотрел вариант с циклом и, похоже, ExpertRemove тоже не годится, т.к. в случае с циклом он не моментально грохнет программу, а дождётся окончания цикла (выдаст все диалоговые окна). Только хардкор, только ошибки времени выполнения :(
Про преимущества макроса понятно. У меня тоже был макрос, но короткий - в нем содавался специальный объект куда эти все __FUNCSIG__ и прочее передавалось, а потом использовалось. Не столь эффективно, конечно.
Задумка про диалог тоже понятна, только у меня по-прежнему и в новом варианте впечатление, что в цикле будут множиться боксы.
Про преимущества макроса понятно. У меня тоже был макрос, но короткий - в нем содавался специальный объект куда эти все __FUNCSIG__ и прочее передавалось, а потом использовалось. Не столь эффективно, конечно.
Задумка про диалог тоже понятна, только у меня по-прежнему и в новом варианте впечатление, что в цикле будут множиться боксы.
Я проверил на таком коде:
#property version"1.00"#include <assert.mqh>
//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+ intOnInit()
{
//---for(int i = 0; i < 1000; i++)
{
assert(0 > 1, "test message 001");
}
//---return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
//---
}
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
//---
}
Т.к. MessageBox приостанавливает поток программы (в отличие от алертов), то до следующего варианта не доходит. По крайней мере в MT5 1159 это верно.
Но и этот вариант уже не вариант: вспомнилось, что MessageBox не работают в индикаторах. Так что теперь крайний вариант:
Т.е. просто выдаём алерт и грохаем приложение, без всякого взаимодействия с пользователем.
Кстати, не хотелось связываться с ошибками времени выполнения отчасти потому, что если мы это проделываем в индикаторе, который существует в отдельном подокне, то это самое подокно останется. Т.е. индикатор прибъётся, но его подокно никуда не денется. Вынужденное зло?
Т.к. MessageBox приостанавливает поток программы (в отличие от алертов), то до следующего варианта не доходит. По крайней мере в MT5 1159 это верно.
Но и этот вариант уже не вариант: вспомнилось, что MessageBox не работают в индикаторах. Так что теперь крайний вариант:
Т.е. просто выдаём алерт и грохаем приложение, без всякого взаимодействия с пользователем.
Кстати, не хотелось связываться с ошибками времени выполнения отчасти потому, что если мы это проделываем в индикаторе, который существует в отдельном подокне, то это самое подокно останется. Т.е. индикатор прибъётся, но его подокно никуда не денется. Вынужденное зло?
В принципе, тип программы можно узнать и в зависимости от этого либо выдавать бокс (в эксперте), либо нет. Только насчет приостановления потока я б все-таки проверил случай не в OnInit, а где-нибудь в OnTick.
С пятеркой сейчас не работаю, а вот в четверке у меня подокно после ошибки в индюке пропадает. Может быть это зависит от типа ошибки. Попробуйте вызвать out of bounds.
В принципе, тип программы можно узнать и в зависимости от этого либо выдавать бокс (в эксперте), либо нет. Только насчет приостановления потока я б все-таки проверил случай не в OnInit, а где-нибудь в OnTick.
С пятеркой сейчас не работаю, а вот в четверке у меня подокно после ошибки в индюке пропадает. Может быть это зависит от типа ошибки. Попробуйте вызвать out of bounds.
Раз в MT4 (или и в MT5) возможно такое поведение (всё же решение универсальным предполагается), то, я думаю, что теперь ни к чему усложнять с MessageBox'ами. Но я попроверяю ещё. Out of bounds привёл к тому же побочному эффекту, но думаю это не смертельно. Главное, это описать в статье (если с таким кошмаром вообще одобрят).
В принципе решение, пусть и самое грустное, найдено, так что всем откликнувшемся спасибо. Особенно Вам, Станислав. Вы очень здорово помогли!
Igor Konyashin: Посмотрите эту тему, может подойдет? (касаемо индикатора)
Спасибо!
В данном примере идёт отталкивание от допущения, что в первом подокне наш индикатор будет первым (насколько видно по ChartIndicatorName(0, 1, 0)).
Однако, боюсь, это не универсально: мы заранее не знаем ни в каком подокне окажется наш индикатор, ни каким он будет там по счёту. Так можно снова вернуться к задаче "узнать короткое имя индикатора". И частный способ решения есть в указанной Вами ветке - запомнить в глобальную переменную, а хотелось бы общий :)
Но по крайней мере предположение Михаила в последнем сообщении кажется вполне логичным касательно того, почему окно индикатора остаётся висеть.
А в любом месте кода ( когда Вам нужно остановить работу советника),
присваиваете переменной значение true
Михаил, а почему Ваш код приведет к остановке работы советника?? Тут же просто выход из OnTick, советник как работал, так и будет работать, только в холостую.
Михаил, а почему Ваш код приведет к остановке работы советника?? Тут же просто выход из OnTick, советник как работал, так и будет работать, только в холостую.
Я так понял, автору вопроса надо ExpertRemove()? Пример из справки.
Я думал, что мне было надо нечто подобное ExpertRemove(), но для индикаторов и скриптов.
Но оказался безбожно неправ: если мне нужно грохнуть программу на некоей итерации цикла и я для этого попробую вызвать ExpertRemove, то я не получу ожидаемого: все последующие итерации всё равно выполнятся (вставить break тоже не пойдёт - это нарушит принцип универсальности макроса, т.к. он будет использоваться не только в циклах).
Так что пока крайнее решение для аварийной остановки программы в произвольном месте - вызов ошибки времени выполнения (к примеру, деление на ноль).
Спасибо за ответ и понимание! Если я не ошибаюсь, то в одной из статей я видел Ваше решение. Если так, то, надеюсь, Вы не будете сильно возражать, если я напишу статью целиком полностью про утверждения и сделаю ссылку на Вас, как на пример применения оных (и если не будете против, то очень прошу скинуть сюда или в личку ссылку на ту статью)?
Ну и как человеку, понимающему мою задачу, отдельная просьба - оцените сам мой макрос (третье сообщение ветки), как оно Вам? Может что-то режет глаз?
В общем-то я статей не публиковал, поэтому не очень понятно, о какой ссылке идет речь. Хотя хальт выдернут действительно из кода моей забракованной статьи.
Что касается макроса, наверно он сгодится, хотя я не люблю таких многострочных дефайнов. Понятно, что экономится вызов, но с точки зрения читабельности в контексте статьи... И потом у меня сомнения относительно диалогов сообщений - если ассертов будет много подряд (например, в цикле), пользователь не успеет ответить на первый запрос, как появится следующий (если я ничего не путаю). В общем нужно как-то сделать более дружественно.
В общем-то я статей не публиковал, поэтому не очень понятно, о какой ссылке идет речь. Хотя хальт выдернут действительно из кода моей забракованной статьи.
Что касается макроса, наверно он сгодится, хотя я не люблю таких многострочных дефайнов. Понятно, что экономится вызов, но с точки зрения читабельности в контексте статьи... И потом у меня сомнения относительно диалогов сообщений - если ассертов будет много подряд (например, в цикле), пользователь не успеет ответить на первый запрос, как появится следующий (если я ничего не путаю). В общем нужно как-то сделать более дружественно.
Видимо, ошибся насчёт статьи. Просто сейчас и сам не могу найти ту статью, но точно помню, что там был не макрос, а функция.
Преимущества макроса в основном такие: можно вывести выражение (#condition), имя файла (__FILE__), сигнатуру функции (__FUNCSIG__) и номер строки (__LINE__), где утверждение оказалось ложным. Получается примерно как на картинке. При варианте с функцией этих всех вкусностей уже не будет, придётся как-то через параметр указывать место в программе так, чтобы оно оставалось понятным программисту.
А насчёт диалога - задумка такая: если нажать "No", т.е. ответ на вопрос "Continue?" будет "No", то программа завершается, и последующие диалоги не будут выданы (см. UPD).
Спасибо!
UPD: посмотрел вариант с циклом и, похоже, ExpertRemove тоже не годится, т.к. в случае с циклом он не моментально грохнет программу, а дождётся окончания цикла (выдаст все диалоговые окна). Только хардкор, только ошибки времени выполнения :(
Крайний вариант теперь такой:
Преимущества макроса в основном такие: можно вывести выражение (#condition), имя файла (__FILE__), сигнатуру функции (__FUNCSIG__) и номер строки (__LINE__), где утверждение оказалось ложным. Получается примерно как на картинке. При варианте с функцией этих всех вкусностей уже не будет, придётся как-то через параметр указывать место в программе так, чтобы оно оставалось понятным программисту.
А насчёт диалога - задумка такая: если нажать "No", т.е. ответ на вопрос "Continue?" будет "No", то программа завершается, и последующие диалоги не будут выданы (см. UPD).
UPD: посмотрел вариант с циклом и, похоже, ExpertRemove тоже не годится, т.к. в случае с циклом он не моментально грохнет программу, а дождётся окончания цикла (выдаст все диалоговые окна). Только хардкор, только ошибки времени выполнения :(
Про преимущества макроса понятно. У меня тоже был макрос, но короткий - в нем содавался специальный объект куда эти все __FUNCSIG__ и прочее передавалось, а потом использовалось. Не столь эффективно, конечно.
Задумка про диалог тоже понятна, только у меня по-прежнему и в новом варианте впечатление, что в цикле будут множиться боксы.
Про преимущества макроса понятно. У меня тоже был макрос, но короткий - в нем содавался специальный объект куда эти все __FUNCSIG__ и прочее передавалось, а потом использовалось. Не столь эффективно, конечно.
Задумка про диалог тоже понятна, только у меня по-прежнему и в новом варианте впечатление, что в цикле будут множиться боксы.
Я проверил на таком коде:
Т.к. MessageBox приостанавливает поток программы (в отличие от алертов), то до следующего варианта не доходит. По крайней мере в MT5 1159 это верно.
Но и этот вариант уже не вариант: вспомнилось, что MessageBox не работают в индикаторах. Так что теперь крайний вариант:
Т.е. просто выдаём алерт и грохаем приложение, без всякого взаимодействия с пользователем.
Кстати, не хотелось связываться с ошибками времени выполнения отчасти потому, что если мы это проделываем в индикаторе, который существует в отдельном подокне, то это самое подокно останется. Т.е. индикатор прибъётся, но его подокно никуда не денется. Вынужденное зло?
Пример на картинке:
Т.к. MessageBox приостанавливает поток программы (в отличие от алертов), то до следующего варианта не доходит. По крайней мере в MT5 1159 это верно.
Но и этот вариант уже не вариант: вспомнилось, что MessageBox не работают в индикаторах. Так что теперь крайний вариант:
Т.е. просто выдаём алерт и грохаем приложение, без всякого взаимодействия с пользователем.
Кстати, не хотелось связываться с ошибками времени выполнения отчасти потому, что если мы это проделываем в индикаторе, который существует в отдельном подокне, то это самое подокно останется. Т.е. индикатор прибъётся, но его подокно никуда не денется. Вынужденное зло?
В принципе, тип программы можно узнать и в зависимости от этого либо выдавать бокс (в эксперте), либо нет. Только насчет приостановления потока я б все-таки проверил случай не в OnInit, а где-нибудь в OnTick.
С пятеркой сейчас не работаю, а вот в четверке у меня подокно после ошибки в индюке пропадает. Может быть это зависит от типа ошибки. Попробуйте вызвать out of bounds.
В принципе, тип программы можно узнать и в зависимости от этого либо выдавать бокс (в эксперте), либо нет. Только насчет приостановления потока я б все-таки проверил случай не в OnInit, а где-нибудь в OnTick.
С пятеркой сейчас не работаю, а вот в четверке у меня подокно после ошибки в индюке пропадает. Может быть это зависит от типа ошибки. Попробуйте вызвать out of bounds.
Раз в MT4 (или и в MT5) возможно такое поведение (всё же решение универсальным предполагается), то, я думаю, что теперь ни к чему усложнять с MessageBox'ами. Но я попроверяю ещё. Out of bounds привёл к тому же побочному эффекту, но думаю это не смертельно. Главное, это описать в статье (если с таким кошмаром вообще одобрят).
В принципе решение, пусть и самое грустное, найдено, так что всем откликнувшемся спасибо. Особенно Вам, Станислав. Вы очень здорово помогли!
Посмотрите эту тему, может подойдет? (касаемо индикатора)
Спасибо!
В данном примере идёт отталкивание от допущения, что в первом подокне наш индикатор будет первым (насколько видно по ChartIndicatorName(0, 1, 0)).
Однако, боюсь, это не универсально: мы заранее не знаем ни в каком подокне окажется наш индикатор, ни каким он будет там по счёту. Так можно снова вернуться к задаче "узнать короткое имя индикатора". И частный способ решения есть в указанной Вами ветке - запомнить в глобальную переменную, а хотелось бы общий :)
Но по крайней мере предположение Михаила в последнем сообщении кажется вполне логичным касательно того, почему окно индикатора остаётся висеть.
Есть очень простой способ:
Объявляем глобальную переменную н-р: stop_trading;
При инициализации присваиваем ей значение false
А в OnTick() пишем:
А в любом месте кода ( когда Вам нужно остановить работу советника),
присваиваете переменной значение true
Михаил, а почему Ваш код приведет к остановке работы советника?? Тут же просто выход из OnTick, советник как работал, так и будет работать, только в холостую.
Я так понял, автору вопроса надо ExpertRemove()? Пример из справки.
Михаил, а почему Ваш код приведет к остановке работы советника?? Тут же просто выход из OnTick, советник как работал, так и будет работать, только в холостую.
Я так понял, автору вопроса надо ExpertRemove()? Пример из справки.
Я думал, что мне было надо нечто подобное ExpertRemove(), но для индикаторов и скриптов.
Но оказался безбожно неправ: если мне нужно грохнуть программу на некоей итерации цикла и я для этого попробую вызвать ExpertRemove, то я не получу ожидаемого: все последующие итерации всё равно выполнятся (вставить break тоже не пойдёт - это нарушит принцип универсальности макроса, т.к. он будет использоваться не только в циклах).
Так что пока крайнее решение для аварийной остановки программы в произвольном месте - вызов ошибки времени выполнения (к примеру, деление на ноль).