Здравствуйте, 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);
Именно так я закрываю окно вспомогательного приложения, когда закрывается основное.
Здравствуйте, kevkev, Вы писали:
K> ExitProcess(0); K>...
K>в результате мессаджбокс показывается, но программа работает дальше в цикле. K>выход не производится.
K>Что я делаю не так?
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.
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.
В гугле какие то мутные куски с энумерацией...
Здравствуйте, kevkev, Вы писали:
K>программа продолжила выполняться.
Вполне вероятно, что работает один (или более) рабочих потоков — Threads. То есть, рабочий поток не завершен, поэтому приложение не выгружается из памяти. То есть, при закрытии приложения необходимо корректно завершить все его потоки.
Факт наличия незакрытых потоков, а также и их идентификаторы можно выяснить, например, при помощи утилиты Process Explorer.
K>>программа продолжила выполняться.
AG>Вполне вероятно, что работает один (или более) рабочих потоков — Threads. То есть, рабочий поток не завершен, поэтому приложение не выгружается из памяти. То есть, при закрытии приложения необходимо корректно завершить все его потоки.
AG>Факт наличия незакрытых потоков, а также и их идентификаторы можно выяснить, например, при помощи утилиты Process Explorer.
Мне просто надо выйти сразу, а посылка сообщения этого не предполагает.
Здравствуйте, kevkev, Вы писали:
K>Нельзя ли просто дать мне кусок кода, я не знаю, как получить хендл для TerminateProcess. K>В гугле какие то мутные куски с энумерацией...
Здравствуйте, kevkev, Вы писали:
K>>>программа продолжила выполняться.
AG>>Вполне вероятно, что работает один (или более) рабочих потоков — Threads. То есть, рабочий поток не завершен, поэтому приложение не выгружается из памяти. То есть, при закрытии приложения необходимо корректно завершить все его потоки.
AG>>Факт наличия незакрытых потоков, а также и их идентификаторы можно выяснить, например, при помощи утилиты Process Explorer.
K>Мне просто надо выйти сразу, а посылка сообщения этого не предполагает.
1) Посылка сообщения закроет головное окно приложения — это примерно то же самое, что пользователь нажал "крестик" в заголовке главного окна.
2) Еще раз напомню — такая ситуация характерна для случая, когда НЕТ ВЫХОДА ИЗ ПОТОКА! Пожалуйста, проверьте — не остается ли ВИСЕТЬ один из потоков. В случае, если все-таки остается, следует сделать его корректное закрытие. Процедура этого закрытия должна запускаться, например, из обработчиков события OnClose (ON_WM_CLOSE) главного окна приложения.
3) Для того, чтобы определиться с идентификатором потока (Thread ID) следует при создании потока, сохранять его идентификатор, вместе с названием потока или его основной процедуры (например в LOG-файле). И далее, вызвав Process Explorer, определить — какой из потоков остается висеть.
Скорее всего причина в том, что бесконечный цикл не дает шанса приложению обработать сообщение. Нужно внутри бесконечного цикла организовать прокачку сообщений (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);
}
}
}