У меня тоже не создаётся почему то. В длл индикатора можно создать
окно говорят (общий оконный поток терминала) а в эксперте и скрипте
отдельный порождается поток и видимо поэтому окно создать нельзя.
Попробуй создать свой поток и в нём окно своё. Возможно это сработает.
Не пробовал но тоже интересно, получится ли. Можно созадать
окно в своем exe файле и обмениваться нужной информацией с DLL
вызываемой из советника или скрипта. Я пробовал - этот подход
работает.
elritmo:
У меня тоже не создаётся почему то. В длл индикатора можно создать окно говорят (общий оконный поток терминала) а в эксперте и скрипте отдельный порождается поток и видимо поэтому окно создать нельзя. Попробуй создать свой поток и в нём окно своё. Возможно это сработает. Не пробовал но тоже интересно, получится ли. Можно созадать окно в своем exe файле и обмениваться нужной информацией с DLL вызываемой из советника или скрипта. Я пробовал - этот подход работает.
У меня тоже не создаётся почему то. В длл индикатора можно создать окно говорят (общий оконный поток терминала) а в эксперте и скрипте отдельный порождается поток и видимо поэтому окно создать нельзя. Попробуй создать свой поток и в нём окно своё. Возможно это сработает. Не пробовал но тоже интересно, получится ли. Можно созадать окно в своем exe файле и обмениваться нужной информацией с DLL вызываемой из советника или скрипта. Я пробовал - этот подход работает.
в отдельном потоке тож ничего хорошего не вышло. В итоге взял создал отдельно процесс а из скрипта нужные данные пихаю в файл. а уже из файла забираю в своё окно. вот. хотя можно как и ты говорил юзать SendMessage из DLL. Или как то можно ещё ? А насчёт индикатора я попробую.
Да использую SendMessage(hWnd, WM_COPYDATA, ...) Работает очень надёжно. Данные не теряются, причём идёт обмен данными в обе стороны от длл к моему процессу и обратно.
elritmo:
Да использую SendMessage(hWnd, WM_COPYDATA, ...) Работает очень надёжно. Данные не теряются, причём идёт обмен данными в обе стороны от длл к моему процессу и обратно.
Да использую SendMessage(hWnd, WM_COPYDATA, ...) Работает очень надёжно. Данные не теряются, причём идёт обмен данными в обе стороны от длл к моему процессу и обратно.
Очень интересно. В окно процесса можно отправить, а как назад в dll получить?
RickD:
Очень интересно. В окно процесса можно отправить, а как назад в dll получить?
Боюсь если расскажу то MQ снова испугаются и вообще DLL запретят
:) Ну да ладно поделюсь знаниямиelritmo:
Да использую SendMessage(hWnd, WM_COPYDATA, ...) Работает очень надёжно. Данные не теряются, причём идёт обмен данными в обе стороны от длл к моему процессу и обратно.
Да использую SendMessage(hWnd, WM_COPYDATA, ...) Работает очень надёжно. Данные не теряются, причём идёт обмен данными в обе стороны от длл к моему процессу и обратно.
Очень интересно. В окно процесса можно отправить, а как назад в dll получить?
Delphi Dll где нибудь в инициализации Ищем хендлер главного окна из хендлера чарта кторый передаём в DLL из советника скрипта. Хендлер в советнике скрипте получаем через WindowHandler while MTChartWin <> 0 do begin MTMainWin := MTChartWin; MTChartWin := GetParent(MTChartWin); end; Затем подставляем вместо терминальной оконной процедуры свою которая дополняет её нашими обработками сообщений. SetWindowLong(MTMainWin, GWL_USERDATA, SetWindowLong(MTMainWin, GWL_WNDPROC, LongInt(@NewWndProc))); А это пример моей оконной процедуры function NewWndProc(Wnd: THandle; Msg: Cardinal; wParam, lParam: Integer): Cardinal; begin case Msg of WM_COPYDATA: begin // сообщение с данными от нашего приложения Inc(PosCnt); if Length(Positions) < PosCnt then SetLength(Positions, PosCnt + 1000); Positions[PosCnt - 1] := PPosition(PCopyDataStruct(lParam).lpData)^; Result := 0; Exit; end; WM_USER + 1: begin // Простое сообщение событие от нашего приложения, чтобы не использовать более сложное WM_COPYDATA ZeroMemory(@LastBarCnt, SizeOf(LastBarCnt)); Result := 0; Exit; end; end; Result := CallWindowProc(Pointer(GetWindowLong(Wnd, GWL_USERDATA)), Wnd, Msg, wParam, lParam); end; Так я отсылаю данные в мой процесс exe Нахожу его по классу окна FeatherWinCaption который передаю в советнике как параметр И вместе с сообщенеим отсылаю хендлер главного окна терминала. в этом случаем мы можем свободно перегружать терминал не закрывая наше приложение. Оно получит новый хендлер с новым сообщением. MTCommWnd := FindWindow(nil, FeatherWinCaption); if MTCommWnd = 0 then Exit; with CopyDS do begin dwData := TICK_IND; cbData := SizeOf(TTick); lpData := @Tick; end; SendMessage(MTCommWnd, WM_COPYDATA, MTMainWin, Integer(@CopyDS)); Ну а при деинициализации советника надо вызвать функцию в DLL которая вызовет эту функцию чтобы подставить терминалу её собсвенную оконную процедуру обработки сообщений. В этом случае у нас ничего падать не будет SetWindowLong(MTMainWin, GWL_WNDPROC, GetWindowLong(MTMainWin, GWL_USERDATA)); Этого достаточно чтобы обмениваться данными вполне успешно в обе стороны на одном тике.
Данные копируются в локальный буфер. А используются в эксперте или скрипте. Верно?
Что будет - если эксперт или скрипт будет использовать данные в тот момент, когда NewWndProc их изменяет?
Такого не случается, потому что ты используешь SendMessage для отсылки
сообщений и поток скрипта или эксперта замирает пока не обработается
посланное сообщение и оконная процедура не вернёт значение.
Асинхронно работает PostMessage. Поэтому ты посылаешь сообщение
своему приложенияю и поток замерает и ждёт пока это сообщение
не обработается. Оконная процедура твоего приложения принимает
твоё сообщение, обрабаотывает и в свою очередь может послать
сообщение через SendMessage оконной процедуре MetaTrader-а которую ты
перегрузил и которая висит в общем оконном потоке МТ а не в потоке
советника. На это сообщение ты в DLL советника забираешь и сохраняешь
данные в массивах в DLL и выходишь из оконной процедуры. Далее
размораживается поток при вызове второго SendMessage в оконной процедуре
твоего приложения и происходит выход из этой процедуры, что
в свою очеред размораживает поток советника в том месте где
ты вызвал SendMessage в DLL советника. Далее ты можешь записать в массив
доступный советнику данные полученные от твоего приложения
при обмене сообщениями в коде после вызова всех твоих SendMessgae.
В итоге не может быть доступа к данным одновременно разными
потоками.
Надеюсь ты понял. Если нет то мне уже надо писать статью. :) Возможно меня раскритикуют с доводами, но метод работает и падений не было или порчи данных пока что.
Надеюсь ты понял. Если нет то мне уже надо писать статью. :) Возможно меня раскритикуют с доводами, но метод работает и падений не было или порчи данных пока что.
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Привет всем. Я в своей либе создаю окно:
bResCheck = CreateMyWindow(0);Данный код я вызываю либо в эксперте (init) либо в скрипте (start). Когда вызываю в эксперте то окно успешно создаётся но сразу же пропадает. если создаю в скрипте то для того чтобы оно не пропадало юзаю
бесконечный цикл, но он всё тормозин и не рендеоит моё окно. В итоге вопрос как сделать окно через мою либу что бы оно нормально работало ?
Вешать создание окна на другой поток не пробовал пока.