Привет всем!
Почти полдня убил на то, чтобы открыть текстовый файл в блокноте прямо из программы MQL4. Я понимаю, что тема уже избита, но тем не менее мне пришлось попробовать 3 разных способа пока я не нашел верный да и к тому же универсальный.
Не будем затягивать предисловие, сразу к делу.
Задача:
Советник ведет журнал, записывая все в текстовый файл на компьютере "log.txt", нужно чтобы при нажатии на кнопку, данный журнал открывался в стандартном блокноте.
Решение:
#import "shell32.dll"
int ShellExecuteW(int hwnd,string lpOperation,string lpFile,string lpParameters,string lpDirectory,int nShowCmd);
#import
// непосредственное открытие файла
ShellExecuteW(NULL, NULL, "C:\\Users\\User\\AppData\\Roaming\\MetaQuotes\\Terminal\\ID\\MQL4\\Files\\log.txt", NULL, NULL, SW_SHOWNORMAL);
Путь "lpFile" должен быть полным до файла (ярлыка), который нужно открыть/запустить. В строчке "путь" обязательно должен применяться двойной обратный слэш (\\).
Таким способом можно не только открывать текстовые файлы, но и запускать программы, даже по ярлыку из любого места на диске (проверено). А файлы буду открываться в той программе, которая настроена в системе по умолчанию для открытия данного типа файлов. Проще говоря функция "ShellExecuteW" эмитирует двойной клик на файле/ярлыке/программе (стандартный "ShellExecute" у меня не заработал).
Понятно, что приведенный выше код не подходит для универсального использования, поэтому подправим его до нормального вида:
#import "shell32.dll"
int ShellExecuteW(int hwnd,string lpOperation,string lpFile,string lpParameters,string lpDirectory,int nShowCmd);
#import
//------ global parameters
string logPath = TerminalInfoString(TERMINAL_DATA_PATH)+"\\MQL4\\Files\\NameAdvisor_log_"+(string)magicNumber+".txt"; // переменная пути до log-файла
int OnInit()
{
// меняем обратный слэш на двойной "\" ---> "\\"
if(StringReplace(logPath, "\\", "\\\\") == -1)
Alert("ОШИБКА - в формировании пути к файлу журнала!");
}
// непосредственное открытие файла в блокноте и обработка ошибок
int sew = ShellExecuteW(NULL, NULL, logPath, NULL, NULL, SW_SHOWNORMAL);
if(sew <= 32)
switch(sew)
{
case 0: Alert("ОШИБКА - Системе не хватает памяти, выполняемый файл испорчен или произошло ошибочное перераспределение памяти!"); break;
case 2: Alert("ОШИБКА - Файл не найден!"); break;
case 3: Alert("ОШИБКА - Путь не найден!"); break;
case 5: Alert("ОШИБКА - Была попытка динамически связаться с задачей, была ошибка многопроцессорного выполнения или ошибка защиты сети!"); break;
case 6: Alert("ОШИБКА - Библиотека требует отдельных сегментов данных для каждой задачи!"); break;
case 8: Alert("ОШИБКА - Недостаточно памяти для запуска приложения!"); break;
case 10: Alert("ОШИБКА - Ошибочная версия Windows!"); break;
case 11: Alert("ОШИБКА - Ошибочный выполняемый файл. Или это не приложение Windows, или ошибка в .exe файле!"); break;
case 12: Alert("ОШИБКА - Приложение спроектировано для другой операционной системы!"); break;
case 13: Alert("ОШИБКА - Приложение спроектировано для MS-DOS 4.0!"); break;
case 14: Alert("ОШИБКА - Неизвестный тип выполняемого файла!"); break;
case 15: Alert("ОШИБКА - Попытка запустить приложение, работающее только на более ранних версиях Windows!"); break;
case 16: Alert("ОШИБКА - Попытка запустить второй экземпляр приложения, содержащего сегменты данных, не помеченные \"только для чтения\"!"); break;
case 19: Alert("ОШИБКА - Попытка запустить архивированный файл. Файл должен быть разархивирован, прежде чем его можно будет загрузить!"); break;
case 20: Alert("ОШИБКА - Ошибочный файл одной из DLL, требуемой для приложения!"); break;
case 21: Alert("ОШИБКА - Приложение требует 32-битного расширения Windows!"); break;
case 31: Alert("ОШИБКА - Нет приложения, связанного с файлом указанного типа, или нет файла, связанного с указанной операцией!"); break;
default: Alert("ОШИБКА - открытия журнала! № ", sew); break;
}
А с созданием/записью/чтением из файла я думаю вы и без меня разберетесь, используя стандартные функции MQL4.
Удачи!
ОС: Windows 7 64-bit
МТ4: Build 1010