Скачать MetaTrader 5

MetaTrader and ExitProcess

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
. ... Rick D. ... .
1181
. ... Rick D. ... .  
Попытка закрыть терминал программным способом:
#import "kernel32.dll"
  void ExitProcess(int ExitCode);
#import
 
void init()
{
   ExitProcess(0);
}
И разрешается импорт dll в эксперте.

Результат получается такой. У меня закрывается нормально.
У некоторых терминал закрывается, а процесс остается висеть.
У некоторых закрывается с ошибкой.

В MSDN сказано:
Warning Calling ExitProcess in a DLL can lead to unexpected application or system errors. Be sure to call ExitProcess from a DLL only if you know which applications or system components will load the DLL and that it is safe to call ExitProcess in this context.

Может быть причина такого поведения ExitProcess кроется в этом?
Slava
Модератор
6932
Slava  
RickD писал (а):
В MSDN сказано:
Warning Calling ExitProcess in a DLL can lead to unexpected application or system errors. Be sure to call ExitProcess from a DLL only if you know which applications or system components will load the DLL and that it is safe to call ExitProcess in this context.

Может быть причина такого поведения ExitProcess кроется в этом?

Вряд ли.

Вообще, непонятный ворнинг (я его, кстати, не нашёл в своём MSDN). Причём здесь вызов ExitProcess из DLL? Библиотеки по-любому выполняются в адресном пространстве процесса
Юрий Макаров
358
Юрий Макаров  
У меня даже при закрытии терминала руками он часто остается висеть в TaskManager и его приходится убивать там руками.
Вот и сегодня посмотрел, висит терминал которой я закрывал в четверг, три дня комп был включен, но я к нему не подходил.
Alexandre
602
Alexandre  

Дэн Эпплман "Win32 API и Visual Basic", SAMS - Питер, 2002. Теме посвящена глава 14 "Процессы и нити", подраздел "Межпроцессные взаимодействия".

На стр. 848 в описании функции ExitProcess читаем (дословно):

"...
Применять эту функцию для закрытия процессов не рекомендуется. Не используйте ее в приложениях VB. Вместо этого попробуйте отправить сообщение WM_CLOSE главному окну закрываемого приложения. Сообщение WM_CLOSE рассматривается в главе 16.
..."

Глава 16 "Стандартные сообщения Windows", стр. 940:

" Const WM_CLOSE = &H10
...
В следующей строке программы это сообщение используется для закрытия формы:
di& = PostMessage(hWnd, WM_CLOSE, 0&, 0&)"

Функция long PostMessage(..., ..., ..., ...) достаточно простая и хорошо описана в MSDN. Вызывается из библиотеки user32.

Alexandre
602
Alexandre  
Mak писал (а):
У меня даже при закрытии терминала руками он часто остается висеть в TaskManager и его приходится убивать там руками.
Вот и сегодня посмотрел, висит терминал которой я закрывал в четверг, три дня комп был включен, но я к нему не подходил.

Если через меню "Файл" --> "Выход", в принципе могут быть проблемы. Это известный виндовский глюк. Лучше действовать через крестик на форме.
. ... Rick D. ... .
1181
. ... Rick D. ... .  
alexjou писал (а):

В следующей строке программы это сообщение используется для закрытия формы:
PostMessage(hWnd, WM_CLOSE, 0&, 0&)"

Можно также отправить сообщение через PostThreadMessage.
BOOL PostThreadMessage(
  DWORD idThread, // thread identifier
  UINT Msg,       // message
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
);
Но как определить хэндл главного окна либо Id главного потока из EA, вот в чем вопрос.
Alexandre
602
Alexandre  
Это можно сделать оконным субклассингом (для окна) либо повесив хук на запуск МТ (для процессов). Посмотри в MSDN описания функций EnumWindows(), EnumWindowsProc(), EnumChildWindows(), SetWindowsHookEx() и CallWndProc(). Здесь в аттаче примерчик на VB6 c библиотекой и описанием. Правда, сам детально с ним пока что не разбирался. Посмотри, может пригодится.
Файлы:
8024.zip 31 kb
. ... Rick D. ... .
1181
. ... Rick D. ... .  

Хуки сразу в топку. :)
По поводу EnumWindows().
Во первых - придется свою dll писать, это первое неудобство.
Во вторых - как узнать, какое из найденных окон и есть главное?

Slava
Модератор
6932
Slava  
RickD писал (а):

Хуки сразу в топку. :)
По поводу EnumWindows().
Во первых - придется свою dll писать, это первое неудобство.
Во вторых - как узнать, какое из найденных окон и есть главное?


Как вариант - поискать в цикле родительское окно. Хэндл окна графика известен.
//+------------------------------------------------------------------+
//|                                                CloseTerminal.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net"
#property show_inputs
#include <WinUser32.mqh>
 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
   int hwnd=WindowHandle(Symbol(),Period());
   int hwnd_parent=0;
//----
   while(!IsStopped())
     {
      hwnd=GetParent(hwnd);
      if(hwnd==0) break;
      hwnd_parent=hwnd;
     }
   if(hwnd_parent!=0)
      PostMessageA(hwnd_parent,WM_CLOSE,0,0);
//----
   return(0);
  }
//+------------------------------------------------------------------+
wladimir
1160
wladimir  
Подскажите, как этим пользоваться
Например при нажатии клавиши пробел, чтобы закрывался терминал
при компиляции к тому же выскакивает GetParent - функция не объявлена
Евгений
110
Евгений  

Но как определить хэндл главного окна



FindWindow('MetaQuotes::MetaTrader::4.00',nil)
123
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий