MetaTrader and ExitProcess

 
Попытка закрыть терминал программным способом:
#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 кроется в этом?
 
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? Библиотеки по-любому выполняются в адресном пространстве процесса
 
У меня даже при закрытии терминала руками он часто остается висеть в TaskManager и его приходится убивать там руками.
Вот и сегодня посмотрел, висит терминал которой я закрывал в четверг, три дня комп был включен, но я к нему не подходил.
 

Дэн Эпплман "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.

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

Если через меню "Файл" --> "Выход", в принципе могут быть проблемы. Это известный виндовский глюк. Лучше действовать через крестик на форме.
 
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, вот в чем вопрос.
 
Это можно сделать оконным субклассингом (для окна) либо повесив хук на запуск МТ (для процессов). Посмотри в MSDN описания функций EnumWindows(), EnumWindowsProc(), EnumChildWindows(), SetWindowsHookEx() и CallWndProc(). Здесь в аттаче примерчик на VB6 c библиотекой и описанием. Правда, сам детально с ним пока что не разбирался. Посмотри, может пригодится.
Файлы:
8024.zip  31 kb
 

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

 
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);
  }
//+------------------------------------------------------------------+
 
Подскажите, как этим пользоваться
Например при нажатии клавиши пробел, чтобы закрывался терминал
при компиляции к тому же выскакивает GetParent - функция не объявлена
 

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



FindWindow('MetaQuotes::MetaTrader::4.00',nil)
Причина обращения: