Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: SetConsoleCtrlHandler - отмена нажатия на крестик!  (Прочитано 11659 раз)
0 Пользователей и 1 Гость смотрят эту тему.
titov_alex
Участник

ru
Offline Offline

« : 16-04-2004 07:25 » 

суть проблемы- в программе нужно по выходу обязательно делать деинициализацию (программа сетевая и нужно хотя бы уведомить абонентов, что сеанс окончен), причем деинициализация может быть долгой (секунд 20-30 если без учета тормозов машины).. так вот.
если мы в функции

BOOL WINAPI ConsoleHandler(DWORD CEvent) {
  ...
}

возвращаем TRUE, то завершение программы отменяется.. должно отменяться.. Ctrl+C и Ctrl+Break - отменяются без проблемм..
но вот если нажать на крестик - то тоже отменяется..
а потом выскакивает сообщение что программа зависла и не убить ли ее сейчас? Молчу
кто-нибудь знает, как с этим окошком бороться можно?? :?

спасибо

ПС деинициализацию я делаю не в этой функции, в ней я только отдаю команду к главному потоку программы..
Записан
titov_alex
Участник

ru
Offline Offline

« Ответ #1 : 19-04-2004 04:29 » 

Сам спросил и сам ответил )
SetProcessShutdownParameters(0, SHUTDOWN_NORETRY);
это хоть и не все, но решает. Просто деинициализацию надо завершить до окончания функции обработки сигнала - по выходу из функции программа падает.
Я сделал примерно так:
Код:
HANDLE hStopProgram_Command;

int main(int argc, char* argv[]){
  DWORD dRes;
 
  hStopProgram_Command = CreateEvent(NULL, TRUE, FALSE, NULL);
 
  SetProcessShutdownParameters(0, SHUTDOWN_NORETRY);
 
  if (SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler,TRUE)==FALSE) {
    // unable to install handler.display message to the user
    dRes = GetLastError();
    printf("(MAIN): Unable to install handler! (err = %i)\n", dRes);
    return -1;
  }
 
  while (true) {
    dRes = WaitForSingleObject(hStopProgram_Command, 10000L);
    if (dRes != WAIT_ABANDONED) break;
  }
 
  printf("Stop_program signal handled! Press OK button in msg to terminate program...\n");
  MessageBox(0,"Press OK!!!", "Stopping",0);
 
  return 0;
} /* */

BOOL WINAPI ConsoleHandler(DWORD CEvent) {
  switch(CEvent) {
    case CTRL_CLOSE_EVENT:
      printf("exit\n");
      break;
    // тут обработка остальных сигналов
  }
 
  SetEvent(hStopProgram_Command);
   
  while (true);

   return TRUE;
}

т.е., функция ConsoleHandler только ставит в сигнальное состояние событие hStopProgram_Command и "зависает", а в главном потоке - ждем это событие и завершаем работу программы.
Остается только непонятным первый параметр функции SetProcessShutdownParameters - dwLevel...
MSDN:
Цитата
dwLevel
[in] Shutdown priority for a process relative to other processes in the system. The system shuts down processes from high dwLevel values to low. The highest and lowest shutdown priorities are reserved for system components. This parameter must be in the following range of values. Value Meaning
000–0FF System reserved last shutdown range.
100–1FF Application reserved last shutdown range.
200–2FF Application reserved "in between" shutdown range.
300–3FF Application reserved first shutdown range.
400–4FF System reserved first shutdown range.
All processes start at shutdown level 0x280.
« Последнее редактирование: 25-11-2007 17:14 от Алексей1153++ » Записан
titov_alex
Участник

ru
Offline Offline

« Ответ #2 : 19-04-2004 06:34 » 

хотя нет.. похоже, я поторопился радоваться успеху :oops:

дело в том, что процесс действительно остается жить.. но живет он по таймауту - через определенное время он вылетает безо всякого предупреждения или сообщения (если в программе, код которой приведен выше, не нажимать кнопку ОК, то программа упадет сама) Жаль

Причем, программа живет только 5 секунд, после чего падает, тогда как мне на деиннициализацию может потребоваться время около 30 секунд и более.

так что, вопрос еще открыт..
Записан
Anchorite
Гость
« Ответ #3 : 20-04-2004 18:49 » 

А обязательно делать консольную программу?
Записан
titov_alex
Участник

ru
Offline Offline

« Ответ #4 : 21-04-2004 03:44 » 

Консоль делать в общем-то не обязательно, но желательно. Проблемма решилась следующим образом:

Код:
  HWND ConsoleWnd;
  HMENU hm;
 
  hm = GetSystemMenu( ConsoleWnd, FALSE );
  DeleteMenu(hm, SC_CLOSE , MF_BYCOMMAND);
  DrawMenuBar(ConsoleWnd);

Перед этим, соответственно, нужно просто найти hWnd консоли - путей поиска много, я выбрал поиск по имени окна, сперва сменив его на название программы, чем убил двух зайцев.

Всем спасибо за участие
« Последнее редактирование: 25-11-2007 17:14 от Алексей1153++ » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines