Как создать библиотеку dll

Образцы, куски исходников, вопросы. Обсуждаем программирование.
Сообщение
Автор
Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

Загадочное исчезновение. // Дым без огня?

#61 Сообщение Николай Тарасов » Пт фев 18, 2011 8:54 pm

Ха!
Решил сейчас проверить то, что вам предложил выше.
Попробовал раз, другой, пятый - не выходит.
Проблема пропала куда-то. :?

Засомневался было. Вот, мол, - думаю, - поднял шум, а подтверждений нет.
Но вспомнил, что есть документ - рисунок 'Error of Objects Time' (см. выше).
Ведь было такое? Было. И многократно.
Что в ручном, что в автоматическом режиме.

* * *
В общем, есть версия, что в тот период времени процессор у меня работал в перегруженном режиме (100%).
Я тогда сканировал диски Антивирусником, в Delphi редактировал код, тестировал FT, слушал AudioJet, смотрел MT-терминал и интернет одновременно. А перегруженность в частности проявлялась в регулярном "притормаживании" ("подвисании") видео-клипов.

Вероятно, всё это могло способствовать смещению объектов на временной оси в FT.
Помнится такую тонкость в MT4 описывали.
Что мол, "если процесс вычисления не успеет завершиться на момент прорисовки (появления) следующего тика, то" у вас будет то-то, и то-то.

* * *
Понаблюдаю ещё.
Может, всё и наладится.
В любом случае, Александр, благодарю вас за отзывчивость!



PS:
Раз уж снова привлёк ваше внимание, озвучу ещё пару вопросов-предложений:

1. Вы знаете, что при первоначальном тестировании (самом первом, после запуска FT) недоступны никакие кнопки. Ни "+", ни "-". Ни одна из кнопок для установки объектов. Все они (кроме одной кнопки - "Пауза") изображаются неяркими красками и "нажать" (курсором) на них не возможно.
После остановки (нажатия на паузу) все кнопки "оживают" и становятся доступными.
* * *
Вроде мелочь, но всё же, думаю, стоит сказать о ней.

2. Не понял, как можно удалять ненужные скрипты? Неужели только вручную, самостоятельно вычищая папки FT со скриптами?
Было бы не плохо удаление скриптов сделать столь же легким, как и их установку. То есть чрез нажатие каких-нибудь кнопок внутри самой программы.

3. Планирует ли Михаил дополнить ScriptInterfaceUnit функциями для работы с экранными координатами? Такими как:
1. Added new function ChartToScrX - converts index to screen x coordinate
2. Added new function ChartToScrY - converts price to screen y coordinate
3. Added new function ScrToChartX - converts screen x coordinate to index
4. Added new function ScrToChartY - converts screen y coordinate to price
Я желаю всем счастья.

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

Продолжаю делиться опытом

#62 Сообщение Николай Тарасов » Вс фев 20, 2011 12:06 pm

Отловил у себя ошибку, которая, как выяснилось, возникла, при не совсем корректном переводе MT4-кода на Delphi-код.
Дело в том, что MT4-функцию MathFloor() (см. рисунок) нельзя и просто так заменить на Delphi-функцию Trunc(). Иначе проблем в отрицательной области значений аргумента не избежать.
Но можно сделать вот так:

Код: Выделить всё

var
   x:  Double;
// ...
   x:= ...;                                                              
   x:= Trunc(x+(Abs(Trunc(x))+1))-(Abs(Trunc(x))+1); 
Либо же можно сделать специальную функцию с одноимённым названием.
Вложения
MathFloor() - function of MT4.JPG
(30.99 КБ) 50696 скачиваний
Я желаю всем счастья.

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

Функция Floor()

#63 Сообщение Николай Тарасов » Вс фев 20, 2011 12:49 pm

Итак, прошу любить и жаловать - функция Floor() - полный Delphi-аналог MQL4-функции MathFloor().

Код: Выделить всё

  function Floor(x: Double): Double;
  // Функция возвращает числовое значение, представляющее наибольшее целое
  // число, которое меньше или равно x. Это полный Delphi-аналог
  // функции double MathFloor(double x) в MQL4 (MetaQuotes Language 4).
  // Пример:
  //   Наименьшее целое от 2.8 есть 2.
  //   Наименьшее целое от -2.8 есть -3.
  var
    y:  Double;
  begin
    y:= Trunc(x + (Abs(Trunc(x))+1)) - (Abs(Trunc(x))+1);
    Result := y;
  end;
PS
Простите, выяснилось, что такая функция в Delphi уже есть.
Подробнее смотрите здесь: http://www.helloworld.ru/texts/comp/lan ... th5104.htm
Последний раз редактировалось Николай Тарасов Вт фев 22, 2011 4:24 pm, всего редактировалось 1 раз.
Я желаю всем счастья.

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

Теперь я знаю!!! :?

#64 Сообщение Николай Тарасов » Пн фев 21, 2011 8:33 am

FT Support писал(а):Здравствуйте, Николай,
...
Можете ли Вы прислать нам проект или темплейт, на котором будет видна проблема?
Здравствуйте, Александр.
Спасибо, что спросили про темплейт. :wink:
Теперь я знаю что это такое.

Темплейтами (template - копир по-английски) называются записи с экрана компьютера.

Эта технология - аналог создания скриншотов (screenshot - снимок (копия) экрана). Только программы, которые это делают (например, UVScreenCamera 4.5.0.98 - см. приложение или http://sweet.211.ru/action/download/downloadid/6494/), не фотографируют экран, а делают видеозаписи.

А это очень удобно, чтобы создавать целые видеоуроки.
Вот такие, например: http://www.youtube.com/user/Terranin#p/u
Всем рекомендую.


PS
Обмен обогащает. Не правда ли?
Вложения
записи видео с экрана.rar
(2.86 МБ) 1601 скачивание
Я желаю всем счастья.

FT Support
Сообщения: 329
Зарегистрирован: Сб июл 11, 2009 3:59 pm

#65 Сообщение FT Support » Вт фев 22, 2011 1:04 pm

Здравствуйте, Николай,

1) Ошибку с "прыгающими" вертикальными линиями мы так и не отловили (а следовательно исправить пока что не сможем). Да, линии действительно перемещаются, но только за счёт несуществующих баров (например выходных) после перемещения линий их показания остаются правильными если только линия не была изначально установлена на несуществующий бар.
Проверял я всё именно так как Вы сказали в первый раз (установил много вертикальных линий впереди графика и запустил тестирование) после этого сравнивал показания линий с фактическими координатами на графике.

2) Да, действительно была проблема с недоступными кнопками после начала тестрования, но насколько помню мы её уже исправили, по кайней мере на скорую руку воспроизвести на последней версии не получилось. Какая версия у Вас?

3) Скрипты, Индикаторы, Стратегии пока что можно удалить только вручную из папки, но не думаю что это большая проблема, насколько помню в МТ тоже нельзя ничего удалить пользуясь лишь интерфейсом терминала

4) Не советую использовть имя функции "Floor" так как оно совпадает с именем встроенной Delphi функции, которая делает прямопротивоположные вещи (http://www.helloworld.ru/texts/comp/lan ... th5104.htm)

5) Не совсем согласен по поводу темплейтов, Темплейт в переводе с англ. это "шаблон", а записи экрана сложно назвать шаблонами, обычно их называют скринкастами (http://en.wikipedia.org/wiki/Screencast) для записи видео мы обычно используем Camtasia Studio: http://www.techsmith.com/camtasia/ отличная программа.

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

#66 Сообщение Николай Тарасов » Вт фев 22, 2011 6:14 pm

Здравствуйте, Александр.

1. Благодарю за ответ.

2. Версия Forex Tester 2 у меня самая последняя (v.2.6.10 06/09/2010), судя по тому, что пишет FT при проверке обновления.
А неактивные кнопки - такая, право, мелочь.
Я даже думал, что это как-то связано с защитой программы от взлома (перехвата управления). :wink:
Как часто повторяет моя супруга: "Значит так надо! Чего привязался?" :?

3. Я и не знал, что в Delphi есть готовая функция Floor(). Посмотрел вашу ссылку. Оказывается, Floor() делает именно то, что MathFloor() в MQL4. То есть округляет показания условного градусника до нижней риски на шкале. Сравните сами:
-5.7 округляется до -6 аналогично тому, как -2.8 округляется до -3;
+5.7 округляется до +5 аналогично тому, как +2.8 округляется до +2.

* * *
Надо будет сделать пометку на моём сообщении про Foolr(), чтобы не вводить других в заблуждение.



4. Чтобы правильно округлять числа с давних пор использую следующую формулу:

Код: Выделить всё

  x := Floor(x + 5/9); // 5/9 := 0.555555555555555...
В MS Excel это выглядит так:

Код: Выделить всё

  x := ЦЕЛОЕ(x + 5/9);
При таком подходе не обрубаются весомые хвосты. А вес от далекоотстоящих элементов числа последовательно и бережно передаётся ближестоящим.
Примеры последовательного (бережного) округления (по градуснику):
1) 0.4444 ~ 0.444 ~ 0.44 ~ 0.4 ~ 0;
2) 0.4445 ~ 0.445 ~ 0.45 ~ 0.5 ~ 1.
--
Понятно, что водоразделом между 0 и 1 в таком случае является не 0.5 = 1/2, а 0.444444444444444... = 4/9 (см. рисунки).
При этом: 4/9 = 0.444444444444444... ~ 1.
---
Доказательство правильности такого подхода:
1) Известно, что 9/9 = 1.
2) Но 9/9 = 0.999999999999999...
Для полного соответствия дроби "9/9" единице "1" формально не хватает супер миниатюрного числа v = 0.000000000000000...1 = 1/10^N (где N - бесконечно большое натуральное число).
3) Именно такого сверх миниатюрного числа v (ню) формально не хватает для того, чтобы число "0.444444444444444... = 4/9" можно округлить сначала до "0.444444444444444...5", а потом и до "1" по правилам последовательного округления.
4) Но частица v формально равна "0" (нулю), так как:
v = 1 - 9/9 = (9-9)/9 = 0.
5) Поэтому можно спокойно считать, что 4/9 = 4/9 + v = 0.444444444444444...5 ~ 1.  :!:
* * *
Этот подход полностью соответствует тому, как меня учили округлять в школе.
Разработал его, когда в студенчестве сделал программу для построения двух-трёхмерных графиков на основе экспериментальных данных с применением метода наименьших квадратов, похожих на те, что сейчас делает Excel (очень похожий пример смотрите здесь: http://forextester.ru/forum/viewtopic.php?p=3504#3504). Причём первые графики я рисовал символами (звёздочками '*') на экране с разрешением 80 символов на 25 строк. Поэтому вопрос с округлением поначалу стоял довольно ярко, если не сказать крупно. :wink:
Это потом уже у меня появилась область построения 800х600 монохромных точек...
С тех пор использую свой алгоритм везде во избежание разного рода проблем с округлением.
Всем рекомендую.


6. Модификация правильного (бережного) метода округления до нужной точности:

Код: Выделить всё

  x := Floor(x/Precision + 5/9) * Precision;
  // Precision := 0.1 - округление до 0.1
  // Precision := 10  - округление до 10
  
  // Precision := 0.25 - округление до 0.25
  // Precision := 4    - округление до 4
7. Использую многоязычный Lingvo x3 (http://www.lingvo.com). Знаете ли, очень удобно переводить, например, украинские тексты. :wink:
Китайские, правда, ещё не попробовал. :wink:
Ну, так вот, словарь LingvoScience выдаёт вот такие смыслы для Template: "1) копир; 2) лекало; 3) темплет; 4) шаблон; 5) эталон".

8. Благодарю за Camtasia Studi. Обязательно попробую.
Вложения
True rounding+.JPG
(97.58 КБ) 4576 скачиваний
True rounding.JPG
(86.05 КБ) 4576 скачиваний
Последний раз редактировалось Николай Тарасов Пт май 13, 2011 7:43 pm, всего редактировалось 7 раз.
Я желаю всем счастья.

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

#67 Сообщение Николай Тарасов » Чт фев 24, 2011 10:29 am

Здравствуйте, Александр.
Здравствуйте, Михаил.

Давно хочу спросить вас о защите скриптов, стратегий и индикаторов, написанных для FT2.

Есть какие-то успешные решения этого вопроса?
Или прятать код на машине клиента - дело бессмысленное?
Кому надо - всё равно разберётся?

Возможно, у вас есть опыт сотрудничества, когда защиту пользовательского софта обеспечивает ваша программа с её собственной защитой от перехвата управления?

Если нет, то, интересно, как вы относитесь к подобному сотрудничеству?
Я желаю всем счастья.

FT Support
Сообщения: 329
Зарегистрирован: Сб июл 11, 2009 3:59 pm

#68 Сообщение FT Support » Чт фев 24, 2011 2:26 pm

Здравствуйте, Николай,

Какую именно защиту Вы имеете в виду? защиту от декомпиляции? ну из dll и так довольно сложно получить удобочитаемый алгоритм работы программы :)

Если Вы имеете в виду защиту от переноса на другой компьютер то я бы порекомендовал привязаться к железу компьютера как делает это тестер или лучше к регистрационному ключу самого тестера.

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

#69 Сообщение Николай Тарасов » Чт фев 24, 2011 3:57 pm

1. Да-да, я имел в виду именно "защиту от декомпиляции".

Раньше передо мной не вставало такой задачи.
Почитал интернет...

Везде пишут, что код прочитать и внести необходимые поправки - дело одного-двух дней.

Неужели теперь всё мало-мальски ценное из скрипта нужно переносить на сервер (сайт)? Но сайт тоже можно взломать.
Замкнутый круг какой-то!


2. Думаю, можно ещё делать встройку авторских скриптов, индикаторов и стратегий прямо в FT2.
В таком случае никаких dll-файлов, доступных для декомпиляции не будет и в помине.
Понятно, что не просто так, а да денежки. :wink:


3. А как в скрипте узнать регистрационный ключ самого тестера?
Разве у вас есть такая функция?
Я желаю всем счастья.

FT Support
Сообщения: 329
Зарегистрирован: Сб июл 11, 2009 3:59 pm

#70 Сообщение FT Support » Пт фев 25, 2011 9:58 am

Здравствуйте, Николай,

1. Вы скорее всего видели обсуждение декомпиляции МТ скриптов и советников, там действительно всё намного сложнее защитить, но в нашем случае dll просто так декомпилировать не получится, это сможет сделать только специалист.

2. Ну это разве что за большие денежки ))) не так всё просто

