我想捕获一个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
)时,它不会。{/ p>
我也查看了WM_QUERYENDSESSION
,但MSDN说“每个应用程序在收到此消息后应立即返回TRUE
或FALSE
,并推迟任何清理操作,直到它收到WM_ENDSESSION
消息。“
答案 0 :(得分:3)
WM_ENDSESSION
处理实际上并没有让您的应用程序有机会退出消息循环。您应该假设系统在发送WM_ENDSESSION
消息后调用TerminateProcess。
因此,应该在从窗口过程返回之前完成应用程序需要执行的任何清理。
答案 1 :(得分:0)
在Windows UI应用程序中,您可以使用:
LRESULT CMainDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
您可以从this msdn link获得更多帮助。
{
if(message == WM_ENDSESSION)
{
if(lParam == ENDSESSION_LOGOFF)
{
/*Handle event*/
}
}
return CDialogEx::WindowProc(message, wParam, lParam);
}