Я хочу поймать событие выхода из системы Windows, чтобы можно было выполнить некоторую очистку. мой WindowProc
выглядит так:
switch (uMsg){
case WM_ENDSESSION:
case WM_DESTROY:
PostQuitMessage(0);
return 0;
// other messages
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
и цикл сообщений в WinMain
выглядит так:
for(;;){
bool bTerminate = false;
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
if(msg.message == WM_QUIT){
bTerminate = true;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(bTerminate){
break;
}
// do other stuff
Sleep(10);
}
FILE * fout;
fopen_s(&fout, "C:\\success.txt", "w"); // simulating cleanup actions
fclose(fout);
ExitProcess(0);
Предполагаемый механизм заключается в том, что WindowProc
делает PostQuitMessage
в результате чего основной цикл сообщений получает WM_QUIT
, прерывая цикл и отправляя программу на очистку. Когда я выхожу из программы (таким образом, отправка WM_DESTROY
) программа создает success.txt
, но когда программа работает и я выхожу (отправляю WM_ENDSESSION
), Это не.
Я смотрел на WM_QUERYENDSESSION
как хорошо, но MSDN говорит «Каждое приложение должно вернуться TRUE
или же FALSE
сразу же после получения этого сообщения и отложить любые операции очистки, пока не получит WM_ENDSESSION
сообщение.»
WM_ENDSESSION
обработка фактически не дает вашему приложению возможности выйти из цикла сообщений. Вы должны предположить, что системные вызовы TerminateProcess после отправки WM_ENDSESSION
сообщение.
Поэтому любая очистка вашего приложения должна быть выполнена до возвращения из оконной процедуры.
В приложениях с интерфейсом Windows вы можете использовать:
LRESULT CMainDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_ENDSESSION)
{
if(lParam == ENDSESSION_LOGOFF)
{
/*Handle event*/
}
}
return CDialogEx::WindowProc(message, wParam, lParam);
}
Вы можете получить больше помощи от эта ссылка MSDN.