3. Прямой функции нет, но можно прочитать файл options.dat, ключ сохранён там.

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

#71 Сообщение Николай Тарасов » Пт фев 25, 2011 11:19 am

FT Support писал(а):Здравствуйте, Николай,

1. Вы скорее всего видели обсуждение декомпиляции МТ скриптов и советников, там действительно всё намного сложнее защитить, ...
Именно так. Правда, в MT5, пишут, этой проблемы уже нет.
Не знаю, стоит ли этой информации доверять.
Как считаете?
Мне думается, что за MT5 просто ещё не брались по настоящему.
Предмета исследования не было.
Да и круга заинтересованных лиц (заказчиков) тоже.
А пообещать можно, что угодно.
FT Support писал(а):..., но в нашем случае dll просто так декомпилировать не получится, это сможет сделать только специалист.
О-о-о! Это радует, поскольку сильно упрощает мою задачу!!! :wink:
FT Support писал(а):
Николай Тарасов писал(а): 2. Думаю, можно ещё делать встройку авторских скриптов, индикаторов и стратегий прямо в FT2.
В таком случае никаких dll-файлов, доступных для декомпиляции не будет и в помине.
Понятно, что не просто так, а да денежки.
2. Ну это разве что за большие денежки ))) не так всё просто
Я имел в виду не прямую оплату вам от меня, а опосредованную (от клиентов).
Суть в том, что вам под своим брендом можно выпускать (продавать) версии тестировщика с рассширенным (за счёт соавторов-партнёров) функционалом. За более дорогую цену, разумеется.
Как делить поступления (размер авторских отчислений) - тема отдельного разговора.
FT Support писал(а): 3. Прямой функции нет, но можно прочитать файл options.dat, ключ сохранён там.
Ну, вы в своём репертуаре, Александр.
Всё-то из вас, программистов, клещами да гвоздодёром вытаскивать приходится.
И впрямь, команда треминаторов с "железными" сердцами. :wink:
Надеюсь, интернет, поможет.
Спасибо и на этом.
Я желаю всем счастья.

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

#72 Сообщение Николай Тарасов » Пт фев 25, 2011 12:01 pm

Файл options.dat прочитал MS Excel'ем.
Делал так:
1. Навёл курсор на файл.
2. Через правую кнопку мышки выбрал Excel в качестве программы для просмотра файла (см. раздел "Открыть с помощью").
3. Сохранил одноимённый options.xcl со всем списком из 179-ти переменных (констант).

Теперь надо это же сделать в скрипте (индикаторе и стратегии).
Как сделаю, отпишу.
Я желаю всем счастья.

FT Support
Сообщения: 329
Зарегистрирован: Сб июл 11, 2009 3:59 pm

#73 Сообщение FT Support » Пн фев 28, 2011 11:20 am

Здравствуйте, Николай, не нужно гвоздодёра :), вот функция, с помощью которой можно достать регистрационный ключ программы:

Код: Выделить всё

function GetFTKey(): string;
var FolderPath, optDatPath, line: string;
    handleOpt: TextFile;

begin
  FolderPath := ExtractFileDir(ParamStr(0));
  optDatPath := FolderPath+'\options.dat';

  result := '';

  if FileExists(optDatPath) then
    begin
     AssignFile(handleOpt, optDatPath);
     Reset(handleOpt);
     while not Eof(handleOpt) do
     begin
       Readln(handleOpt, line);
       if (Copy(line, 0, 16) = 'RegistrationKey=') then
       begin
         result := Copy(line, 17, 66);
         break;
       end;
     end;
     CloseFile(handleOpt);
   end
end;

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

#74 Сообщение Николай Тарасов » Пн фев 28, 2011 2:56 pm

Даже не знаю, что сказать.
Вы кудесник, Александр.
Браво!



PS:
На основе этого кода можно ещё
GetFTHardwareID() и GetFTUserName() сделать.
Я желаю всем счастья.

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

Манипуляции с индикаторами из скрипта

#75 Сообщение Николай Тарасов » Чт мар 03, 2011 1:38 pm

Добрый утро, Александр.
Не поможете мне?

Что-то не помню, можно ли в MT4 прикреплять к графику, видоизменять и убирать с графика индикаторы из скрипта.
Кажется, нет.

А можно ли в FT2 это делать?
Я желаю всем счастья.

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

Ребята из Казани

#76 Сообщение Николай Тарасов » Вс мар 06, 2011 9:26 pm

Читаю про MQL5 (MT5).
Оказывается его сделали и делают тоже нашенские ребята - из Казани!!!
Смотрите сами: http://www.metaquotes.net/ru/company/management

Вот это да! Молодцы, братья татары.
На уровне работают.

Надо будет и с ними пообщаться как-нибудь. :wink:

--

PS

На форуме http://www.mql5.com/
интересный Гугл-инструмент нашёл. "Тенденции" (тренды) называется. Он статискику разнообразных интернет-явлений составляет.
Видел такое лишь в программе про интернет-технологии на канале "РОССИЯ 24".

Странные результаты получаются у них.
Например, посмотрите вот на это:

1) http://www.google.com/trends?q=Forex+Te ... all&sort=0 - тенденции поиска 'Forex Tester, ForexTester, Forex Tester 2, ForexTester2'

2) http://www.google.com/trends?q=MQL4,+MT4,+MQL5,+MT5 - тенденции поиска 'MQL4, MT4, MQL5, MT5'
Я желаю всем счастья.

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

Как в скрипте узнать "текст/описание" объекта?

#77 Сообщение Николай Тарасов » Вт мар 08, 2011 1:03 am

Здравствуйте.
Подскажите, пожалуйста, как в скрипте узнать "значение текста/описания" у текстового объекта?

Для этого я попробовал извлечь параметр "OBJPROP_TEXT" с помощью функции ObjectGet() (см. скрипт 'ObjectsTest_Plus4').
Не вышло. Выдаётся ошибка:
[Ошибка] ObjectsTest_Plus4.dpr(175): Incompatible types: 'String' and 'Double'
[Ошибка] ObjectsTest_Plus4.dpr(176): Incompatible types: 'String' and 'Double'
[Ошибка] ObjectsTest_Plus4.dpr(177): Incompatible types: 'String' and 'Double'
[Ошибка] ObjectsTest_Plus4.dpr(178): Incompatible types: 'String' and 'Double'
[Ошибка] ObjectsTest_Plus4.dpr(179): Incompatible types: 'String' and 'Double'
[Ошибка] ObjectsTest_Plus4.dpr(180): Incompatible types: 'String' and 'Double'
[Ошибка] ObjectsTest_Plus4.dpr(181): Incompatible types: 'String' and 'Double'
Пробовал вместо текста записывать числа.
Но результат в буквальном и переносном смысле нулевой:
names[0]=0
names[1]=0
names[2]=0
names[3]=0
names[4]=0
names[5]=0
names[8]=0
Заранее благодарю за помощь.
Скрипт прилагается.


PS
Если есть какой-то другой рабочий вариант записи и считывания текста (не через текстовый объект), прошу сообщить. Не откажусь.
Вложения
ObjectsTest_Plus4.rar
(1.3 КБ) 1637 скачиваний
Я желаю всем счастья.

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

#78 Сообщение Николай Тарасов » Вт мар 22, 2011 8:03 am

Здравствуйте.
На основе функции GetFTKey() соорудил функцию UserOptionGet() для считывания параметров из своих файлов.
Теперь вот пытаюсь сделать функцию для перезаписи параметров в этих файлах.
Но что-то у меня не получается - проблема с командой на удаление файла:
[Ошибка] UserSetting.dpr(616): Missing operator or semicolon
[Ошибка] UserSetting.dpr(616): Incompatible types: 'String' and 'PAnsiChar'
Помогите, пожалуйста, разобраться.

Код: Выделить всё

  
  function UserOptionSet(OptFile: string; Option: string; Value: string): Bool;
  // Функция для изменения опций в файлах пользователя.
  // Пример: UserOptionSet('\User\Options.dat', 'Option1', '1');
  // --
  // Прототипы:
  // 1) функции GetFTKey() и UserOptionGet();
  // 2) http://www.delphi.int.ru/articles/126/ (раздел "Хранение записей в файлах").
  // --
  var line:        string; // Строка
    OptionLength: Integer; // Длина имени опции
    FTFolderPath:  string; // FT-папка
    optDatPath1:   string; // Полное имя файла1 (Old)
    optDatPath2:   string; // Полное имя файла2 (New)
    handleOpt1:  TextFile; // Файловая переменная1 = Полное имя файла1
    handleOpt2:  TextFile; // Файловая переменная2 = Полное имя файла2
  begin
  result       :=                        false; // Предварительная установка
  FTFolderPath :=  ExtractFileDir(ParamStr(0)); // FT-папка: 'C:\ForexTester2'
  optDatPath1  :=    FTFolderPath +    OptFile; // Полное имя файла1 (Old)
  optDatPath2  :=    FTFolderPath + 'temp.dat'; // Полное имя файла2 (New)
  OptionLength :=               length(Option); // Длина имени опции
  if FileExists(optDatPath1) then
    begin
      AssignFile(handleOpt1, optDatPath1); // Привязка полн.имени1 файл.переменной1
      AssignFile(handleOpt2, optDatPath2); // Привязка полн.имени2 файл.переменной2
      Reset(     handleOpt1);              // Считывание файла1
      Rewrite(   handleOpt2);              // Перезапись файла2
      while not Eof(handleOpt1) do         // Пока не конец файла1
      begin
        // Читаем строку без перехода к следующей
        Read(handleOpt1, line);
        if (Copy(line, 0, OptionLength) = Option) then
          // В файл2 пишем новую строку с меткой переноса строки
          Writeln(handleOpt2, Option+'='+Value)
        else
          // В файл2 пишем старую строку как есть
          Write(handleOpt2, line);
      end;
      CloseFile(handleOpt1);
      CloseFile(handleOpt2);
    end;
 DeleteFile(optDatPath1);                                  // Строка 616 !!!!!
//  DeleteFile(FTFolderPath + OptFile);
//  DeleteFile(ExtractFileDir(ParamStr(0)) + OptFile);
///   DeleteFile('C:\ForexTester2\User\Options.dat');      // Строка 619 !!!!!
//
//  SetCurrentDir(optDatPath1);
//  SetCurrentDir(ExtractFileDir(ParamStr(0)) + OptFile);
//  DeleteFile('Options.dat');
  RenameFile(optDatPath2, optDatPath1);
  result := true;
  end;
Если же вместо строки 616 активировать строку 619, то проблема отстаётся:
[Ошибка] UserSetting.dpr(619): Missing operator or semicolon
* * *
Заранее благодарю.


PS

И ещё.

Скажите, пожалуйста, с помощью каких средств ФорексТестера пользователю можно (удобнее) вводить свои параметры долгосрочного действия?

Как я понимаю, диалоговое окно для внесения параметров открывается только у индикаторов.

Скрипты же, хоть и могут выдавать Settings-окно (через правую кнопку мышы), но фактически не меняют свои параметры.
По крайней мере, мне пока не удалось это сделать.
Последний раз редактировалось Николай Тарасов Пт май 20, 2011 12:14 pm, всего редактировалось 1 раз.
Я желаю всем счастья.

FT Support
Сообщения: 329
Зарегистрирован: Сб июл 11, 2009 3:59 pm

#79 Сообщение FT Support » Вт мар 22, 2011 7:58 pm

Здравствуйте, Николай,

менять строки в файле options.dat бессмысленно, программа всё-равно перезапишет этот файл при закрытии.

если Вам нужно хранить какие-то данные "долговременного действия", то лучше создать свой файл подобным образом.

чтобы победить ошибку Incompatible types: 'String' and 'PAnsiChar' нужно просто привести типы, например Pchar(ВашаСтрока) или наоборот.

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

Подскажите способ перезаписи параметров в файле

#80 Сообщение Николай Тарасов » Вт мар 22, 2011 11:44 pm

FT Support писал(а):Здравствуйте, Николай,

менять строки в файле options.dat бессмысленно, программа всё-равно перезапишет этот файл при закрытии.

если Вам нужно хранить какие-то данные "долговременного действия", то лучше создать свой файл подобным образом.

чтобы победить ошибку Incompatible types: 'String' and 'PAnsiChar' нужно просто привести типы, например Pchar(ВашаСтрока) или наоборот.
Здравствуйте, Александр.

1. У меня была версия, что FT2 не разрешит перезапись файла.
Но, простите, я же не ваш файл 'C:\ForexTester2\options.dat' хочу менять, а свой собственный 'C:\ForexTester2\User\Options.dat'.
Неужели для этого нужно и корневую папку менять, выносить её куда-нибудь за пределы 'C:\ForexTester2\'?


2. Я, конечно же, могу менять содержимое своего dat-файла вручную. Но хотелось бы соорудить более удобный интерфейс для этого.
Александр, посоветуете, какие из средств FT2 можно использовать для этих целей?

Например, Settings-диалоговое окно для индикаторов вполне бы подошло. Там помимо всего есть ещё и параметры раскраски.

А как пользоваться Settings-окном в скрипте, я пока не пойму.
Например, мне не ясно, когда и как нужно менять параметры скрипта, чтобы их корректировка повлияла на последующее исполнение скрипта.
Если можно, разъясните, пожалуйста этот момент.


3. Александр, благодарю за ваш совет поменять типы в коде. Попробую ещё.


4. Александр, а может быть подскажите способ перезаписи параметров в файле? Я смотрю, ваш файл 'C:\ForexTester2\options.dat' не меняется (как файл) с момента установки FT. Значит, есть (да просто обязан быть!) некий метод перезаписи без создания файла-дублёра.

Понятно, что способов может быть масса.
Например, вставка через буфер.
Александр, задайте хотя бы направление для поиска, ссылку на приемлемое решение.
И, желательно, чтобы не очень было сложно для воспроизведения.
Что-нибудь в стиле вашей замечательной функции GetFTKey().
Уж, пожалуйста. Будьте столь любезны.

--
PS
Очень жаль, что на подобную, казалось бы, ерунду уходит так много времени. Надеюсь, что когда-нибудь FT будет наконец сопровождён подробными инструкциями с типовыми решениями пользовательских задач.
Я желаю всем счастья.

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

Делимся опытом

#81 Сообщение Николай Тарасов » Ср мар 30, 2011 12:24 pm

Здравствуйте.
Продолжаю делиться своими наработками по программированию для Форекстестера.

