Нужно срочно выйти из приложения
От: kevkev  
Дата: 10.01.14 16:01
Оценка:
Запущен бесконечный цикл, в некоторый момент возникает необходимость
показать мессаджбокс, после того, как юзер в нем ткнет ок закрыть программу.

делаю так:
if (need_to_exit)
{
MessageBox("Нажмите ок для выхода из программы",0,0);
ExitProcess(0);
}

...

в результате мессаджбокс показывается, но программа работает дальше в цикле.
выход не производится.

Что я делаю не так?
Re: Нужно срочно выйти из приложения
От: AlexGin Беларусь  
Дата: 10.01.14 21:00
Оценка:
Здравствуйте, kevkev, Вы писали:

K>Запущен бесконечный цикл, в некоторый момент возникает необходимость

K>показать мессаджбокс, после того, как юзер в нем ткнет ок закрыть программу.

K>делаю так:

K>if (need_to_exit)
K>{
K> MessageBox("Нажмите ок для выхода из программы",0,0);
K> ExitProcess(0);
K>}

K>...


K>в результате мессаджбокс показывается, но программа работает дальше в цикле.

K>выход не производится.

K>Что я делаю не так?


Я бы просто послал главному окну приложения сообщение WM_CLOSE (пример ниже):

::PostMessage(hWndMainFrm, WM_CLOSE, 0L, 0L);

Именно так я закрываю окно вспомогательного приложения, когда закрывается основное.
Re: Нужно срочно выйти из приложения
От: VladFein США  
Дата: 10.01.14 21:11
Оценка:
Здравствуйте, kevkev, Вы писали:

K> ExitProcess(0);

K>...

K>в результате мессаджбокс показывается, но программа работает дальше в цикле.

K>выход не производится.

K>Что я делаю не так?


MSDN

If one of the terminated threads in the process holds a lock and the DLL detach code in one of the loaded DLLs attempts to acquire the same lock, then calling ExitProcess results in a deadlock. In contrast, if a process terminates by calling TerminateProcess, the DLLs that the process is attached to are not notified of the process termination. Therefore, if you do not know the state of all threads in your process, it is better to call TerminateProcess than ExitProcess.

Re[2]: Нужно срочно выйти из приложения
От: kevkev  
Дата: 11.01.14 06:48
Оценка:
AG>Я бы просто послал главному окну приложения сообщение WM_CLOSE (пример ниже):
AG>

AG>::PostMessage(hWndMainFrm, WM_CLOSE, 0L, 0L);

AG>Именно так я закрываю окно вспомогательного приложения, когда закрывается основное.

Это не сработало:

CWnd* pWnd = AfxGetMainWnd();
HWND mainHandle = pWnd->m_hWnd;
::PostMessage(mainHandle, WM_CLOSE, 0L, 0L);

программа продолжила выполняться.
Re[2]: Нужно срочно выйти из приложения
От: kevkev  
Дата: 11.01.14 06:50
Оценка:
VF>MSDN
VF>

If one of the terminated threads in the process holds a lock and the DLL detach code in one of the loaded DLLs attempts to acquire the same lock, then calling ExitProcess results in a deadlock. In contrast, if a process terminates by calling TerminateProcess, the DLLs that the process is attached to are not notified of the process termination. Therefore, if you do not know the state of all threads in your process, it is better to call TerminateProcess than ExitProcess.


Нельзя ли просто дать мне кусок кода, я не знаю, как получить хендл для TerminateProcess.
В гугле какие то мутные куски с энумерацией...
Re[3]: Нужно срочно выйти из приложения
От: AlexGin Беларусь  
Дата: 11.01.14 06:58
Оценка:
Здравствуйте, kevkev, Вы писали:

K>программа продолжила выполняться.


Вполне вероятно, что работает один (или более) рабочих потоков — Threads. То есть, рабочий поток не завершен, поэтому приложение не выгружается из памяти. То есть, при закрытии приложения необходимо корректно завершить все его потоки.

Факт наличия незакрытых потоков, а также и их идентификаторы можно выяснить, например, при помощи утилиты Process Explorer.
Re[4]: Нужно срочно выйти из приложения
От: kevkev  
Дата: 11.01.14 16:46
Оценка:
K>>программа продолжила выполняться.

AG>Вполне вероятно, что работает один (или более) рабочих потоков — Threads. То есть, рабочий поток не завершен, поэтому приложение не выгружается из памяти. То есть, при закрытии приложения необходимо корректно завершить все его потоки.


AG>Факт наличия незакрытых потоков, а также и их идентификаторы можно выяснить, например, при помощи утилиты Process Explorer.


Мне просто надо выйти сразу, а посылка сообщения этого не предполагает.
Re[3]: Нужно срочно выйти из приложения
От: rus blood Россия  
Дата: 11.01.14 19:24
Оценка:
Здравствуйте, kevkev, Вы писали:

K>Нельзя ли просто дать мне кусок кода, я не знаю, как получить хендл для TerminateProcess.

K>В гугле какие то мутные куски с энумерацией...


TerminateProcess(GetCurrentProcess(), 0);
Имею скафандр — готов путешествовать!
Re[5]: Нужно срочно выйти из приложения
От: AlexGin Беларусь  
Дата: 12.01.14 17:42
Оценка: 1 (1)
Здравствуйте, kevkev, Вы писали:

K>>>программа продолжила выполняться.


AG>>Вполне вероятно, что работает один (или более) рабочих потоков — Threads. То есть, рабочий поток не завершен, поэтому приложение не выгружается из памяти. То есть, при закрытии приложения необходимо корректно завершить все его потоки.


AG>>Факт наличия незакрытых потоков, а также и их идентификаторы можно выяснить, например, при помощи утилиты Process Explorer.


K>Мне просто надо выйти сразу, а посылка сообщения этого не предполагает.


1) Посылка сообщения закроет головное окно приложения — это примерно то же самое, что пользователь нажал "крестик" в заголовке главного окна.
2) Еще раз напомню — такая ситуация характерна для случая, когда НЕТ ВЫХОДА ИЗ ПОТОКА! Пожалуйста, проверьте — не остается ли ВИСЕТЬ один из потоков. В случае, если все-таки остается, следует сделать его корректное закрытие. Процедура этого закрытия должна запускаться, например, из обработчиков события OnClose (ON_WM_CLOSE) главного окна приложения.
3) Для того, чтобы определиться с идентификатором потока (Thread ID) следует при создании потока, сохранять его идентификатор, вместе с названием потока или его основной процедуры (например в LOG-файле). И далее, вызвав Process Explorer, определить — какой из потоков остается висеть.

В общем — ищите и обрящите!!!
Успехов!!!
Re[3]: Нужно срочно выйти из приложения
От: Hawk Россия  
Дата: 12.02.14 11:25
Оценка:
Здравствуйте, kevkev, Вы писали:

K>Это не сработало:


K>CWnd* pWnd = AfxGetMainWnd();

K>HWND mainHandle = pWnd->m_hWnd;
K>::PostMessage(mainHandle, WM_CLOSE, 0L, 0L);

K>программа продолжила выполняться.


Скорее всего причина в том, что бесконечный цикл не дает шанса приложению обработать сообщение. Нужно внутри бесконечного цикла организовать прокачку сообщений (message pumping). Примерно так:

while (true)
{
    // Тело цикла.
    ...

    if (...)
    {
        ::AfxMessageBox("Программа сейчас закроется. Выбора нет, жизнь - это боль. :(");
        ::PostMessage(::AfxGetMainWnd()->GetSafeHwnd(), WM_CLOSE, 0L, 0L);
    }

    // "Прокачка" сообщений вручную.
    while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        if (msg.message == WM_QUIT)
        {
           ::PostQuitMessage(0);
           break;
        }

        if (!AfxGetApp()->PreTranslateMessage(&msg))
        {
            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);
        }
    }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.