Итак, прошу любить и жаловать:
1. Функция для считывания параметра из файла с опциями пользователя.
2. Функция для изменения параметра в файле с опциями пользователя.
3. Стандартная и очень простая функция для проигрывания звуков.

Думаю, они понадобятся не только мне.
Последний раз редактировалось Николай Тарасов Ср мар 30, 2011 1:21 pm, всего редактировалось 1 раз.
Я желаю всем счастья.

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

Функция для считывания параметра из файла

#82 Сообщение Николай Тарасов » Ср мар 30, 2011 12:36 pm

1. Функция UserOptionGet()

Код: Выделить всё

  function UserOptionGet(OptFile: string; Option: string): string;
  // Функция для извлечения User-опций из файлов.
  // Пример: UserOptionGet('\UserToFT\Options.dat', 'History');
  // --
  // Переделал из: function GetFTKey().
  // Исходник: forextester.ru/forum/viewtopic.php?p=3689#3689 (см. GetFTKey).
  // --
  var OptionLength, lineLength: Integer; // Длина имени опции и длина строки
    x1, x2: Integer;                     // Номер первого символа и длинна опции
    FTFolderPath, optDatPath: string;    // FT-папка, полное имя файла и строка
    line: string;                        // Строка
    handleOpt: TextFile;                 // Файловая переменная=Полное имя файла
  begin
  result       :=                          ''; // Предварительная очистка
  FTFolderPath := ExtractFileDir(ParamStr(0)); // FT2-папка: 'C:\ForexTester2'
  optDatPath   :=      FTFolderPath + OptFile; // Полное имя файла
  OptionLength :=              length(Option); // Длина имени опции
  if FileExists(optDatPath) then
    begin
      AssignFile(handleOpt, optDatPath);       // Привязываем полное имя
                                               // файловой переменной
      Reset(handleOpt);                        // Запуск файла
      while not Eof(handleOpt) do              // Пока не конец файла
      begin
        Readln(handleOpt, line);               // Читаем файл по строкам
        lineLength:=length(line);              // Длина строки
        if (Copy(line, 0, OptionLength) = Option) then
        begin
          x1 := OptionLength+2;                // '+2' из-за '='.
          x2 := lineLength - (OptionLength+1); // '+1' из-за '='.
          result := Copy(line, x1, x2);
          break;
        end;
      end;
      CloseFile(handleOpt);
    end;
  end;
Последний раз редактировалось Николай Тарасов Пт май 20, 2011 12:15 pm, всего редактировалось 4 раза.
Я желаю всем счастья.

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

#83 Сообщение Николай Тарасов » Ср мар 30, 2011 12:42 pm

2. Функция UserOptionSet()

Код: Выделить всё

  function UserOptionSet(OptFile: string; Option: string; Value: string): Bool;
  // Функция для изменения опций в файлах пользователя.
  // Пример: UserOptionSet('\UserToFT\Options.dat', 'Option1', '1');
  // --
  // Прототипы:
  // 1) функции GetFTKey() и UserOptionGet();
  // 2) http://www.delphi.int.ru/articles/126/ (раздел "Хранение записей в файлах").
  // --
  var line:        string; // Строка
    OptionLength: Integer; // Длина имени опции
    FTFolderPath:  string; // FT-папка
    optDatPath1:   string; // Полное имя файла1 (Old)
    optDatPath2:   string; // Полное имя файла2 (New)
    handleOpt1:  TextFile; // Файловая переменная1 = Полное имя файла1
    handleOpt2:  TextFile; // Файловая переменная2 = Полное имя файла2
  begin
  result       :=                        false; // Предварительная установка
  FTFolderPath :=  ExtractFileDir(ParamStr(0)); // FT-папка: 'C:\ForexTester2'
  optDatPath1  :=    FTFolderPath +    OptFile; // Полное имя файла1 (Old)
  optDatPath2  :=    FTFolderPath + 'temp.dat'; // Полное имя файла2 (New)
  OptionLength :=               length(Option); // Длина имени опции
  if FileExists(optDatPath1) then
    begin
      AssignFile(handleOpt1, optDatPath1); // Привязка имени1 файл.переменной1
      AssignFile(handleOpt2, optDatPath2); // Привязка имени2 файл.переменной2
      Reset(     handleOpt1);              // Считывание файла1
      Rewrite(   handleOpt2);              // Перезапись файла2
      while not Eof(handleOpt1) do         // Пока не конец файла1
      begin
        Read(handleOpt1, line);            // Читаем строку без перехода к следующей
        if (Copy(line, 0, OptionLength) = Option) then
        begin
          Writeln(handleOpt2, Option+'='+  // В файл2 пишем новую строку
            Value);                        // с меткой переноса строки
          result := true;                  // Признак успешного изменения опции
        end
        else Write(handleOpt2, line);      // В файл2 пишем старую строку как есть
      end;
      CloseFile(handleOpt1);
      CloseFile(handleOpt2);
      DeleteFile(pchar(optDatPath1));
      RenameFile(optDatPath2, optDatPath1);
    end;
  end;
* * *
Благодарю Александра за помощь.
Исправить ранее возникавшую ошибку помогла функция pchar(), преобразующая 'String' в 'PAnsiChar'.
Последний раз редактировалось Николай Тарасов Ср мар 30, 2011 1:10 pm, всего редактировалось 2 раза.
Я желаю всем счастья.

Аватара пользователя
Николай Тарасов
Сообщения: 144
Зарегистрирован: Чт авг 27, 2009 4:39 pm
Откуда: Екатеринбург
Контактная информация:

#84 Сообщение Николай Тарасов » Ср мар 30, 2011 1:00 pm

3. Функция PlaySound()
Delphi урок - Воспроизводим звук в программе без MediaPlayer
Автор урока: Владимир Любаев
Источник: http://www.delphiexpert.ru/view_lesson.php?id=71
--
Парадокс, но я часто сталкиваюсь с тем, что многие не умеют воспроизводить звук
в программе без использования компонента MediaPlayer. В этом небольшом уроке
я хочу исправить это дело и показать вам, как проиграть у себя в программе
звуковой файл в формате Wav без использования MediaPlayer.

На самом деле делается это очень просто.
Достаточно всего лишь добавить в раздел uses модуль mmsystem

И далее в месте где вам нужно воспроизвести звук использовать функцию PlaySound

function PlaySound(pszSound:PChar; hmod:HINST; fdwSound:Cardinal):boolean;

Как всегда разберем это на конкретном примере.

Первым делом открываем Delphi, создаем новый проект и дописываем в раздел uses
модуль mmsystem.
Далее кидаем на форму кнопку (Button) с закладки Standard и создаем на ней
обработчик событий Onclick.
Между begin end пишем:

PlaySound('D:\1.wav', 0, SND_ASYNC);

Первый параметр в нашей функции это полный путь к звуковому файлу с указанием
его расширения, т.к. у меня файл называется 1.wav и находиться на диске
D:\ я написал тут 'D:\1.wav'.
Второй параметр используется в случае, когда звук берется из ресурса, поскольку
мы этого делать не будем, то можно этот параметр задавать равным 0 или nil.
Последний параметр определяет, как будет воспроизводиться звук
(режим воспроизведения). Существует несколько режимов воспроизведения
которые задаются соответствующими флагами, вот пример некоторых из них:

SND_ASYNC - Звук воспроизводится асинхронно и функция возвращается сразу же
после начала воспроизведения. Чтобы прекратить воспроизведение нужно вызвать
функцию PlaySound с параметром pszSound, равным 0.
SND_LOOP - воспроизведение звука постоянно повторяется, одновременно надо
установить флаг SND_ASYNC.
SND_NOSTOP - Если заданный звук не может быть воспроизведен из-за занятости
ресурсов, то функция немедленно вернет false (и звук не будет воспроизведен).
Если же данный флаг не указан, то функция попытается остановить воспроизведение
другого звука, чтобы освободить ресурсы.
SND_PURGE - Останавливает воспроизведение любых звуков, вызванных в данной задаче.
SND_SYNC - Синхронное воспроизведение звука события. Функция PlaySound
возвращается только после окончания воспроизведения.

т.е. Если мы хотим, чтобы звук воспроизводился асинхронно и постоянно повторялся
в нашей функции нужно использовать флаги SND_ASYNC и SND_LOOP.
Комбинировать флаги можно при помощи операции or.

Пример:

PlaySound('D:\1.wav', 0, SND_ASYNC or SND_LOOP);

Вот в принципе и все что я хотел рассказать вам в этом уроке. До встречи.

Владимир Любаев
--
Источник: http://www.delphiexpert.ru/view_lesson.php?id=71



PS
Вместо явного указания папки с wav-файлом:

Код: Выделить всё

  PlaySound('C:\ForexTester2\UserToFT\UserSounds\UserFile.wav', 0, SND_SYNC);
можно сделать немного иначе:

Код: Выделить всё

  PlaySound(pchar(ExtractFileDir(ParamStr(0))+     // FT-папка: 'C:\ForexTester2'
    '\UserToFT\UserSounds\UserFile.wav'), 0, SND_SYNC);
То есть адрес FT-папки определяется также как в функции GetFTKey - автоматически.
Последний раз редактировалось Николай Тарасов Ср апр 06, 2011 11:21 am, всего редактировалось 3 раза.
Я желаю всем счастья.

FT Support
Сообщения: 329
Зарегистрирован: Сб июл 11, 2009 3:59 pm

#85 Сообщение FT Support » Ср мар 30, 2011 1:17 pm

Здравствуйте, Николай,

Спасибо за то что делитесь информацией!

Извините, не было времени Вам ответить, сейчас занимаемся новым релизом (2.7)

Ответить